Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I divide Z by W in a perspective projection in OpenGL?

I guess this is more a math question than it is an OpenGL one, but I digress. Anyways, if the whole purpose of the perspective divide is to get usable x and y coordinates, why bother dividing z by w? Also how do I get w in the first place?

like image 421
Nooble Avatar asked Aug 30 '14 16:08

Nooble


People also ask

What is perspective division in OpenGL?

Once all the vertices are transformed to clip space a final operation called perspective division is performed where we divide the x , y and z components of the position vectors by the vector's homogeneous w component; perspective division is what transforms the 4D clip space coordinates to 3D normalized device ...

What is W in 3D graphics?

Summary. Homogeneous coordinates have an extra dimension called W, which scales the X, Y, and Z dimensions. Matrices for translation and perspective projection transformations can only be applied to homogeneous coordinates, which is why they are so common in 3D computer graphics.

What are the two main projection methods used in OpenGL?

OpenGL consists of two general classes of projection transformations: orthographic (parallel) and perspective.

What is perspective divide in computer graphics?

The perspective divideThe projection matrix sets things up so that after multiplying with the projection matrix, each coordinate's W will increase the further away the object is. OpenGL will then divide by w: X, Y, Z will be divided by W.


1 Answers

Actually, the explanation has much more to do with the limitations of the depth buffer than it does math.

At its simplest, "the depth buffer is a texture in which each on-screen pixel is assigned a grayscale value depending on its distance from the camera. This allows visual effects to easily alter with distance." Source

More accurately, a depth buffer is a texture containing the value of z/w for each fragment, where:

  • Z is the distance from the near clipping plane to the fragment.
  • W is the distance from the camera to the fragment.

In the following diagram illustrating the relationship between z, w, and z/w, n is equal to the zNear parameter passed to gluPerspective, or an equivalent function, and f is equal to the zFar parameter passed to the same function.

Diagram illustrating the relationship between *z*, *w*, and *z*/*w*

At a glance, this system look unintuitive. But as a result, z/w is always a floating-point value between 0 and 1 (0/n and f/f), and can therefore be represented as a single channel of a texture.

A second important note: the depth buffer is nonlinear, meaning an object exactly in between the near and far clipping planes is nowhere near a value of 0.5 in the depth buffer. As shown above, it would correlate to a value of 0.999 in the depth buffer. Depending on your view, this could be good or bad; you may want the depth buffer to be more detailed close-up (which it is), or offer even detail throughout (which it doesn't).

TL;DR:

  • You divide z by w so it is always in the range [0, 1].
  • W is the distance from the camera to the fragment.
like image 188
Proxy Avatar answered Oct 12 '22 14:10

Proxy