Why are inverse transformations applied to rays rather than forward transformations to objects?

When computing ray-object intersections against a transformed object, most raytracers apply the inverse transform to each ray and compute the intersection against a non-transformed object. Wouldn't applying the forward transform, putting the object into a flat world-space, be faster and more efficient, because you only need to compute the transform once?

• What do you mean by "only compute the transform once"? Meaning you don't have to compute the inverse transform, or you only ever need to transform an object once? Computing the inverse transform is cheap compared to a geometry intersection, and you definitely would need to transform an object multiple times (into the space of each different ray). Aug 12 '15 at 3:35
• I think the assumption is that all primitives would be transformed to a flat world-space position during scene preparation. (Which does dramatically increase memory usage.) Then rays would be directly intersected against the primitives without a preceding transformation between spaces, since they're now both in world-space. Aug 12 '15 at 4:19

Most raytracers do both!

Have you ever seen a ray-triangle intersection test where the triangle is transformed so that one vertex is at the origin and the triangle is flat along one of the axes? That would simplify the test, but storing the inverse transformation to apply it to the ray takes more space than the triangle itself. So you could say that almost all ray-triangle tests do apply the forward transformation to the object.

And yet most of the time you are rendering a mesh of many triangles, and "most raytracers" don't transform every vertex in the mesh by the object's transform matrix, they inverse transform the ray into object space. There isn't necessarily a good reason for this—it can definitely be more performant in some cases to preprocess the mesh and put every vertex in world space.

But then say you're doing animation studio-scale path tracing. Now your scene geometry might not all fit in RAM at once. It's no longer a performance win to pre-transform all your vertices/control points, because (a) you need one copy of the object per instance, and (b) you need to transform it each time you read it into RAM. When data bound, the cost of two matrix multiplies per ray is insignificant anyway.

Floating point precision is a potential reason as well: when you have an object a long way from the origin, you get more error from floating point positions, and if you pre-transform the object you apply that error in different directions to each vertex, whereas if you inverse transform the ray you have one fixed error amount from the imprecise position of the ray, but your vertices have less error relative to each other.

Although I suspect the real answer to "why do most raytracers inverse transform the ray" is that most raytracers with public source code implement a wide range of geometric primitives, either for educational purposes or as a proof-of-concept, and it's easier to implement one cheap ray inverse transform than N shape forward transforms. (Plus, as has been mentioned, some intersection algorithms are much simpler if the object is in its canonical space.)

Most ray intersection algorithms can be greatly simplified if you can assume the shape you're intersecting is at the origin, unrotated and with unit size. There are a few exceptions (Like spheres, which have rotational symmetry.) but the more general versions of the algorithms mathematically usually end up basically translating both the shape and ray to the origin before calculating the intersection. With that in mind it's simpler and more consistent to simply transform rays so that the intersection always happens in object-space.

• It can be more accurate too. The farther you get away from zero, the less resolution there is between integers, when using floating point numbers. Aug 12 '15 at 1:39
• @AlanWolfe, wouldn't the same resolution issues show up when computing the inverse transformation and applying it to the ray, though?
– Mark
Aug 12 '15 at 4:27