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.