Hi, I’m using optixTraverse to get some hit info. In some (rare) cases I need the barycentrics of a triangle hit. I’m doing something like:
uint hitKind = optixHitObjectGetHitKind ( );
if ( optixGetPrimitiveType ( hitKind ) == OPTIX_PRIMITIVE_TYPE_TRIANGLE )
{
const float2 barycentrics = optixHitObjectGetTriangleBarycentrics ( );
…
}
but the barycentrics are 0,0 always. Does it work ? or is something else needed before ?
thanks!
dhart
October 28, 2025, 3:20pm
2
Hi @m.breitzke ,
I just tried your snippet inside the optixTriangle SDK sample and it worked as-is. I don’t think you will need any other shader code, but maybe check your BVH & pipeline flags. Are you using
pipeline_compile_options.usesPrimitiveTypeFlags = OPTIX_PRIMITIVE_TYPE_FLAGS_TRIANGLE?
–
David.
yes sure…. if I use optixGetTriangleBarycentrics () in the closest hit shader (using it with optixInvoke) it works fine.
but using optixHitObjectGetTriangleBarycentrics () right after optixTraverse does not. of course just usin it if optixHitObjectIsHit ( ) returns true
dhart
October 28, 2025, 3:34pm
4
Can you try it in the optixTriangle SDK sample and see if it works for you?
Here’s exactly what I tried, in optixTriangle.cu:
extern "C" __global__ void __raygen__rg()
{
// Lookup our location within the launch grid
const uint3 idx = optixGetLaunchIndex();
const uint3 dim = optixGetLaunchDimensions();
// Map our launch idx to a screen location and create a ray from the camera
// location through the screen
float3 ray_origin, ray_direction;
computeRay( idx, dim, ray_origin, ray_direction );
// Trace the ray against our scene hierarchy
unsigned int p0, p1, p2;
#if 0
optixTrace(
params.handle,
ray_origin,
ray_direction,
0.0f, // Min intersection distance
1e16f, // Max intersection distance
0.0f, // rayTime -- used for motion blur
OptixVisibilityMask( 255 ), // Specify always visible
OPTIX_RAY_FLAG_NONE,
0, // SBT offset -- See SBT discussion
RAY_TYPE_COUNT, // SBT stride -- See SBT discussion
0, // missSBTIndex -- See SBT discussion
p0, p1, p2 );
float3 result;
result.x = __uint_as_float( p0 );
result.y = __uint_as_float( p1 );
result.z = __uint_as_float( p2 );
#else
optixTraverse(
params.handle,
ray_origin,
ray_direction,
0.0f, // Min intersection distance
1e16f, // Max intersection distance
0.0f, // rayTime -- used for motion blur
OptixVisibilityMask( 255 ), // Specify always visible
OPTIX_RAY_FLAG_NONE,
0, // SBT offset -- See SBT discussion
RAY_TYPE_COUNT, // SBT stride -- See SBT discussion
0, // missSBTIndex -- See SBT discussion
p0, p1, p2 );
float3 result {};
unsigned int hitKind = optixHitObjectGetHitKind ( );
float2 barycentrics;
if ( optixGetPrimitiveType ( hitKind ) == OPTIX_PRIMITIVE_TYPE_TRIANGLE )
{
barycentrics = optixHitObjectGetTriangleBarycentrics ( );
result.x = barycentrics.x;
result.y = barycentrics.y;
result.z = 1.0f - barycentrics.x - barycentrics.y;
}
#endif
// Record results in our output raster
params.image[idx.y * params.image_width + idx.x] = sutil::make_color( result );
}
thanks for the code! I tried it and it’s working fine, interesting …
let me debug to find the difference
Were you ever able to figure out what the problem was? I also had the same issue of only the barycentrics being zeroed.