2

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:

  1. 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]);
        }
    }
}
  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.
bortgerres
  • 185
  • 1
  • 2
  • 10
  • @httpdigest, I also tried laying it out as a flat array in a separate SSBO, with the children being defined as integer indices to that same array. That way it isn't infinite size. However, I still have the problem of question 1 where I need a stack to traverse through the thing. – bortgerres May 10 '22 at 14:30
  • Wow thanks that seems like exactly the solution I need. I just have one more question; GLSL does not support pointers as you said earlier, this parent pointer from the paper can just be implemented as an index to the array right? – bortgerres May 10 '22 at 15:12
  • Alright thanks! I again have just one more question; I store a static array of triangles of length MAX_TRIANGLES for every node, even if the node is not a leaf and does not contain any triangles. Is it possible to make the length of this array dynamic? That would be a huge improvement of memory consumption. I don't have a lot of experience with GLSL so excuse me if this is a dumb question. – bortgerres May 10 '22 at 15:53
  • see [Reflection and refraction impossible without recursive ray tracing?](https://stackoverflow.com/a/45140313/2521214) You can convert any conventional recursion into iteration ... I use normal shaders and pasing the geometry as texture ... you can do similar stuff and have 2 structures one is your BVH tree and the other starting index of each BVH node that will allow variable length of your tree nodes ... – Spektre May 11 '22 at 06:55
  • Thank you for your answer, someone else commented the same thing yesterday but they apparently removed all of their comments. I'm currently working on implementing it. – bortgerres May 11 '22 at 15:17

0 Answers0