2
\$\begingroup\$

Say we do this:

glm::mat4 View = glm::lookAt(glm::vec3(4,3,-3), glm::vec3(0,0,0),glm::vec3(0,1,0)); 

And after printing to the console with glm tostring (column major order):

View = -0.600000 -0.411597 0.685994 0.000000 0.000000 0.857493 0.514496 0.000000 -0.800000 0.308697 -0.514496 0.000000 -0.000000 -0.000000 -5.830953 1.000000 

This matrix works as intended. I multiplied it by a perspective projection matrix and passed the resulting matrix in to my vertex shader to be multiplied by the vertices of a cube with side length = 1. So the full expression for each projected vertex is:

VERTEX VIEW PERSPECTIVE PROJECTION p.x -0.600000 -0.411597 0.685994 0.000000 0.629325 0.000000 0.000000 0.000000 p.y * 0.000000 0.857493 0.514496 0.000000 * 0.000000 0.839100 0.000000 0.000000 p.z -0.800000 0.308697 -0.514496 0.000000 0.000000 0.000000 -1.002002 -1.000000 1.0 -0.000000 -0.000000 -5.830953 1.000000 0.000000 0.000000 -0.200200 0.000000 

Which produces this:

enter bruhaehfd

However, I was under the impression that to account for the translation of the camera, the camera's coordinates should be inverted and placed in the fourth column of the View Matrix. So I tried this:

 VERTEX VIEW PERSPECTIVE PROJECTION p.x -0.600000 -0.411597 0.685994 -4.000000 0.629325 0.000000 0.000000 0.000000 p.y * 0.000000 0.857493 0.514496 -3.000000 * 0.000000 0.839100 0.000000 0.000000 p.z -0.800000 0.308697 -0.514496 3.000000 0.000000 0.000000 -1.002002 -1.000000 1.0 -0.000000 -0.000000 -0.000000 1.000000 0.000000 0.000000 -0.200200 0.000000 

Which produces this:

enter image description here

Why does the first View Matrix work but not the second one?

\$\endgroup\$
0

1 Answer 1

5
\$\begingroup\$

Alright so upon looking into it further, here's how glm::lookAt produces a View Matrix:

  1. Make a row-major ordered 4x4 Translation Matrix by negating the camera position, c:
 1 0 0 0 0 1 0 0 0 0 1 0 -c.x -c.y -c.z 1 
  1. Multiply it by a column-major ordered 4x4 Rotation Matrix that you make using the formula here: https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml
 TRANSLATION ROTATION 1 0 0 0 x.x y.x z.x 0 VIEW = 0 1 0 0 • x.y y.y z.y 0 0 0 1 0 x.z y.z z.z 0 -c.x -c.y -c.z 1 0.0 0.0 0.0 1 

So what I think is going on is you're effectively inverting the camera-to-world matrix to get the world-to-camera matrix. The above equation produces a column-major ordered View Matrix.

And for people like me who like row-major ordered matrices (contiguous memory gang), you can do this with a row-major ordered rotation matrix to produce a row-major ordered View Matrix. Notice the multiplication order must be swapped:

 ROTATION TRANSLATION x.x x.y x.z 0 1 0 0 -c.x VIEW = y.x y.y y.z 0 • 0 1 0 -c.y z.x z.y z.z 0 0 0 1 -c.z 0.0 0.0 0.0 1 0 0 0 1 
\$\endgroup\$
2
  • 2
    \$\begingroup\$ "So what I think is going on is you're effectively inverting the camera-to-world matrix to get the world-to-camera matrix." Bingo. \$\endgroup\$ Commented Feb 9, 2021 at 18:43
  • 1
    \$\begingroup\$ On step 2. you should add that after the TRANSLATION * ROTATION multiplication the final matrix is transposed in order to get the world-to-camera result \$\endgroup\$ Commented Jan 10, 2022 at 11:06

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.