Hi,
In OptiX 7.7, how do you calculate normals along the OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BEZIER
?
(curve.h
in SDK seems not to support this)
Thanks!
Hi,
In OptiX 7.7, how do you calculate normals along the OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BEZIER
?
(curve.h
in SDK seems not to support this)
Thanks!
Now I’ve got:
const uint32_t primitiveIndex = optixGetPrimitiveIndex();
const OptixTraversableHandle gas = optixGetGASTraversableHandle();
const unsigned int gasSbtIndex = optixGetSbtGASIndex();
float4 controlPoints[4];
optixGetCubicBezierVertexData(gas, primitiveIndex, gasSbtIndex, 0.0f, controlPoints);
const float t = optixGetCurveParameter();
const float4 p10 = lerp(v0, v1, t);
const float4 p11 = lerp(v1, v2, t);
const float4 p12 = lerp(v2, v3, t);
const float4 p20 = lerp(p10, p11, t);
const float4 p21 = lerp(p11, p12, t);
const float3 bo = make_float3(lerp(p20, p21, t));
const float3 bw = optixTransformPointFromObjectToWorldSpace(bo);
const float3 normal = normalize(worldHitPoint - bw);
It seems to work correctly. Though if there is any better way to get the normal, I’d be happy to adopt it.
I’ve asked internally and it’s hopefully making it into curve.h inside the upcoming OptiX SDK release.
It shouldn’t take too long. The R535 drivers for it are already out.
Otherwise we can post the code before that, once it’s in.
Great! Thanks for checking. Waiting for the next SDK :)
Until then, if you add these two functions to the struct CubicInterpolator
, that will enable using the surfaceNormal()
function the same way as with cubic B-splines.
An example showing that for cubic B-splines is optixHair
inside the optixHair.cu
normalCubic()
function. Just replace initializeFromBSpline()
with the new initializeFromBezier()
function when using Bezier control points.
__device__ __forceinline__ void initializeFromBezier(const float4* q)
{
// Bezier-to-Poly = Matrix([[-1, 3, -3, 1],
// [ 3, -6, 3, 0],
// [-3, 3, 0, 0],
// [ 1, 0, 0, 0]])
p[0] = q[0] * ( -1.0f ) + q[1] * ( 3.0f ) + q[2] * ( -3.0f ) + q[3];
p[1] = q[0] * ( 3.0f ) + q[1] * ( -6.0f ) + q[2] * ( 3.0f );
p[2] = q[0] * ( -3.0f ) + q[1] * ( 3.0f );
p[3] = q[0];
}
__device__ __forceinline__ void export2Bezier(float4 bz[4]) const
{
// inverse of initializeFromBezier
// Bezier-to-Poly = Matrix([[-1, 3, -3, 1],
// [ 3, -6, 3, 0],
// [-3, 3, 0, 0],
// [ 1, 0, 0, 0]])
// invert to get:
// Poly-to-Bezier = Matrix([[0, 0, 0, 1],
// [0, 0, 1/3, 1],
// [0, 1/3, 2/3, 1],
// [1, 1, 1, 1]])
bz[0] = p[3];
bz[1] = p[2] * (1.f/3.f) + p[3];
bz[2] = p[1] * (1.f/3.f) + p[2] * (2.f/3.f) + p[3];
bz[3] = p[0] + p[1] + p[2] + p[3];
}
Thank you! Sounds clear. I’ll put it in the code and let you know how it works.
OK, checked, code works fine. Performance is exactly the same as with my code, so I’ll stay with your solution since it is going to appear in SDK. :)
Thanks again!
Thanks for checking.
Depending on how your curves are specified exactly, there are different options for the surfaceNormal() function template which allow taking quicker code paths if possible.