That should work, but there is a more elegant and robust way if you’re using the OptiX C++ wrappers. You can declare and set variables in one line and don’t need to care about the variable index.
In your case, like this:
GeometryInstance inst = context->createGeometryInstance();
// This can be called with any number of variables already on the object, the index isn't needed.
inst["objectID"]->setInt(myItem->getUniqueID());
The operator on the wrapped objects will try to get the variable by name and if doesn’t exist, create it and the set*() function will set them to the proper type, which must match with the declarations inside the device code or validation will fail.
You can debug through those wrappers and see how the underlying OptiX C-API is used. It’s all in one header.
// Put this into a header! It must be the same everywhere.
struct PerRayData_radiance
{
float3 result;
float importance;
int depth;
int objectID;
int primitiveID;
};
All of the fields in your structure have a 4-byte alignment requirement, so that’s fine and no padding is needed if you do not use that in arrays (e.g. user defined output buffer formats.)
Check Table 3. Alignment Requirements here: http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#vector-types
Something like this would be bad.
struct Foo
{
int i; // 4-byte alignment.
float4 f4; // 16-byte alignment!
}
Inside the closest hit program you would then have the variable declarations at module scope outside the functions.
Put the following into all your closest hit programs which can be active in a scene during picking:
rtDeclareVariable(PerRayData_radiance, thePrd, rtPayload, );
// For the attribute, the user defined attribute semantic (here PRIMITIVE_ID) and variable type (here int)
// must match with the one inside the intersection program.
// The variable name itself doesn't matter for the matching.
rtDeclareVariable(int, primitiveID, attribute PRIMITIVE_ID, );
// This will be filled from the GeometryInstance variable scope.
rtDeclareVariable(int, objectID, , );
// And inside the closest hit program, this is the
RT_PROGRAM void closesthit()
{
thePrd.objectID = objectID;
thePrd.primitiveID = primitiveID;
// If you're running a recursive algorithm you would need make sure to return after the primary hit.
// Or you would need to put this at the very end so that the first ray wins.
}
If you have made sure the PerRayData is the same everywhere and all(!) GeometryInstances have that objectID variable declared and initialized, that misaligned address could have other reasons.
What is your system setup?
OS version and bitness, installed GPU(s), NVIDA display driver version, OptiX version (major. minor.micro), CUDA toolkit version used to compile the PTX code.