Friday, August 14, 2009

Order of Matrix Multiplication for 3D Transformations – Two Interpretations

In 3D graphics applications such as video games, a 4x4 matrix of real numbers is used to perform transformations on objects. A transformation can be any or all of: a scale operation (re-size), a rotation, or a translation (change of position). Any of these transformations can occur along any or all axis and can all be represented amazingly, in a single 4x4 matrix. When applying these transformations, multiple matrices can combine their transformations into one matrix using matrix multiplication. The order of matrix multiplication is important and when visualizing the results, there are two distinct ways to interpret this.

In Microsoft’s XNA Framework which supports the creation of games for Windows and the XBOX 360, the 4x4 matrix is used for 3D transformations. Before we can intelligently use the matrix, we need to know how the 3D directions are aligned to each other. 3D space in XNA is right handed which means if the fingers of your open right hand are pointing in the +X direction and if your palm faces the +Y direction then by definition your thumb points in the +Z direction. The convention used in the game industry is: +Y is up; and in engineering: +Z is up. For now, let’s use the more familiar terms Right, Forward, and Up which also form a right handed system.

What does it mean to rotate around an axis? When rotating an object around say Up, if you point your right thumb Up, then the object will rotate the way your four fingers curl as you make a fist. The Earth rotates around the north pole this same way.

Suppose we create one matrix to rotate 90 degrees around Up, called M1, and a second matrix to rotate 90 degrees around Right called M2. If we want to apply both of these rotations to our 3D model we might multiply M1 * M2, or we could multiply M2 * M1 which would not produce the same result. To visualize the results of M1 * M2, we can say M1 is applied first, then M2, and M2 operates within our original axes alignment. This is left to right associativity. Or, we could say M2 is applied first, then M1 but we have to reconfigure our axes such that after M2 is applied, they appear unchanged from the model’s perspective. Then M1 operates within this re-aligned coordinate system that resulted from M2 . This is right to left associativity. Either way we get the same final result, and this is true regardless of whether M1 and M2 are rotations, scale, or translations, or any combination thereof.

Lets look at an example using only rotation around two axes and illustrating left to right matrix associativity. Figure 1 shows on the left our 3D space with axes located at the origin: green is Up, black is Right, and white is Forward.
Figure 1: 3D axes and 3D model
Figure 1 shows on the right our lovely 3D model consisting of a cube, sphere, and cone all attached together and centered at the origin.

Figure 2 shows on the left the results of applying just M1 – rotate 90 degrees around Up, and on the right shows M1 * M2 – rotate around Up then Forward. The cone is down and the ball is to the right.

Figure 2: Rotation around Up then Forward

Figure 3 illustrates the order of matrix multiplication is important: On the left is just M2 -rotation around Forward, and on the right shows M2 * M1 which is rotate Forward then Up,

Figure 3: Rotation around Forward then Up
- obviously not the same result as in Figure 2 (Up then Forward). The Right, Forward and Up axes did not rotate in any of these first three Figures because we are using left to right matrix associativity.

Now lets look at M1 * M2 using right to left matrix associativity. Here we describe M1 * M2 as M1 “after” M2 and now we must apply each matrix to the axes as well as the model.

Figure 4: Rotate Up After Forward

Figure 4 shows on the left just M2 applied this way. Notice the axes have been rotated so that from the perspective of the model they are unchanged. Figure 4 on the right shows M1 * M2 “M1 after M2” where M1 is rotated around Up, but Up is the transformed green axes. You can see it is the same result for the model as Figure 2 M1 * M2: The cone is down and the ball is to the right.

Let’s now consider instead of rotations, the other two transformations: scale and translation. Suppose we create a matrix M3 that translates forward, and another M4 that scales by half. Figure 5 shows on the left the result of M3: a translation forward and on the right is shown M3 * M4: translation then scale by half.

Figure 5: Translate Then Scale

When performing a scale operation, the distance from the origin to the model is scaled, so the model ends up closer to the origin by half. The axes were unchanged because we are using left to right matrix associativity. Using right to left matrix associativity we would call M3 * M4 “M3 after M4” and apply all transformations to the axes. Figure 6 shows on the left the scale by half which is M4, then on the right the translation forward is applied but since the axes have also shrunk, the model is moved forward only by half.

Figure 6: Translate After Scale

The end results for either associativity are the same although the intermediate steps are indeed different. The model never really experiences the intermediate step though, so the path it actually takes assumes a mystique somewhat reminiscent of certain quantum mechanics principles like perhaps wave particle duality.

When visualizing 3D transformations, I prefer to use left to right associativity for two reasons. First it seems more natural to me to apply the matrix operations left to right since that is the direction we read text, and second, I don’t need to keep a separate set of axes in my head. Either one works if applied correctly.

-----------------------------------------------

1: XNA 2.0 Game Programming Receipes by Riemer Grootjans

No comments:

Post a Comment