# Process of writing to the depth texture

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?

• gamedev.stackexchange.com/questions/8050/… josh Petrie says the next operations, but he just says them and I want the exact formula Jun 8, 2016 at 1:52
• The accepted answer to the question you referenced in your comment does mention that the z value is divided by w. Jun 8, 2016 at 14:42

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.

• 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. Jun 8, 2016 at 16:41
• @HolyBlackCat you are correct; I edited my answer. Jun 9, 2016 at 0:00

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.

• there is something else happening after z/w Jun 8, 2016 at 1:40
• @Wusevari Edited. Jun 8, 2016 at 20:56

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.

• The formula is correct. I would also mention that default range is 0..1. Jun 9, 2016 at 0:13
• 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. Jun 9, 2016 at 0:17
• 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 ;^) Jun 9, 2016 at 0:18
• I think the bonus is the reason for downvotes. (At least it is for my one.) Jun 9, 2016 at 10:29