Not sure if this should go here or in the shader forum…
I am having trouble deciphering why my render depth buffer is coming out not as expected. I am attempting to write a shader based shadow mapper, as I was partially successful with an immediate mode version.
I have attached three screen shot to attempt to illustrate this along with the GL setup code and the two shaders.
It appears that my off screen depth buffer is storing only 8bit values and not the packed 32 float to RGBA I am attempting to store. This is seen when I capture the depth buffer and output to a file. The areas with infinite depth have 80 80 80 FF as there hex values, R, G, B all have same value and alpha is FF or 1, I’m assuming 80 is 0.5. This is illustrated by the depth.jpg.
The depth_noshader.jpg show the same logic but no enabling the render buffer thus rendering to the current screen buffer. Basically not calling glBindBuffer(GL_FRAME_BUFFER). By the looks of the output I’d say the say the shader is calculating a floating point representation in RGBA. Banding seems to indicate some accurate scaling.
The screencapture.jpg is a shoe of the final render stage with the depth buffer in the lower right.
All I can seem to get out of the shader is an alpha effect. All my depth calculations fail as I suspect the depth buffer doesn’t actually have what I really want to see, the linearly adjusted distance from light source on the first pass to depth buffer.
Can anyone see from the code below is there is something wrong with the way the depth buffer is setup? I suspect the problem is there as when rendering to the actual frame buffer the bluish banding seems consistent with what I might expect a bit pattern to progress by for depth.
Setup Render Depth Buffer
private bool SetupDepthMapTexture(int width, int height, int depth)
{
// Generate the frame buffer and bind
Gl.glGenFramebuffersEXT(1, out frameBufferID);
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, frameBufferID);
// Generate the render buffer and bind
Gl.glGenRenderbuffersEXT(1, out renderBufferID);
Gl.glBindRenderbufferEXT(Gl.GL_RENDERBUFFER_EXT, renderBufferID);
// Render buffer depth, width and height setup
Gl.glRenderbufferStorageEXT(Gl.GL_RENDERBUFFER_EXT, depth, width, height);
// Attach the render buffer to the frame buffer
Gl.glFramebufferRenderbufferEXT(Gl.GL_FRAMEBUFFER_EXT,
Gl.GL_DEPTH_ATTACHMENT_EXT, Gl.GL_RENDERBUFFER_EXT, renderBufferID);
// Setup for new color(draw) buffer and to read buffer
Gl.glDrawBuffer(Gl.GL_NONE);
Gl.glReadBuffer(Gl.GL_NONE);
// Generate texture and bind
Gl.glGenTextures(1, out textureBufferID);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, textureBufferID);
// Allocate texture space of desired format but no data is specified
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_DEPTH_COMPONENT32,
1024, 1024, 0, Gl.GL_DEPTH_COMPONENT, Gl.GL_FLOAT, null);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_DEPTH_TEXTURE_MODE, Gl.GL_INTENSITY);
// Attach texture to FBO so we can render to it
Gl.glFramebufferTexture2DEXT(Gl.GL_FRAMEBUFFER_EXT,
Gl.GL_DEPTH_ATTACHMENT_EXT, Gl.GL_TEXTURE_2D, textureBufferID, 0);
// Check if FBO creation was successful
int status = Gl.glCheckFramebufferStatusEXT(Gl.GL_FRAMEBUFFER_EXT);
if (status != Gl.GL_FRAMEBUFFER_COMPLETE_EXT)
{
frameBufferID = renderBufferID = textureBufferID = -1;
return false;
}
// Revert back to fixed pipeline rendering
Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);
Gl.glBindFramebufferEXT(Gl.GL_FRAMEBUFFER_EXT, 0);
return true;
}
Vertex Shader
#version 120
uniform mat4 mProjection;
uniform mat4 mView;
uniform mat4 mModel;
attribute vec3 a_vVertex;
varying vec4 v_vPosition;
void main(void)
{
v_vPosition = mView * mModel * vec4(a_vVertex, 1.0);
gl_Position = mProjection * v_vPosition;
}
Fragment Shader
#version 120
varying vec4 v_vPosition;
vec4 pack (float depth)
{
const vec4 c_bias = vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);
float r = depth;
float g = fract(r * 255.0);
float b = fract(g * 255.0);
float a = fract(b * 255.0);
vec4 color = vec4(r, g, b, a);
return color - (color.yzww * c_bias);
}
void main()
{
const float c_LinearDepthConstant = 1.0 / (1.0 - 30.0);
float linearDepth = length(v_vPosition) * c_LinearDepthConstant;
gl_FragColor = pack(linearDepth);
}