Inverse Transform without matrices?

David Gavilan
Real Time Rendering
3 min readMar 4, 2020

Affine transforms

In 3D graphics, it’s common to express an affine transform as a translation or position, a scale, and a rotation. The translation and scale are stored as 3D vectors, and the rotation can be stored with just 4 values by using a quaternion, or an angle-axis representation.

That representation can be converted into a 4×4 matrix, but we can also operate directly with vectors and quaternions.

The question is, can we compute the inverse of a transform without using matrices?

Inverse of transform matrices

To answer our question, let us write first the transform as a matrix,

M = T × R × S

*(using column vectors, so the first operation is at the right hand side).

The inverse of M is,

M’ = (T × R × S)’ = S’ × R’ × T’

*(I’m using a single quote instead of -1 to write the inverse).

Can we write that as another affine transform? That is,

M’ = S’ × R’ × T’ = T_ × R_ × S_

Well, a person from the future wrote in math.stackexchange how to extract the translation, the scale, and the rotation of a given affine transform.

So far, so good. But if you look at the comments, someone else also points out that the extracted rotation matrix might be a combination of shear and rotation! 🙄

This might be a trivial problem for many, but I never encountered it before. The issue is that, if the scaling is anisotropic, then there’s certainly shearing going on in the inverse. That is, you can extract T, R, and S from M using what’s described in math.stackexchange, but you can’t extract T_, R_, and S_ 😥.

Partial solution

What can we do to find the inverse, then? Is there an inverse that can be represented as an affine transform or not?

Well, the translation can still be computed the same. If t is the position in the original transform, then the new position is,

t_ = S’ × R’ × (-t)

and we don’t have to use the matrix forms for this. If your rotation is a quaternion, simply invert the quaternion and rotate t with it. Then, divide each component by the scale.

But can we convert (S’ × R’) into (R_ × S_)? Well, we can use the Singular Value Decomposition to see how that would look like,

S’ × R’ = U × Σ × V’

Σ is a diagonal matrix, that is, a scaling matrix. But unless V is the identity, you can see this isn’t looking like (R_ × S_) in the general case 😢.

Conclusion

In the end I bit the bullet and I decided to use matrices when I need the inverse of a transform and I know the scaling may not be isotropic.

For context, I was computing ray-to-object intersections in an AR sample app. These are computed in the CPU, and it would be costly to transform all the triangles of the object to test the intersection, so I’m converting the ray to model space instead. That’s why I needed the inverse of the world transform of the object.

For a reference implementation in Swift, check this commit: Fix transform.inverse (VidEngine). You can see how I implemented the inverse of a Transform for isotropic scalings, the SVD, and the matrix operations, along with several unit tests that exercise the different conversions.

Originally published at http://endavid.com.

--

--

David Gavilan
Real Time Rendering

Ph.D. Graphics Engineer at Metail. Worked on several graphics engines in the past (Fox Engine, Disney Infinity, mobile VR, server-side rendering).