Ray-triangles intersection when ray origin is inside multiple triangles

Hi, I’m trying to launch a ray whose origin is contained inside multiple triangles and get the primitive IDs of all the triangles within which it is contained. My scene only contains triangles. Since the ray origin is inside the triangles, I get tmax= 0 on ray-triangle intersection and I can’t just generate another ray with new origin as the hit point(hit_t = origin + tmax * direction) of the previous intersection as suggested by some other posts on this forum.

This is an example of my scene:
Triangle-1: (-1,2,0) (1,-2,0) (2,0,0)
Triangle-2: (-0.5,2,0) (0.5,-2,0) (2.5,0,0)
Ray Origin: (0,0,0)
Ray Direction: arbitrary

I am new to Optix and from what I’ve read so far, it seems like the any_hit program might be useful for this but result in slowdowns. Is there a way in which I can launch a single ray, with its origin inside multiple triangle primitives and arbitrary direction, and get back the ID of all such triangles? Thanks!

Hi @n16, welcome!

Our warnings against any-hit programs are really only intended to make people aware of the costs of any-hit in cases where any-hit is not actually needed. This is mostly because any-hit programs are turned on by default and you have to opt-out. Sometimes, any-hit programs are needed, and in that case I don’t want people to feel bad about using the feature as it was intended.

There are three ways I can think of to collect multiple hits along a ray: (1) any-hit, (2) use side-effect code in an intersection program, and (3) iteratively query for the closest hit and then re-cast a new ray from the previous hit point.

OptiX currently will not return intersections for hardware triangles at t<=0, and the closest-hit order for co-incident geometry is undefined. This means the iterative closest-hit approach will not work for you because you won’t be able to catch both hits of two or more co-incident triangles. Unfortunately, this also means the any-hit won’t work either when the origin is co-incident with your co-incident triangles. If your triangles aren’t lying in an axial plane like z=0, then you might catch some of the hits sometimes due to floating point rounding discrepancies between the triangle plane and your ray origin, but that’s uncontrollable and I’m sure you don’t want your case to depend on floating point rounding.

So I guess the solution would be to use any-hit or a custom intersection. With any-hit you’d have to move the ray origin off the co-incident plane (perhaps scaled by the triangle’s normal or some other handy direction that doesn’t lie in the triangles’ plane) and then narrow your t-min and t-max values to a reasonable and safe window, and filter out any unwanted hits as part of your any-hit processing. Or, you can write a custom primitive intersection program, and then you will be able to handle t=0 if you want, without having to move the ray origin. Using a custom primitive intersection program will have a slightly higher cost than any-hit, since the intersection itself will be software.

This is an interesting use case, can you elaborate on what you’re doing with multiple intersections at the ray origin? The use case that seems to get questions more often is trying to do the opposite and avoid getting any ray hits at the ray origin. ;) (For example, when casting shadow rays away from a surface, you don’t want the surface to count as a hit, otherwise it will shadow itself.)


Thank you for your detailed response @dhart! I’m trying to use the Optix Wrapper Library(OWL) to solve a non-rendering problem similar to: http://www.sci.utah.edu/~wald/Publications/2020/springs/springs.pdf

I got this to work by using a custom intersection program; however, I’m trying to leverage the speedup from hardware ray-triangle intersection.

With any-hit you’d have to move the ray origin off the co-incident plane (perhaps scaled by the triangle’s normal or some other handy direction that doesn’t lie in the triangles’ plane)

If I’m not wrong, since z=0 for all the triangles, the normals of the triangle would be (0,0,1) when normalized. Would you mind elaborating on how to do the scaling for the ray origin?

If all the triangles are z=0, can you set your ray origin’s z value to -1, and set your ray direction to (0,0,1)? My previous reply was written under the assumption that you didn’t want to move the ray origin because you might hit other unwanted triangles that are not at z=0. But if your triangles are always at z=0, there’s no strong need to limit your t-max, and you can easily move the ray origin out of the z=0 plane, use a ray direction perpendicular to the z-plane, and get the hits you want. In this case, I’d suspect to collect multiple hit points, using an any-hit program and the built-in hardware triangle intersector would probably be the fastest approach.