I am currently working on getting models to work efficiently in a ray tracer implemented as an OpenGL compute shader. I already figured out how to construct the BVH and have implemented this on the CPU side. The problem I now have is that I can't figure out how to handle the tree traversal on the GPU side.
This is a snippet of something I came up with:
struct BVHNode {
vec3 AABBMin;
vec3 AABBMax;
BVHNode Children[2];
int NumTriangles;
Triangle Triangles[MAX_TRIANGLES]; // Waste of memory, non leaf nodes dont have any triangles but still have a fully allocated array
};
struct Mesh {
BVHNode BVH;
Material Material;
};
layout(std140, binding=2) buffer MeshSSBO {
Mesh Meshes[];
} meshSSBO;
This was in my opinion the most straightforward way of doing it, just a normal tree that can be traversed easily with recursion or a stack. Sadly, GLSL supports neither of these so I am not sure how to traverse this tree.
So I have a couple questions:
- How to traverse a full binary tree of unknown depth in GLSL?
The algorithm I need is very easily implemented with a stack or recursion, but I don't know how to do it without those. This is a snippet of C# that shows what I want to do.
Stack<BVHNode> stack = new Stack<BVHNode>();
stack.Push(root);
while(stack.Count > 0) {
var currentNode = stack.Pop();
if(rayIntersects(ray, currentNode)) {
// Check triangles if leaf
if (node.NumTriangles > 0) {
for (int i = 0; i < node.NumTriangles; i++) {
if (rayIntersects(ray, currentNode.Triangles[i])) {
// handle intersection
}
}
}
// Otherwise continue traversal
else {
stack.Push(currentNode.Children[0]);
stack.Push(currentNode.Children[1]);
}
}
}
- Is loading the meshes and BVHs through an SSBO an efficient way to get this data to the shader?
The vertices are loaded through a separate SSBO, the Triangle struct only contains indices to this vertex array.