I thought that whenever you transform an object to world space, then view space and finally screen space, the last matrix you apply(the projection matrix) normalizes the z values between 0 and 1.

However, I'm getting big z coordinates, which implies that the projection matrix didn't normalize it. Am I doing something wrong? I mean, all I do is:

gl_Position = projection * view * world * gl_Vertex;

2 Answers 2


You are missing a few key points.

After the application of the projection matrix, you have a 4-component vector in clip space (not screen space), which is a homogeneous coordinate system in which clipping will be performed (after your vertex shader).

After clipping, the surviving coordinates are divided by the w component to get normalized device coordinates in (-1, 1). A transformation will then be applied to move from NDC space to window coordinates, where the X and Y coordinates are normalized based on the viewport provided to OpenGL and the Z coordinate is normalized based on the depth range, which is ultimately what gives you your (0, 1) range for depth (unless you use glDepthRange to set a different range).

If you want to access this normalized Z value in your vertex shader, you will need to do the computation manually in the shader (based on the information above).

  • \$\begingroup\$ Damn it, you beat me by a few seconds :P \$\endgroup\$
    – Polar
    Nov 20, 2013 at 17:49
  • \$\begingroup\$ And if I want to access the z value in the fragment shader? I presume gl_FragCoord won't be of any help too? \$\endgroup\$
    – Kipras
    Nov 20, 2013 at 18:04
  • \$\begingroup\$ @Polar Multiple answers are fine (especially when they're only a few seconds apart). Saying the same thing in slightly different ways may help get the point across to future visitors. So in the future, don't hold back your answers just because there's another answer already :) \$\endgroup\$
    – House
    Nov 20, 2013 at 18:12
  • \$\begingroup\$ @Byte56 Yeah, but Josh's answer had what I'd written and a fair bit more, so I didn't reckon it was worth adding the answer. \$\endgroup\$
    – Polar
    Nov 20, 2013 at 18:49
  • 2
    \$\begingroup\$ @Kipras gl_FragCoord.z should give the window-space (normalized) depth in the fragment shader. \$\endgroup\$ Nov 21, 2013 at 2:51

Multiplying a vertex position by the world, view, and projection matrices generates a position in homogeneous coordinates, i.e. (x, y, z, w). Only after dividing by w are the xyz values between -1 and 1 (note: not 0 to 1).

If you're not familiar with homogeneous coordinates, see these other questions on this site: What does the graphics card do with the fourth element of a vector? and Do I need the 'w' component in my Vector class?


You must log in to answer this question.

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