1

I have been trying to understand how the view matrix is constructed given the position of the camera, the point to look at and the up vector.

I found two tutorials, here and here, that explain this. However, they differ in the way the view matrix is built. In former they create a translation and a rotation then multiply them to get the view-matrix. In the latter, though, they just put the translation in the last row (column, depending on the convention row/col-major).

So my question is, why are these two ways? Isn't the lookAt matrix be unique? To my understanding and after reading and thinking a lot, it seems to me that the first blog has the correct way. Am I missing something?

BRabbit27
  • 6,333
  • 17
  • 90
  • 161

1 Answers1

1

(assuming row-major order, because that's what I usually use)

Think about it this way: at first, you have the untransformed world, with a camera at some position with some rotation. You know that, in order to get from that world to the transformed world where the camera is at the origin and pointing toward +z or -z or what-have-you, you need to do some sort of translation (because the camera isn't at the center) and some sort of rotation (because the camera could be pointing in any direction).

Since it's easiest to perform a rotation when the point you're rotating around (the camera) is at the origin, you first want to translate the camera so that it's located at the origin. Here's what the matrix would look like:

1 0 0 -camera_x
0 1 0 -camera_y
0 0 1 -camera_z
0 0 0     1

After you perform this rotation, the camera is at the center. Now you can rotate it so it's pointing the way you want. Rotations can be accomplished in many ways, so instead writing an actual matrix, I'll just give a placeholder:

a b c 0
d e f 0
g h i 0
0 0 0 1

Now, how can we combine these matrices to get our view matrix? The rule is that you multiply the matrices all together, in right-to-left order. So the calculation looks like this:

view = rotation * translation

because you're translating first, then rotating second.

To answer your question: if you were rotating first, and translating second, like this:

view = translation * rotation

then view would be equal to this:

a b c -camera_x
d e f -camera_y
g h i -camera_z
0 0 0     1

That's because, when you transform a matrix using a pure translation matrix, you get your original matrix with the xyz offsets added to the top three values in the last column. That might be what that second tutorial was trying to do.

However, matrix multiplication is not commutative. When assembling your view matrix the easier way (translate first, rotate second), you can't just subtract the camera position from the rotation matrix, because you're rotating a translation instead of translating a rotation, which is just a more complicated thing to do by hand. In this case, you need to multiply the two matrices together.

Sam Estep
  • 12,974
  • 2
  • 37
  • 75
  • Ok. I get you point although I got some observations. Isn't row-major order suppossed to have the translation in the last row? I also read [in here](http://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/row-major-vs-column-major-vector) that in row-major the multiplication is done left-to-right. – BRabbit27 Jun 25 '15 at 03:35
  • Finally, I understand the difference between both results, i.e. `view = translation * rotation` and `view=rotation*translation`. However, which method would give me the representation as in real-life, to my understanding, first translate then rotate would give the result as one can see it in reality. Am I misunderstanding something? – BRabbit27 Jun 25 '15 at 03:38
  • About the multiplication order: while matrix multiplication isn't commutative (you can't switch around the order of your matrices), it *is* associative (if you have matrices A, B, and C, `A * B * C` = `(A * B) * C` = `A * (B * C)`). As for your other question: the goal of a view matrix is that, when you use it to transform the world, the result will *always* have the camera at the same point (the origin) with the same orientation. Any matrix that achieves that effect will work, but as I said, the easiest way to do it in this case is to translate first, then rotate. – Sam Estep Jun 25 '15 at 12:24
  • I agree with @BRabbit27. Assuming row major order the translation matrix is wrong as well as the multiplication order of the view matrix. See also this: [link](https://stackoverflow.com/questions/349050/calculating-a-lookat-matrix?rq=1) – asdf Dec 19 '21 at 18:20