6

I stumbled on this question because I had the same problem with my camera, and changing the multiplication order worked.

I ran into a similar problem when scaling a model. This code produced the wrong result:

// world is an existing Matrix
var scale = world * Matrix.CreateScale(3.2f);

whereas this worked perfectly (scaled a model to 3.2x it's size):

var scale = Matrix.CreateScale(3.2f) * world;

I don't understand why the order matters though - in "normal" math (that is, 5*3 vs 3*5), swapping the factors yields the same result. I understand differences if there are more than 2 factors (like in this question), but I don't see the issue here?

I don't know much about how Matrices really work and so I don't know if that's an XNA quirk or if it would happen in OpenGL as well?

Michael Stum
  • 2,543
  • 5
  • 30
  • 41
  • 14
    This isn't a game dev question, it's a math question. Go teach yourself how to manually multiply matrices, you'll quickly learn why the order matters. – House Sep 11 '13 at 05:50
  • 3
    Matrix multiplication is not commutative, unlike "normal" multiplication. In this sense it's more like "normal" division - would you expect 5 / 3 to be the same as 3 / 5? – congusbongus Sep 11 '13 at 07:03
  • Just by definition – acrilige Sep 11 '13 at 09:09
  • 21
    Walk five steps then rotate 90 degrees. Now, rotate 90 degrees then walk five steps. Are you in the same place? Please, Don't do this test near a cliff. – Zhen Sep 11 '13 at 10:53
  • @Zhen The weird thing (to me) is that I'm not doing a rotation and a translation. I'm only doing scaling - existing world * scale or scale * existing world seem completely equivalent. It's the Row vs Column stuff that is the case here, I wasn't aware that matrix multiplication in general math isn't commutative. – Michael Stum Sep 11 '13 at 16:28
  • @MichaelStum Scaling and translation don't commute for the same reason that rotation and translation don't: both scaling and rotation are done relative to the origin, and translation moves the origin. – Nathan Reed Sep 11 '13 at 18:11
  • @MichaelStum, you think there are different things because visually you get different output. But in the computer, all of them [scale, rotation, translation] are only matrixes and matrix multiplication mean apply them in order. – Zhen Sep 12 '13 at 07:17
  • 1
    @MichaelStum, another way to think about it. You mean scale matrix but in reality [in a more accurate way] this matrix should be called scale using (0,0,0) as center. So if world move the mesh from the (0,0,0), the scale result will be different. – Zhen Sep 12 '13 at 07:25
  • @Byte56 Arguably, shader programming, physics algorithms, logic/rendering culling, and deterministic update systems also aren't game dev-specific.  But all these things are heavily used in game dev, and considered core competencies for game development (even if they all are also used occasionally elsewhere, e.g. the internal implementations of iOS's 2D Cocoa MVC/layout/rendering systems in the form of CoreImage, UIKit Dynamics, UITableView dequeueReusableCell, & Auto Layout respectively). – Slipp D. Thompson May 26 '17 at 05:18
  • @MichaelStum Walk five steps then put on large 36"-long clown shoes.  Now, put on large 36"-long clown shoes then walk five steps.  Are you in the same place? – Slipp D. Thompson May 26 '17 at 05:25

2 Answers2

26

The fact that matrix multiplication isn't (usually) commutative is a mathematical fact, and doesn't have anything to do with which API or library (XNA, OpenGL, etc.) you're using.

At the level of arithmetic, the order matters because matrix multiplication involves combining the rows of the first matrix with the columns of the second. If you swap the two matrices, you're swapping which one contributes rows and which one contributes columns to the result.

The deeper reason that order matters is that matrices represent geometric transformations, and the order of transformations matters. For example, since simple scaling is always relative to the origin of coordinates, doing a scale after a translate is different from a translate after a scale, since the translate moves the origin. Similarly, rotations don't commute with translation, and rotations around one axis don't commute with those around another axis.

Nathan Reed
  • 33,657
  • 3
  • 90
  • 114
-2

Man is this kind of hard to figure out a good explanation of why.

Basically the matrices all transform the geometric values. If you shift the object any, you aren't just performing on a mathematical operation on the original object, but you are performing the operation after any other adjustments you have already done.

You can almost think of the object after any matrix operation as a completely new object, because that's what it is in RAM, for the most part. So, if you move the object 4 steps to the left, you end up with (Object on top of an "invisible board" 4 steps to the left). If you rotate the resultant object, you aren't rotating the original object anymore, but the object based on the object that is attached to that "invisible board" 4 steps to the left.

Joe Plante
  • 117
  • 2