# gl\_FragCoord.z

**URL:** <https://community.khronos.org/t/gl-fragcoord-z/54092>\
**Category:** OpenGL: Advanced Coding\
**Created:** [February 21, 2008, 4:08am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092 "2008-02-21T04:08:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michele\_Bosi](https://community.khronos.org/letter_avatar_proxy/v4/letter/m/ee7513/32.png) [@Michele\_Bosi](https://community.khronos.org/u/Michele_Bosi)\
**Post date:** [February 21, 2008, 4:08am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/1 "2008-02-21T04:08:13Z")

</div>

Hello,  
I would like to know in what space is defined the value gl\_FragCoord.z. As far as I know gl\_FragCoord.x and y are in screen coordinates, but the .z component seems to gives values always between more or less 0.9 and 1.0.  
How can I compute the world or eye .z coordinate from gl\_FragCoord.z?

Thanks!  
Mic

---

<div class="post-metadata">

**Author:** ![NiCo1](https://community.khronos.org/letter_avatar_proxy/v4/letter/n/f6c823/32.png) [@NiCo1](https://community.khronos.org/u/NiCo1)\
**Post date:** [February 21, 2008, 4:22am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/2 "2008-02-21T04:22:40Z")

</div>

From the GLSL spec:

> ```
> The fixed functionality computed depth for a fragment may be obtained by reading gl_FragCoord.z, ...
> 
> ```

So at the near plane this value is 0 and at the far plane it’s 1.

You can calculate the world/eye z-coordinates the same way [gluUnproject](http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/unproject.html) does.

N.

---

<div class="post-metadata">

**Author:** ![knackered](https://community.khronos.org/user_avatar/community.khronos.org/knackered/32/58_2.png) [@knackered](https://community.khronos.org/u/knackered)\
**Post date:** [February 21, 2008, 4:48am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/3 "2008-02-21T04:48:50Z")

</div>

and because z is non-linear to favour the nearer triangles, most of a scenes z will be in that very small range (0.9 to 1.0).  
You can linearise it by encoding (z-near)/(far-near) in the z column of projection matrix, and pre-multiply z by w in the vertex shader : (z \* w) / w = z

---

<div class="post-metadata">

**Author:** ![Michele\_Bosi](https://community.khronos.org/letter_avatar_proxy/v4/letter/m/ee7513/32.png) [@Michele\_Bosi](https://community.khronos.org/u/Michele_Bosi)\
**Post date:** [February 21, 2008, 6:53am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/4 "2008-02-21T06:53:56Z")

</div>

Thank you guys, the source code of gluUnproject seems the definitive reference 🙂

---

<div class="post-metadata">

**Author:** ![Xmas](https://community.khronos.org/letter_avatar_proxy/v4/letter/x/958977/32.png) [@Xmas](https://community.khronos.org/u/Xmas)\
**Post date:** [February 21, 2008, 7:21am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/5 "2008-02-21T07:21:37Z")

</div>

> [@knackered](#):
>
> and because z is non-linear to favour the nearer triangles, most of a scenes z will be in that very small range (0.9 to 1.0).  
> You can linearise it by encoding (z-near)/(far-near) in the z column of projection matrix, and pre-multiply z by w in the vertex shader : (z \* w) / w = z

I suppose what you actually meant was Zclip = Wclip \* (2\*(Zview-near)/(far-near) - 1), as OpenGL clip space ranges from -Wclip to +Wclip, or -1 to 1 after perspective division. It’s only the viewport transformation that scales this to [n, f] as given by glDepthRange(n, f).

Your formula would very likely move the near clip plane behind the camera (if far \> 2 \* near) which can lead to weird artifacts.

But there is another catch: Z interpolation is always linear in screen space, i.e. the difference between Z in neighboring fragments is constant, unlike perspective correct varyings which are usually linear in view space but non-linear in screen space.  
Because of this, if you use a perspective projection the per-vertex Z values in screen space must be non-linear. Otherwise the interpolated Z values are wrong, and you could have a small object appear in front of a large polygon even though it’s actually behind.

---

<div class="post-metadata">

**Author:** ![system](https://community.khronos.org/uploads/default/original/2X/b/ba89cb49313a0e869198c8be354afde8bcae027e.png) [@system](https://community.khronos.org/u/system)\
**Post date:** [February 21, 2008, 7:31am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/6 "2008-02-21T07:31:58Z")

</div>

> [@Michele\_Bosi](#):
>
> Hello,  
> How can I compute the world or eye .z coordinate from gl\_FragCoord.z?
> 
> Thanks!  
> Mic

Just do this in the VS  
varying float EyeVertexZ;  
EyeVertexZ = (ModelView \* gl\_Vertex).z;

and in the FS  
you can use EyeVertexZ

---

<div class="post-metadata">

**Author:** ![Michele\_Bosi](https://community.khronos.org/letter_avatar_proxy/v4/letter/m/ee7513/32.png) [@Michele\_Bosi](https://community.khronos.org/u/Michele_Bosi)\
**Post date:** [February 21, 2008, 11:07am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/7 "2008-02-21T11:07:43Z")

</div>

Thank you V-man, that’s so easy that I cannot expalin how I couldn’t think about it before! Will try it immediately…

---

<div class="post-metadata">

**Author:** ![oc2k1](https://community.khronos.org/user_avatar/community.khronos.org/oc2k1/32/97_2.png) [@oc2k1](https://community.khronos.org/u/oc2k1)\
**Post date:** [February 21, 2008, 4:20pm UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/8 "2008-02-21T16:20:42Z")

</div>

It is possible to convert a Z buffer value to the distance with:

```auto

float Z = gl_ProjectionMatrix[3].z/(gl_FragCoord.z * -2.0 + 1.0 - gl_ProjectionMatrix[2].z);

```

This is useful for deferred rendering, but if the distance is already known in a vertex shader, a varying is faster.

---

<div class="post-metadata">

**Author:** ![cass](https://community.khronos.org/user_avatar/community.khronos.org/cass/32/4347_2.png) [@cass](https://community.khronos.org/u/cass)\
**Post date:** [February 23, 2008, 3:39am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/9 "2008-02-23T03:39:55Z")

</div>

In OpenGL, the gl\_FragCoord.w is the reciprocal of the clip space w of the fragment, which is just the eye space z (or the negative of it, anyway).

In D3D, frag.w really is just the clip space w, and thus doesn’t need to be reciprocated for use as eye space z.

---

<div class="post-metadata">

**Author:** ![sqrt\_1](https://community.khronos.org/user_avatar/community.khronos.org/sqrt_1/32/61_2.png) [@sqrt\_1](https://community.khronos.org/u/sqrt_1)\
**Post date:** [April 28, 2008, 6:39pm UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/10 "2008-04-28T18:39:07Z")

</div>

> [@oc2k1](#):
>
> It is possible to convert a Z buffer value to the distance with:
> 
> ```auto
> 
> float Z = gl_ProjectionMatrix[3].z/(gl_FragCoord.z * -2.0 + 1.0 - gl_ProjectionMatrix[2].z);
> 
> ```
> 
> This is useful for deferred rendering, but if the distance is already known in a vertex shader, a varying is faster.

Sorry for the thread revive…  
I have seen this code in a few places - but I cannot seem to figure out the math behind it. Is there an article or tutorial somewhere on this?

---

<div class="post-metadata">

**Author:** ![sqrt\_1](https://community.khronos.org/user_avatar/community.khronos.org/sqrt_1/32/61_2.png) [@sqrt\_1](https://community.khronos.org/u/sqrt_1)\
**Post date:** [April 28, 2008, 8:52pm UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/11 "2008-04-28T20:52:58Z")

</div>

Never mind, I figured out the math.  
For reference:

Using the projection math from here to get C and D:  
[http://www.opengl.org/sdk/docs/man/xhtml/glFrustum.xml](http://www.opengl.org/sdk/docs/man/xhtml/glFrustum.xml)

we can see that to get the final depth (F) from the view depth (V) (matrix expansion and divide by w and assuming w = 1)

F = (V\*C + D) / -V

therefore to get V from F…

F = -C + (D / -V)  
F + C = D / -V  
(F + C) / D = 1 / -V  
D / (F + C) = -V  
D / (-F - C) = V

also as F needs scaling from 0…1 to -1…1 we need to F\*2-1 which equals:

D / (F \* -2 + 1 - C) = V

Which is what was shown above.

---

<div class="post-metadata">

**Author:** ![DungeonLords](https://community.khronos.org/letter_avatar_proxy/v4/letter/d/4bbf92/32.png) [@DungeonLords](https://community.khronos.org/u/DungeonLords)\
**Post date:** [November 19, 2009, 4:17am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/12 "2009-11-19T04:17:01Z")

</div>

Hi all!

Please say, is gl\_FragCoord.z/gl\_FragCoord.w a distance from the point to camera?

---

<div class="post-metadata">

**Author:** ![Dark\_Photon](https://community.khronos.org/user_avatar/community.khronos.org/dark_photon/32/4349_2.png) [@Dark\_Photon](https://community.khronos.org/u/Dark_Photon)\
**Post date:** [November 19, 2009, 5:25am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/13 "2009-11-19T05:25:39Z")

</div>

> [@DungeonLords](#):
>
> Please say, is gl\_FragCoord.z/gl\_FragCoord.w a distance from the point to camera?

Nope. Check [the spec](http://www.opengl.org/registry/doc/GLSLangSpec.1.50.09.pdf).

gl\_FragCoord is window-relative (screen) coordinates. .xy is pixel units of the center of the fragment. .z is the depth value that’ll be written to the depth buffer (0…1). .w is 1/clip\_space.w, where (for perspective projections only!!) clip\_space.w is -eye\_space.z, so: gl\_FragCoord.w = -1/eye\_space.z … for perspective projections only!

For orthographic projections, gl\_FragCoord.w should just be 1 (i.e. 1/clip\_space.w, i.e. 1/eye\_space.w, where eye\_space.w == 1).

For confirmation, see the last row of the perspective and orthographic projection transforms in Appendix F of the Red Book.

So for a perspective projection, you probably want -1/gl\_FragCoord.w. Keep in mind this gives you eye-space Z, where values in front of the screen are negative. If you want positive, don’t negate.

Also, you said you wanted a distance from the point to the camera (eyepoint, presumably). This is not what eye\_space Z is! eye\_space Z is a minimum distance from the XY plane in eye-space to the point, not a radial distance from the eyepoint (0,0,0) to the point. This is the same concept as between EYE\_PLANE fog coordinate mode and EYE\_RADIAL fog coordinate modes, from the pre-shader days.

---

<div class="post-metadata">

**Author:** ![DungeonLords](https://community.khronos.org/letter_avatar_proxy/v4/letter/d/4bbf92/32.png) [@DungeonLords](https://community.khronos.org/u/DungeonLords)\
**Post date:** [November 19, 2009, 1:11pm UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/14 "2009-11-19T13:11:54Z")

</div>

Thank you!!!

Then whot is this: float Oz = gl\_FragCoord.z/gl\_FragCoord.w;

---

<div class="post-metadata">

**Author:** ![Dark\_Photon](https://community.khronos.org/user_avatar/community.khronos.org/dark_photon/32/4349_2.png) [@Dark\_Photon](https://community.khronos.org/u/Dark_Photon)\
**Post date:** [November 20, 2009, 4:57am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/15 "2009-11-20T04:57:03Z")

</div>

> [@DungeonLords](#):
>
> Then whot is this: float Oz = gl\_FragCoord.z/gl\_FragCoord.w;

For a perspective projection…  
gl\_FragCoord.z/gl\_FragCoord.w == (0…1 depth value of fragment) \* (eye\_space Z value of fragment)

Math-wise, this makes no sense to me (maybe I need more caffeine this morning).

Just out of curiousity, where did you get this expression? Googling, I find these top hits:

- [oZone3D.Net: Fog in GLSL](http://www.ozone3d.net/tutorials/glsl_fog/p04.php)
- [Ogre Forums: How to render the Z-buffer to a Texture](http://www.ogre3d.org/forums/viewtopic.php?t=38354&start=0&postdays=0&postorder=asc&highlight=)
- [Gamedev.net: Debugging the depth buffer of a FBO](http://www.gamedev.net/community/forums/topic.asp?topic_id=508269)

Your wording suggests the first (oZone3D). This states the expression is “The distance between the camera and the current pixel (the z axis value)”. Sorry, I’m not buying it.

Maybe someone else can make sense of this.

---

<div class="post-metadata">

**Author:** ![tomriddle](https://community.khronos.org/user_avatar/community.khronos.org/tomriddle/32/3048_2.png) [@tomriddle](https://community.khronos.org/u/tomriddle)\
**Post date:** [October 15, 2011, 6:07am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/16 "2011-10-15T06:07:55Z")

</div>

Thanks to all.

And I want to ask one question.

To render out the depth with shader, I think this is the quickest way.

[b]smooth in vec4 ex\_Color ;  
out vec4 out\_Color ;

void main(void){  
float depth = gl\_FragCoord.z ;  
out\_Color = vec4(depth, depth, depth, 1.0) ;  
}[/b]

however, you mentioned that this gl\_FragCoord.z is not linear above.

this is very important to me since this depth render is not for graphic rather an academic computer vision mid ware for me.

then my question is how to linearlize it?

could you just modify my code to give me an answer?

thanks

---

<div class="post-metadata">

**Author:** ![Dark\_Photon](https://community.khronos.org/user_avatar/community.khronos.org/dark_photon/32/4349_2.png) [@Dark\_Photon](https://community.khronos.org/u/Dark_Photon)\
**Post date:** [October 15, 2011, 5:31pm UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/17 "2011-10-15T17:31:29Z")

</div>

> [@tomriddle](#):
>
> …however, you mentioned that this gl\_FragCoord.z is not linear above … then my question is how to linearlize it?

See [Re: Urgent: Accessing Depth Texture FBO in GLSL](http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=298939&Searchpage=1&Main=57630&Words=geeks3d&Search=true#Post298939)

---

<div class="post-metadata">

**Author:** ![tomriddle](https://community.khronos.org/user_avatar/community.khronos.org/tomriddle/32/3048_2.png) [@tomriddle](https://community.khronos.org/u/tomriddle)\
**Post date:** [October 16, 2011, 12:19am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/18 "2011-10-16T00:19:58Z")

</div>

thank you!

As a beginner modern GL learner, I still have some questions.

1. eventually, I want this rendered depth map of an object to store in a OpenCV Mat data type (as a picture).

Is this means I must render this object to frame buffer then do some memory copy to another data type? I even don’t need it to display on the screen. How to achieve this fast and avoid to cost CPU time? it seems your redirect link showed something about glBlitzFrameBuffer(), but I don’t know what function should I use in this case.

1. [http://www.geeks3d.com/20091216/geexlab-how-to-visualize-the-depth-buffer-in-glsl/](http://www.geeks3d.com/20091216/geexlab-how-to-visualize-the-depth-buffer-in-glsl/)  
this example seems involved in the texture calculations.  
I’m not sure whether to use texture there, can you just calculate the linear depth from the gl\_FragCoord.z?

is there any mature example I can code as a reference? that geek3d lab has only piece of shader program…

1. I’d display (store) the near as white (1), far as black(0).

so now I modified

glDepthFunc(GL\_GEQUAL); //because it reversed, this must be turned  
glDepthRange(1.0f, 0.0f); //reverse

and clear depth at display function  
glClearDepth(0.0f) ;//since reversed

then my old frag shader works right except the value is not linear.

am I doing this right?

how to modify the geek3d example do the same?

thank you so much.

---

<div class="post-metadata">

**Author:** ![Dark\_Photon](https://community.khronos.org/user_avatar/community.khronos.org/dark_photon/32/4349_2.png) [@Dark\_Photon](https://community.khronos.org/u/Dark_Photon)\
**Post date:** [October 17, 2011, 5:52am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/19 "2011-10-17T05:52:14Z")

</div>

> [@tomriddle](#):
>
> 1. eventually, I want this rendered depth map of an object to store in a OpenCV Mat data type (as a picture). …this means I must render this object to frame buffer then do some memory copy to another data type?

That would be the easiest way to go. Render the scene, then use glReadPixels to fetch the color (or depth) buffer back to the CPU, then do what you want with it.

glBlitFramebuffer is a function that provides for transferring data from one framebuffer to another. You instead want to get your data back from the framebuffer (and/or a texture) to the CPU.

> 1. …this example seems involved in the texture calculations. I’m not sure whether to use texture there, can you just calculate the linear depth from the gl\_FragCoord.z?

Even easier: for perspective projections specifically (see posts above), -1/gl\_FragCoord.w will be eye-space Z. Just scale and shift that by near/far to get in your desired 0…1 value.

But to your point about texture, if you don’t care about what the color buffer for the scene is, and you just want the color buffer to be a linearized version of the depth buffer, then yes, you can just skip the intermediate texture (and multipass), and do all this in a single pass writing directly to the framebuffer using a simple fragment that basically just pipes your linearized 0…1 value to the color output (using the depth buffer behind-the-scenes for occlusion as normal). So for computing your color value in the frag shader, something like:

```auto

gl_FragColor.rrr = ( 1/gl_FragCoord.w - n ) / (f - n); // 0 = near; 1 = far
gl_FragColor.a = 1.0;

```

> 1. I’d display (store) the near as white (1), far as black(0). so now I modified…

I guess you could do that. But even simpler would just be to take your computed 0…1 value in the shader, negate, and add 1.

---

<div class="post-metadata">

**Author:** ![tomriddle](https://community.khronos.org/user_avatar/community.khronos.org/tomriddle/32/3048_2.png) [@tomriddle](https://community.khronos.org/u/tomriddle)\
**Post date:** [October 19, 2011, 8:05am UTC](https://community.khronos.org/t/gl-fragcoord-z/54092/20 "2011-10-19T08:05:38Z")

</div>

[quote=“Dark\_Photon”]

> [@tomriddle](#):
>
> I guess you could do that. But even simpler would just be to take your computed 0…1 value in the shader, negate, and add 1.

yes! how didn’t I come out this…

but I knew glReadPixels() was deprecated and very slow…
