Given a NDC depth value (sampled from a depth texture) and the near and far values used in the projection matrix how do I go from non linear NDC depth to linear viewspace depth? Figuring this out saves me having to use MRTs storing viewspace depth in it's own texture, I can just sample a depth texture directly (useful for things like volumefog and softparticles). The only good examples I have found are for D3D10 and I am having trouble doing the coordinate system change.

Dark Photon

04-23-2010, 05:37 AM

Given a NDC depth value (sampled from a depth texture) and the near and far values used in the projection matrix how do I go from non linear NDC depth to linear viewspace depth?

Common question. You can figure all this out yourself just by looking at the appropriate OpenGL projection matrix (see Appendix F in the Red Book, or the bottom of this page (http://www.songho.ca/opengl/gl_projectionmatrix.html)) you used for computing the depth texture values.

And note that typically you don't store Z_ndc NDC-space depth (-1..1) in a depth texture. You usually store Z_viewport -- that is viewport-space depth (0..1, or whatever you set glDepthRange to). But undoing that mapping to get to Z_ndc is easy.

Referring to the projection matrix, for a perspective projection you have:

That did it. This works especially well because it gives you the correct value regardless of the ndc z mapping (-1 to 1, 0 - 1). I was trying to solve a much harder problem than needed, I was basically trying to solve the same equation for z_eye but using the full equations for gl_ProjectionMatrix[2] + gl_ProjectionMatrix[3] using only the far and near values. Thanks!