Hi, I’m trying to trace the ray against ellipsoids, but having some issue with the normal of ellipsoids.
I set up my scene in this way:
- Set local aabb for sphere, using its center and radius.
- Build acceleration structure for one sphere.
- Build instance acceleration structure for 4 spheres, with transform [1.5, 0, 0, Tx, 0, 1, 0, Ty, 0, 0, 1, Tz]. This spread 4 instance around the box, and scale them by 1.5 along the x axis. The code looks like this :
float instanceZero[12] = { 1.5, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 3.5 };
memcpy(optixInstances[0].transform, &instanceZero[0], sizeof(float) * 12);
Then in my __intersection__sphere function, I do sphere-ray intersection using object space ray (optixGetObjectRayOrigin and optixGetObjectRayDirection). Then I get my object space normal float3(p0, p1, p2). I know I need to multiply the inverse transpose of object to world matrix to the object space normal in order to get the actual world space normal for shading. I noticed that OptiX has a function called optixTransformNormalFromObjectToWorldSpace to do that. I tried this:
float3 transformedNormal = optixTransformNormalFromObjectToWorldSpace(normal);
unsigned int p0, p1, p2, p3;
p0 = float_as_int(transformedNormal.x);
p1 = float_as_int(transformedNormal.y);
p2 = float_as_int(transformedNormal.z);
But It seemed that this function just multiply an identity matrix to my normal (here is the image, the sharp edge on the ellipsoids comes from shadow, and the blurred edge comes from dot(normal, lightDirection)).
I also tried the optixGetObjectToWorldTransformMatrix function.
float transform[12];
optixGetWorldToObjectTransformMatrix(transform);
//More precisely, I should get the transpose matrix of it.
unsigned int p0, p1, p2, p3;
p0 = float_as_int(normal.x * transform[0]);
//I only scale in x axis and have no rotation,
//so it is okay to just multiply the first element in transform matrix
//if transform[0] equals 0.667, I will get correct result.
p1 = float_as_int(normal.y);
p2 = float_as_int(normal.z);
But it did not work either.
Here is the image with correct normal.
.And finally comes my question, is there a way to get my normal correct? I’m wondering if the object to world matrix is not the transform matrix of that instance?
Some other words:
There is one thing that I have noticed: the transform matrix used in optixGetObjectRayOrigin and optixGetObjectRayDirection is exactly what I want. I looked up the documentation and found that:
optixGetObjectRayDirection()
Returns the current object space ray direction based on the current transform stack.optixGetObjectToWorldTransformMatrix(float m[12])
Returns the object-to-world transformation matrix resulting from the current active transformation list.
I’m wondering if the transform stack and the transformation list are two different things.