1
votes

Could you explain to me what is the purpose of -1 in the last row of the gl_projection matrix? And how it affects the perspective division step ?

enter image description here

2

2 Answers

3
votes

The essential property of a perspective projection is that you divide the x/y coordinates by the depth (distance from viewer). This makes objects closer to the viewer (which have smaller depth values) larger, and objects farther from the viewer (which have larger depth values) smaller.

The next piece of the puzzle is how homogenous coordinates work. The (x, y, z, w) coordinates in homogenous space produced by the vertex shader are converted to regular 3D coordinates by dividing them by w:

(x, y, z, w) --> (x/w, y/w, z/w, 1)

So we want a division by the depth to achieve a perspective, and we know that the coordinates produced by the vertex shader will be divided by w. To get the desired result, we can simply put the depth value in eye coordinate space into the w coordinate.

This is exactly what the last row of the projection matrix does. The dot product of the last row with the input vector (which are the eye space coordinates of the vertex) produces the w value of the output:

(0 0 -1 0) * (x y z 1) = -z

You might have expected the value of the matrix element to be 1, to simply copy the z value in eye space to the w value of the vertex shader output. The reason we use -1 to invert the sign is based on the common arrangement of eye space coordinates in OpenGL.

Eye coordinates in OpenGL typically have the "camera" at the origin, looking down the negative z-axis. So the visible range of z-coordinates has negative values. Since we want the distance from the viewer in the resulting w-coordinate, we flip the sign of the eye space z-coordinate, which turns the negative z-values into positive distance values from the origin.

Note that much of this is just common policy, partly rooted in the legacy fixed function pipeline. With the programmable pipeline used in current OpenGL versions, you have complete freedom in how you organize your coordinate spaces and transformations. For example, you could easily use an eye space coordinate system where the camera points in the positive z-direction, and then have a 1 in the last row of the projection matrix instead of a -1.

0
votes

As stated here: http://www.songho.ca/opengl/gl_projectionmatrix.html

"Therefore, we can set the w-component of the clip coordinates as -ze. And, the 4th of GL_PROJECTION matrix becomes (0, 0, -1, 0)."