先放下代码,未完待续。
TraversalStack.Push(hierarchy.Root);
while ( not TraversalStack.Empty() or not QueryQueue.Empty() ) {
//--PART 1: process finished occlusion queries
while (not QueryQueue.Empty() and [ResultAvailable(QueryQueue.Front()) or TraversalStack.Empty()] ) {
node = QueryQueue.Dequeue();
// wait if result not available
visiblePixels = GetOcclusionQueryResult(node);
if (visiblePixels > VisibilityThreshold) {
PullUpVisibility(node);
TraverseNode(node);
}
}
//--PART 2: hierarchical traversal
if ( not TraversalStack.Empty() ) {
node = TraversalStack.Pop();
if ( InsideViewFrustum(node) ) {
// identify previously visible nodes
wasVisible = node.visible and (node.lastVisited == frameID - 1);
// identify nodes that we cannot skip queries for
leafOrWasInvisible = not wasVisible or IsLeaf(node);
// reset node's visibility classification
node.visible = false;
// update node's visited flag
node.lastVisited = frameID;
// skip testing previously visible interior nodes
if ( leafOrWasInvisible ) {
IssueOcclusionQuery(node);
QueryQueue.Enqueue(node);
}
// always traverse a node if it was visible
if ( wasVisible ) TraverseNode(node);
}
}
}
TraverseNode(node) {
if ( IsLeaf(node) ) Render(node);
else TraversalStack.PushChildren(node);
}
PullUpVisibility(node) {
while (not node.visible) {
node.visible = true;
node = node.parent;
}
}