5
\$\begingroup\$

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;
\$\endgroup\$
13
\$\begingroup\$

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).

\$\endgroup\$
  • \$\begingroup\$ Damn it, you beat me by a few seconds :P \$\endgroup\$ – Polar Nov 20 '13 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 '13 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\$ – MichaelHouse Nov 20 '13 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 '13 at 18:49
  • 2
    \$\begingroup\$ @Kipras gl_FragCoord.z should give the window-space (normalized) depth in the fragment shader. \$\endgroup\$ – Nathan Reed Nov 21 '13 at 2:51
2
\$\begingroup\$

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?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.