1
\$\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
\$\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\$
1
  • 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 at 18:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.