Im writting a raytracer, for which I want to be able to test intersections with implicit surfaces (in my case spheres). Without applying any transformation it works great, but I would like to upgrade it to test intersections against non-uniform scaled spheres. For such purpose, I have computed the object's local to world matrix, as well as the world to local matrix.
During the intersection test, I first transform the ray origin and direction to the object local space:
Vector o = ray.getOrigin(); Vector l = ray.getDirection(); #ifdef _RT_TRANSFORM_RAY_TO_LOCAL_SPACE o = worldToLocalMatrix * o; l = worldToLocalMatrix * Vector(l.x, l.y, l.z, 0.0f); l = l.Normalize(); #endif
I perform the test, compute the intersection point in object's local space and then transform it back to world space:
Vector hitPoint(o + (l * distance)); Vector hitNormal((hitPoint - center) / radius); hitNormal = hitNormal.Normalize(); #ifdef _RT_TRANSFORM_RAY_TO_LOCAL_SPACE hitPoint = localToWorldMatrix * hitPoint; hitNormal = localToWorldMatrix * Vector(hitNormal.x, hitNormal.y, hitNormal.z, 0.0f); #endif hitNormal = hitNormal.Normalize();
If I run the raytracer, it works great:
However, from some points of view (not all), I obtain wrong renders from the dielectric sphere (center in the above image) and the perfect specular (right in the above image), as well as one of the cubes:
If I just apply the affine transformations to the object's vertices and normals during start up(in the case of the sphere, I only apply translation since its an implicit surface), the render works flawlessly, so my guess its that the problem comes from the transformations applied to the ray.
To compute the local to world matrix:
Model = rotation * translation * scale
To compute the world to local matrix:
InvModel = inverse(scale) * inverse(translation) * inverse(rotation)
I would like to know if I'm applying the transformation to the ray as well as to the output hit properly