Some confusion on AnyHit shader in OptiX

Hello, currently I’m learning OptiX. I’m using OptiX 7.5. Now I’m trying to setup a very simple scene with ray origin locating at (0, 0, -1), N spheres locating at (0, 0, 1), (0, 0, 2), …, (0, 0, N), and I’m shooting ray from the origin to (0, 0, 1) direction with tmax=1e16, as following figure:

I expect the anyhit shader to report 2*N hit record (1 for front and 1 for back), while it only report 1 hit record (the front surface of the first sphere). Following is my raygen shader:

extern "C" __global__ void __raygen__rg() {
    const uint3 idx = optixGetLaunchIndex();
    const uint3 dim = optixGetLaunchDimensions();
    const float3 origin = make_float3(0.0f, 0.0f, 0.0f);
    const float3 direction = make_float3(0.0f, 0.0f, 1.0f);
    // printf("Ray:%d Generated, Origin:(%f,%f,%f)\n", idx.x, origin.x, origin.y, origin.z);

I also tried to recursively invoke optixTrace in closest_hit shader, while the parameter max_traverse_depth limit the max hit record I can generate. Moreover, according to my understand, the ray tracing will find all primitives that intersect with a ray in a single ray casting, am I right?

The problem is: How can I generate all expected hit record in this pipeline?

Without providing the code of your anyhit program, I would guess that you didn’t call optixIgnoreIntersection() inside it to let the BVH traversal continue.

Note that the anyhit program is not called in ray direction order but in BVH traversal order.

When using closest hit programs to gather all hits along a ray in ray direction order, there is no need to implement that recursively. That can be done easily with an iterative path tracer following the ray direction with different ray origin or t_min values until there is no hit anymore.

Please read these two posts and follow all links in there for more information:

Thanks, I actually did not call optixIgnoreIntersection() in AH shader, and I will try, thanks!

Please note that even with a call to optixIgnoreIntersection(), your any-hit shader will be invoked N times for N spheres along a ray. For each invocation, you can query your entry (or “front-face”) hit via optixGetRayTmax(), and you can query the exit (or “back-face”) hit via optixGetAttribute_0() (making sure that the attribute is > 0). If your rays might originate inside of a sphere, then you can end up with a single exit (“back-face”) hit and you could use optixIsBackFaceHit() to check which kind of hit this is. In the case of a single back-face hit, you’ll query the t value using optixGetRayTmax() rather than the attribute.


Thanks, this helps me alot.