0

When I create z-buffer texture like so:

gl.bindTexture(GL_TEXTURE_2D, texBuff);
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gl.texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, frameBuff.width, frameBuff.height,    0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, null);

I get a proper z-buffer which I can then use for shadows (and my shadows render fine). However, if I create a color texture, and color the texture with the z-value, my shadows have a lot of artifacts (even with a high bias). The color buffer is created like this:

gl.bindTexture(GL_TEXTURE_2D, colorBuff);
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, frameBuff.width, frameBuff.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);

This is the fragment shader program that writes to the color buffer:

precision highp float;
void main() {
    float z = gl_FragCoord.z;
    gl_FragColor = vec4(z, z, z, 1.0); 
}

When I render the two textures to some surface, they look similar.

So my question is, why is my color texture not working? Is gl_FragCoord.z not the correct z value that's written to the z-buffer? According to http://www.opengl.org/sdk/docs/manglsl/xhtml/gl_FragCoord.xml it is. Are the texture coordinated different when I bind a color buffer? Or is the z value incorrect?

spearmunkie
  • 21
  • 1
  • 7

1 Answers1

4

This question took me a long time to parse :) I hope I got the right answer:

It's just precision. A depth component texture has at least 16 bits for the z value. In color you have only 8 bits per channel. Instead of writing the same z to rgb, you can write something like (z,frac(z*256.0),frac(z*256.0*256.0)) to write a full 24 bits. It will look weird but you can decode it with a dp3 (1,1/256,1/(256*256)) if you read it back.

Btw, the main reason your question was hard to read was that I never read back fragCoord to get z. I would always just use a texture coordinate to get a texture z. Which gives you a bit more control on how you generate and interpolate the z from the vertex shader.

starmole
  • 4,974
  • 1
  • 28
  • 48
  • You're right, it was a precision issue. I was trying to use the color texture to get full 32-bit precision on the depth value. For some reason, your solution seems to create more artifacts, and I can't seem to get rid of them. It also produces shadows randomly. I think openGL does some extra optimizations. – spearmunkie Oct 15 '13 at 10:22