Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This was asked (by the same person) and <a href="http://www.opengl.org/discussion_boards/showthread.php/179953-%28gl_FragCoord-z-gl_FragCoord-w%29-for-quick-depth-calculation-camera-to-fragment?p=1245290&amp;viewfull=1#post1245290">answered elsewhere</a>. I'm paraphrasing and embellishing the answer here:</p> <p>As stated in section 15.2.2 of the <a href="http://www.opengl.org/registry/doc/glspec43.core.20120806.pdf">OpenGL 4.3 core profile specification (PDF)</a>, <code>gl_FragCoord.w</code> is <code>1 / clip.w</code>, where <code>clip.w</code> is the W component of the clip-space position (ie: what you wrote to <code>gl_Position</code>).</p> <p><code>gl_FragCoord.z</code> is generated by the following process, assuming the usual transforms:</p> <ol> <li>Camera-space to clip-space transform, via projection matrix multiplication in the vertex shader. <code>clip.z = (projectionMatrix * cameraPosition).z</code></li> <li>Transform to normalized device coordinates. <code>ndc.z = clip.z / clip.w</code></li> <li>Transform to window coordinates, using the <a href="http://www.opengl.org/wiki/GLAPI/glDepthRange"><code>glDepthRange</code> near/far values</a>. <code>win.z = ((dfar-dnear)/2) * ndc.z + (dfar+dnear)/2</code>.</li> </ol> <p>Now, using the default depth range of near=0, far=1, we can define <code>win.z</code> in terms of clip-space: <code>(clip.z/clip.w)/2 + 0.5</code>. If we then divide this by <code>gl_FragCoord.w</code>, that is the equivalent of multiplying by <code>clip.w</code>, thus giving us:</p> <pre><code>(gl_FragCoord.z / gl_FragCoord.w) = clip.z/2 + clip.w/2 = (clip.z + clip.w) / 2 </code></pre> <p>Using the standard projection matrix, <code>clip.z</code> represents a scale and offset from camera-space Z component. The scale and offset are defined by the camera's near/far depth values. <code>clip.w</code> is, again in the standard projection matrix, just the negation of the camera-space Z. Therefore, we can redefine our equation in those terms:</p> <pre><code>(gl_FragCoord.z / gl_FragCoord.w) = (A * cam.z + B -cam.z)/2 = (C * cam.z + D) </code></pre> <p>Where <code>A</code> and <code>B</code> represent the offset and scale based on near/far, and <code>C = (A - 1)/2</code> and <code>D = B / 2</code>.</p> <p>Therefore, <code>gl_FragCoord.z / gl_FragCoord.w</code> is <em>not</em> the camera-space (or world-space) distance to the camera. Nor is it the camera-space planar distance to the camera. But it <em>is</em> a linear transform of the camera-space depth. You could use it as a way to compare two depth values together, if they came from the same projection matrix and so forth.</p> <p>To actually compute the camera-space Z, you need to either pass the camera near/far from your matrix (OpenGL <a href="http://www.opengl.org/wiki/Built-in_Variable_%28GLSL%29#Fragment_shader_uniforms">already gives you the range near/far</a>) and compute those <code>A</code> and <code>B</code> values from them, or you need to use the inverse of the projection matrix. Alternatively, you could just use the projection matrix directly yourself, since fragment shaders can use the same uniforms available to vertex shaders. You can pick the <code>A</code> and <code>B</code> terms directly from that matrix. <code>A = projectionMatrix[2][2]</code>, and <code>B = projectionMatrix[3][2]</code>.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload