Game Development Reference

In-Depth Information

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;

return
;

}

[...]

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

PrimCount
.

Search Nedrilad ::

Custom Search