Best way to count closest hit rays?


I am tracing different types of reflected rays that hit a specific object. I am tracing a lot of rays and different numbers of reflected rays hit the object. I would like to have variables to get a final count of the different numbers of rays that hit the object at the end of the ray trace. I have different ray types and for the ones that only have a few I’m printing them with rtPrintf from the closest hit program and I can see exactly which and how many rays hit the object. I know that I can use a variable in the rtPayload and change this variable in the closest hit program. Then I could just check for the rays that have the changed value in the payload, but I’m tracing a lot of rays and different types as well so I would like to just get the final count for each ray type.

I created an input/output buffer, initialize it to zero and then increment it’s value in the closest_hit program. I think this might not be the right way to do it due to the parallelism in which the ray trace is performed. What would be the best way to do this?

This is what’s happening with what I’m doing. For one ray type, I’m getting 3 rays that hit the object, but the value in the buffer it’s not incremented correctly. It’s incremented only 2 times instead of 3.

This is what I have to initialize the buffer and setting it to zero:

optix::uint no_rays = 0;
optix::Variable num_refl_rays_output = mpContext["num_refl_rays_buffer"];
optix::Buffer num_refl_rays_buffer = mpContext->createBuffer( RT_BUFFER_INPUT_OUTPUT, RT_FORMAT_UNSIGNED_INT, 1);
memcpy(num_refl_rays_buffer->map(), &no_rays, sizeof(no_rays));

I have the following code in the closest hit Program:

rtPrintf("Received reflected ray(%d,%d)\n", launch_index.x, launch_index.y);
rtPrintf("Num of rec. rays so far = %d\n",num_refl_rays_buffer[0]);

I’m getting 3 different rays with different launch indices and “Num of rec rays so far =” is printed three times as well but “Num … = 2” is printed twice. At the end, 2 is the final value stored in the buffer.

I’d use atomics: Programming Guide :: CUDA Toolkit Documentation


Great suggestion, it worked.


P.S. Be careful with atomics. They do not work (by default) in multi-GPU environments.