Catmull rom normals?

in the optixHair sample (OptiX 7.4) there is no normal calculaton shown for catmull rom,
so instead of “optixGetCubicBSplineVertexData” I found “optixGetCatmullRomVertexData”, but
how to define CatmullRomSegment interpolator( controlPoints ) ?

thank you.

Analogously to the Cubic normal computation (`normalCubic()` in `optixHair.cu`), you’d initialize the `CubicInterpolator` using a linear transformation to convert the Catrom control points into those for Cubic interpolation. Add the following to the `struct CubicInterpolator` in `curve.h`:

``````    __device__ __forceinline__ void initializeFromCatrom(const float4* q)
{
// Catrom-to-Poly = Matrix([[-1/2, 3/2, -3/2,  1/2],
//                          [1,   -5/2,    2, -1/2],
//                          [-1/2,   0,  1/2,    0],
//                          [0,      1,    0,    0]])
p[0] = ( -1.0f * q[0] + (  3.0f ) * q[1] + ( -3.0f ) * q[2] + (  1.0f ) * q[3] ) / 2.0f;
p[1] = (  2.0f * q[0] + ( -5.0f ) * q[1] + (  4.0f ) * q[2] + ( -1.0f ) * q[3] ) / 2.0f;
p[2] = ( -1.0f * q[0]                    + (  1.0f ) * q[2]                    ) / 2.0f;
p[3] = (                (  2.0f ) * q[1]                                       ) / 2.0f;
}
``````

And for the actual normal computation add

``````// Compute surface normal of Catmull-Rom pimitive in world space.
static __forceinline__ __device__ float3 normalCatrom( const int primitiveIndex )
{
const OptixTraversableHandle gas         = optixGetGASTraversableHandle();
const unsigned int           gasSbtIndex = optixGetSbtGASIndex();
float4                       controlPoints[4];

optixGetCatmullRomVertexData( gas, primitiveIndex, gasSbtIndex, 0.0f, controlPoints );

CubicInterpolator interpolator;
interpolator.initializeFromCatrom(controlPoints);

float3              hitPoint = getHitPoint();
// interpolators work in object space
hitPoint            = optixTransformPointFromWorldToObjectSpace( hitPoint );
const float3 normal = surfaceNormal( interpolator, optixGetCurveParameter(), hitPoint );
return optixTransformNormalFromObjectToWorldSpace( normal );
}
``````

in `optixHair.cu`.

In other words, you’re reusing the existing cubic interpolator and transform the Catmul-Rom control points into the form the interpolator needs using a matrix multiplication the same way it’s done for the cubic b-spline control points.

1 Like

I tested the other matrix shown in this post:

That one works better for me.

Ah, right. Good you found David’s post. Those are the right weights for the current SDK. The code I showed is from the upcoming release in which we’re also changing the `CubicInterpolator` to use plain polynomial evaluation. Sorry for the confusion.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.