Attributes referenced in hit program but not produced in attribute program

Hi, I’m getting an error I can’t understand trying to use a particular attribute program. The error in question is:

rtGeometryInstanceValidate: Invalid context (Details: Function "RTresult _rtGeometryInstanceValidate(RTgeometryinstance)" caught exception: Validation error: The following attributes are referenced in a hit program but are not produced in the attached attribute program: "_attribute_geometric_normal", "_attribute_shading_normal")

and the attribute program:

#include <optix.h>
#include <optixu/optixu_math_namespace.h>

using namespace optix;

rtDeclareVariable(float3, geometric_normal, attribute geometric_normal, );
rtDeclareVariable(float3, shading_normal, attribute shading_normal, );

rtBuffer<rtBufferId<float3>,1 > vertex_buffers;
rtBuffer<rtBufferId<float3>,1 > normal_buffers;
rtBuffer<int3>   index_buffer;

rtDeclareVariable(float,      cur_time, rtCurrentTime, );
rtDeclareVariable(float2, motion_range, , ) = { 0.0f, 1.0f };
rtDeclareVariable( float2, uv, attribute rtTriangleBarycentrics, );

RT_PROGRAM void attrib() {
    const unsigned int prim_idx = rtGetPrimitiveIndex();
    uv = rtGetTriangleBarycentrics();
    const uint3 vidx = index_buffer[prim_idx];

    const float t0 = motion_range.x;
    const float t1 = motion_range.y;
    const float clamped_time = optix::clamp( cur_time, t0, t1 );
    const int   num_keys = vertex_buffers.size();
    const float step_size = num_keys == 1 ? 1.0f : (t1-t0)/(num_keys-1);

    const int   t0_idx = min( num_keys-1, static_cast<int>( (clamped_time-t0) / step_size ) );
    const int   t1_idx = min( num_keys-1, t0_idx+1 ); 
    const float pt = (clamped_time-t0)/step_size - t0_idx;

    const float3 p0_t0 = vertex_buffers[t0_idx][ vidx.x ];
    const float3 p1_t0 = vertex_buffers[t0_idx][ vidx.y ];
    const float3 p2_t0 = vertex_buffers[t0_idx][ vidx.z ];

    const float3 p0_t1 = vertex_buffers[t1_idx][ vidx.x ];
    const float3 p1_t1 = vertex_buffers[t1_idx][ vidx.y ];
    const float3 p2_t1 = vertex_buffers[t1_idx][ vidx.z ];

    const float3 p0 = optix::lerp( p0_t0, p0_t1, pt );
    const float3 p1 = optix::lerp( p1_t0, p1_t1, pt );
    const float3 p2 = optix::lerp( p2_t0, p2_t1, pt );

    const float3 Ng    = optix::cross( p1 - p0, p2 - p0 );
    geometric_normal = optix::normalize( Ng );
    shading_normal = geometric_normal;
}

What’s odd is that the same closest hit program, when used with the following attribute program works fine, which as far as the way the normal attributes are declared and set is pretty similar:

#include <optix.h>
#include <optixu/optixu_math_namespace.h>

using namespace optix;

rtBuffer<float3> vertex_buffer;
rtBuffer<float3> normal_buffer;
rtBuffer<float2> texcoord_buffer;
rtBuffer<uint3>   index_buffer;

rtDeclareVariable(float3, geometric_normal, attribute geometric_normal, );
rtDeclareVariable(float3, shading_normal, attribute shading_normal, );
rtDeclareVariable(float2, uv, attribute rtTriangleBarycentrics, );

RT_PROGRAM void attrib()
{
    const unsigned int prim_idx = rtGetPrimitiveIndex();
    const uint3 vidx = index_buffer[prim_idx];
    uv = rtGetTriangleBarycentrics();

    const float3 v0    = vertex_buffer[vidx.x];
    const float3 v1    = vertex_buffer[vidx.y];
    const float3 v2    = vertex_buffer[vidx.z];
    const float3 Ng    = optix::cross(v1 - v0, v2 - v0);
    geometric_normal = optix::normalize(Ng);

    if (normal_buffer.size() == 0) {
        shading_normal = geometric_normal;
    } else {
        const float3 n0 = normal_buffer[vidx.x];
        const float3 n1 = normal_buffer[vidx.y];
        const float3 n2 = normal_buffer[vidx.z];
        shading_normal = normalize(n1 * uv.x + n2 * uv.y + n0 * (1.0f - uv.x - uv.y));
    }
}

As far as I can tell I"m setting everything correctly. I can’t find any references to _attribute_geometric_normal in any of my material program ptx, so I assume that it’s a machine-generated name?

I’m on optix 6.0, cuda 10.1, drivers 418.56, ubuntu 18.04, 2070 max-q.

The first attribute program looks reasonable to me, so you may want to capture an OAC trace and send it to optix-help, referencing this post.

Another thing to check: make sure that the attribute program is attached to all the geometry that could possibly trigger the closest-hit function. I have seen similar errors when mixing triangles and non-triangles for example, if you forget to also produce an attribute from the non-triangle code path to match the one from the triangle code path.

Thanks! Yeah there’s only one object in the scene and I just double-checked the trace to make sure a bug in my code wasn’t somehow creating more.

I’ve mailed the oac to optix-help

This was solved with Dylan’s help looking at the trace. Turns out due to a copy/paste error on my side I wasn’t actually setting the attribute program on the geometry. Once that was fixed everything works as expected.