Game Development Reference
int isLeaf = 0;
// If the index corresponds to the lastLevel-1, it is leaf.
if ( index >= ( 1 << (g_Depth-1)) )
// Set flag for leaf as true.
isLeaf = 4;
// Check if the node should be leaf.
int primCount = (g_uNodes[parent].iPrimCount >> 3) - 1;
int a = g_uNodes[parent].iPrimPos;
int b = g_uNodes[parent].iPrimPos + primCount;
int mask = g_uMortonCode[a].iCode ˆ g_uMortonCode[b].iCode;
// It is leaf.
if ( mask == 0 )
// Make both children invalid.
// left child
g_uNodes[index].iPrimPos = -MAX_INT;
g_uNodes[index].iPrimCount = -MAX_INT;
// right child
g_uNodes[index+1].iPrimPos = -MAX_INT;
g_uNodes[index+1].iPrimCount = -MAX_INT;
// Set the node as leaf.
g_uNodes[parent].iPrimCount |= 4;
Listing 1.3. Check for if a node is a leaf node.
of the tree is increased. However, the depth is constrained by GPU memory.
Most practical implementations will store more data besides the structure (like
the model itself and the textures), which limits the size of the SLBVH built
on the GPU. Although increasing the depth of the tree improves the traversal
performance, it increases construction time as well. On dynamic scenes, a tradeoff
between construction and traversal times is needed. After a certain depth, the
traversal performance barely increases.
The cut is done on the longest axis, which improves traversal performance
on heterogeneous models such as the Sponza model. On models with uniform
primitive size, the gain is minimal. A round-robin approach is also an option,
and it works almost as fast as using the longest axis. The axis is stored in the
two least-significant bits of PrimCount where x = 00, y = 01, and z =10inbinary
notation. If nodes are neither invalid nor leaf, then both nodes are considered
internal. The boxes will be computed on the next step of construction. Therefore,
this step must store the primitives' offset PrimPos and the number of primitives