8

I'm using THREE.js with shader. I'm trying to get the zbuffer information.

Vertex shader:

// switch on high precision floats
#ifdef GL_ES
precision highp float;
#endif

void main()
{
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

Fragment shader:

#ifdef GL_ES
precision highp float;
#endif

void main()
{
    gl_FragColor = vec4(gl_FragCoord.x, gl_FragCoord.y, gl_FragCoord.z, 1.0);
}

There are objects with different position in the scene, thus the values in zbuffer should vary.

It's strange that gl_FragCoord.x, gl_FragCoord.y and gl_FragCoord.z seems to be 1.0 for all fragments, while gl_FragCoord.w seems to vary for different fragments.

If I use gl_FragCoord.w:

#ifdef GL_ES
precision highp float;
#endif

void main()
{
    float zbuffer = gl_FragCoord.w * 500.0;
    gl_FragColor = vec4(zbuffer, zbuffer, zbuffer, 1.0);
}

It seems to be the zbuffer image:

enter image description here

So why would gl_FragCoord.w be representing depth information while gl_FragCoord.z is always 1.0 for all fragments?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Ovilia
  • 7,066
  • 12
  • 47
  • 70

1 Answers1

16

gl_FragCoord is in window space. And window space is in pixel coordinates of the window. So virtually all of your fragments are going to have values > 1.0. And since you're almost certainly not rendering to a floating-point framebuffer, your colors will be clamped to the [0, 1] range.

gl_FragCoord.z is probably not 1.0, but it may be close enough to it, depending on your depth range and how far the objects are from the camera. If you want to get a real idea of the depth, you need to linearize it.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    How can I get screen width and height in shader? – Ovilia Mar 01 '13 at 05:38
  • But why is `gl_FragCoord.w` varying for different fragments? – Ovilia Mar 01 '13 at 13:54
  • @Ovilia: For the same reason that the other three components do. The difference is that you don't *see it*. – Nicol Bolas Mar 01 '13 at 16:46
  • 3
    Additionally, if somebody asks why `w` has the depth, in reality it has "1/z" according to the standard, but `z` is much higher than 1, so that puts the `w` value in the 0-1 range. Far depths will give darker pixels, low depths brighter ones, and thats why the OP gets those results. – DarkZeros May 18 '15 at 10:43