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

4
\$\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
  • 1
    \$\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\$
    – DMGregory
    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\$
    – PentaKon
    Jan 10, 2022 at 11:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .