2
\$\begingroup\$

In openGL, let's say I output one single point from the vertex shader with this value

gl_Position = vec4(2.0,3.0,5.0,7.0);

what exact math operations happen to "z" after leaving the vertex shader?
what will be the end value of that depth texel?

\$\endgroup\$
2

3 Answers 3

1
\$\begingroup\$

After all of your transformations are applied (rotations, perspective transformations, etc.), all of the coordinates are divided by w (the fourth value in the gl_Position vector) to determine Normalized Device Coordinates, NDC. In other words NDC = (x/w, y/w, z/w)

The x, y, and z coordinates in NDC space are in the range [-1..1] if they are in the clip region. The x and y coordinates are used for the viewport transformation. The z coordinate is linearly transformed into the range [0..1] and is used for depth calculations. This last step depends on the values set by glDepthRange: 0=near and 1=far are the default values.

This is detailed in the OpenGL red book, and here.

\$\endgroup\$
2
  • \$\begingroup\$ Are you sure about this? AFAIK, after z/=w z is in -1..1 range (this is what you should get from gl_FragCoord.z). And then it is mapped to 0..1 (using something like z = z / 2 + 0.5), which is written to depth texture. \$\endgroup\$ Jun 8, 2016 at 16:41
  • \$\begingroup\$ @HolyBlackCat you are correct; I edited my answer. \$\endgroup\$ Jun 9, 2016 at 0:00
0
\$\begingroup\$

If I remember correctly, z (as well as x and y) will be divided by w.

Then, everything outside of -1..1 will be culled.

And then, resulting value will be mapped to 0..1 (or to whatever range you selected with glDepthRange()).

In case of default range, full formula would be depth = z / w / 2 + 0.5.

\$\endgroup\$
2
  • \$\begingroup\$ there is something else happening after z/w \$\endgroup\$
    – porente
    Jun 8, 2016 at 1:40
  • \$\begingroup\$ @Wusevari Edited. \$\endgroup\$ Jun 8, 2016 at 20:56
-3
\$\begingroup\$

after setting

glDepthRange(n, f);

Full formula:

finalDepth = (gl_Position.z/gl_Position.w)*(f-n)*0.5+(f+n)*0.5

Bonus:
Every other answer out there about depth buffer always assumes the use of projection matrix, this matrix is a waste of space, time and precision, of the 16 floats that it has only 2 are really needed, the "field of view" and the "screen ratio".
OpenGL makes the precision worst by not giving us control of that math formula of final depth value.

\$\endgroup\$
4
  • \$\begingroup\$ The formula is correct. I would also mention that default range is 0..1. \$\endgroup\$ Jun 9, 2016 at 0:13
  • 2
    \$\begingroup\$ But the statements about projection matrix seem very questionable: "waste of space" - It's faster and easier to multiply by matrix than manually computing everything. "makes precision worse" - Why would manual calculations be more precise? Or if you're talking about non-linear mapping of z to depth, then there is so-called w-buffer to avoid this effect. | "not giving us control of that math formula" - Just set w to 1 and compute everything manually. Or directly assign to gl_FragDepth, if you only care about depth. | "only 2 are really needed" - You also need znear and zfar. \$\endgroup\$ Jun 9, 2016 at 0:17
  • \$\begingroup\$ Don't know why the down votes, I tested the formula and finally fixed my problem, and I answer the question in this website(without links), and it has even a bonus ;^) \$\endgroup\$
    – porente
    Jun 9, 2016 at 0:18
  • 1
    \$\begingroup\$ I think the bonus is the reason for downvotes. (At least it is for my one.) \$\endgroup\$ Jun 9, 2016 at 10:29

You must log in to answer this question.

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