I am currently implementing a renderer for a mesh of a binary voxel grid (occupied/not occupied). I use it for something similar as this project: GitHub - owl-project/owlDVR_SpaceSkip.
I turned the voxel grid into a mesh and implemented a raytracer against this mesh. That works fine so far. I am also almost 100% sure that my mesh is correct and have conducted many experiments and debugged a ton.
But I get very weird inconsistencies from the RTX cores on my 4090 (and also before on an 3080Ti), where the ray penetrates this waterproof mesh without hitting the surfaces. This only happens in very rare cases (~1 per 100k rays). I think it is because of cases like the one in the image below:
Another inconsistency is that during my segment search, the ray sometimes finds the backface, but not the frontface. I think this happens at voxel corners (see image below):
I was just wondering if this is a known problem that happens because of precision issues in the RT cores. It is quite annoying in my case, because my result is either wrong or it requires additional sanity checks that can be time consuming.
I’m not aware of any cases where precision can cause either ray leaks or incorrect back/front detection. We have gone to great lengths to make sure meshes are watertight when traced.
Are you using an index buffer for your mesh, or is it watertight by virtue of vertex duplication?
Do you have a way to isolate an example ray & local geometry in these situations?
One way that’s handy that I’ve used in the past: instrument the code to output printf calls only for a single ray corresponding to the clicked pixel - can be done easily using optix launch params. If you want to elide this debug code whenever you’re not debugging, you can use optix bound values to specialize the debug prints. Print the geometry (ray, triangles, etc) in OBJ format from your raygen, closest-hit, and any-hit shaders. I usually use an atomic to count the faces. You can add comments as well if you want to see the direct bit values, check indices, etc. Make sure clicking a pixel will produce a ray that is an exact bitwise match for the previous ray that rendered the pixel. Then reproduce the issue, click one of the bad pixels, and save the OBJ to a file. There are many ways to examine the output, I’ve found using Blender to be pretty convenient.
If you can find an exact ray and small submesh that reproduces this, and share it, we will certainly investigate and verify whether it’s a hardware issue.
I happen to have a framework I use for precision testing, and I’m unable to reproduce either of these issues synthetically. But I’m just guessing about the scene scale and ray, so maybe they matter, getting a reproducer will help. Attached is the mesh I tried. I am trying to repro your first example by exhaustively exploring the space of all rays near origin:(0, 0.5, -2) direction:(0, 0, 1) - For me this exact ray hits the front face. I’ve tried billions of ray with small offsets (everything from ~1e-2 down to ~1e-13) to both the origin and the direction and haven’t seen a single ray leak yet. One fun & easy way to check lots and lots of rays quickly is to set the background (miss) color to NaN in all 3 channels. If you do progressive rendering or use lots of samples per pixel, any NaN value result will poison the pixel and immediately indicate whether any rays leaked.
Thank you for the extensive response. To answer your question, yes I am using an index buffer for my vertices
Your answers lead me to question my whole process and I think I might have found the reasons for my problems.
My first problem (completely penetrating waterproof mesh) seemed to come from an “incorrect” mesh (see Image below). I did not connect edges with every index along the path of the vertex, which leads to rays slipping through this non-connected edge (red crosses). This problem does not seem to occur for axis aligned voxel grid meshes, where I did the same thing. Thinking about it now, it makes total sense that this can happen for such non-axis aligned meshes, since the edges and normals are not EXACTLY the same.
The second problem (hitting backface but not frontface) was probably related to me using slightly different parameters for front-ray and back-ray (e.g. advancing the ray along the ray-direction) which leads to precision problems on my part. If I use the exact same ray and just use CULL_FRONT_FACES and CULL_BACK_FACES, it works.
I thank you again for taking the time and looking at my issue. Even though it was due to “errors” on my part in the end, I hope this thread is at least helpful if somebody else encounters similar issues.
Hey excellent, I’m glad you’re unblocked! Yes thank you for sharing the outcome, it’s extremely helpful to see how things get resolved, even if it was due to a bug or something unexpected.