How is RTCRay::id set and what values to expect?

How is RTCRay::id set and what values to expect?

I am trying to use RTCIntersectContext::RTCFilterFunctionN with rtcIntersect1M with per-ray data. I see this in the docs:

callback functions may be invoked with an arbitrary packet size (of size 1, 4, 8, or 16) and different ordering as specified initially. For this reason, one may have to use the rayID component of the ray to identify the original ray, e.g. to access a per-ray payload.

But it isn't clear to me how RTCRay::id is supposed to be set. I tried initializing the ray stream with consecutive ids (0 to stream size) but the ids returned by RTCRayN_id contain many zeros, large out of range values. I'm probably missing something in the docs or tutorials but I can't figure out how it should work.

Let me know if you want to see any code.

5 posts / 0 new

Best Reply

Just checked and we did not test that feature. We have the intersection_filter tutorial which used the ray.mask to pass an id. However, I just changed that tutorial to use the to pass the id, which works fine. Could you please try again. Also are the other ray components correct? Please note that inside the filter function you may get presented with ray packets, thus N may not be 1.

I was processing the packet but I wasn't checking the valid flag per ray, the large ids were coming from invalid rays in the packets.

Now the ids look a bit better now but still strange, some are valid but many are 0. I'll keep looking at it today and see if I can understand better what's going on.

Using RTCRay::id in RTCIntersectContext::RTCFilterFunctionN seems to work fine with rtcIntersect1 but not with rtcIntersect1M in my code.

Here is how I'm setting up the ray stream and filter:

    RTCIntersectContext context;
    rtcInitIntersectContext (&context);
    context.filter = rayFilter;

    std::vector < RTCRayHit > rays (streamSize);

    for (uint i = 0; i < streamSize; ++i) {
        RTCRay& ray = rays[i].ray;
        ray.org_x = cameraPoint.x;
        ray.org_y = cameraPoint.y;
        ray.org_z = cameraPoint.z;
        ray.tnear = 0.f;
        ray.dir_x = rayDirs[i].x;
        ray.dir_y = rayDirs[i].y;
        ray.dir_z = rayDirs[i].z;
        ray.time = 0.f;
        ray.tfar = std::numeric_limits<float>::infinity ();
        ray.mask = 0; = i;
        ray.flags = 0;

This is my simplified context filter function:

void rayFilter (const RTCFilterFunctionNArguments* args)
    // get context data:
    const IntersectContext* context =
            static_cast<const IntersectContext*> (args->context);

    // iterate over packet:
    for (uint i = 0; i < args->N; ++i) {
        if (args->valid[i] == 0) {

        // this works in rtcIntersect1 but skips some ids
        //   and returns many zeros inside of rtcIntersect1M:
        const uint id = RTCRayN_id (args->ray, args->N, i);

Using rtcIntersect1 works fine, the ids work as expected in the filter function:

    for (uint i = 0; i < streamSize; ++i) {
        rtcIntersect1 (scene_, &context, &rays[i]);

But without changing any other code, the filter seems to get bad ids when I use rtcIntersect1M instead:

    rtcIntersect1M (scene_, &context,, streamSize, sizeof(RTCRay));

Thanks again for all your help! This is not a showstopper problem for me, I can use rtcIntersect1 for now, it is fast enough. I was just curious to try ray streaming.

Oh I see my bug now, sizeof(RTCRay) should be sizeof(RTCRayHit)! Sorry for wasting your time, it is working now!

Leave a Comment

Please sign in to add a comment. Not a member? Join today