0
votes

I'm trying to access a DepthComponent Texture in my GLSL Shader of version 400.

The program does a two pass rendering. In the first pass I render all the geometry and colors to a Framebuffer on which I have a ColorAttachment and DepthAttachment. The DepthAttachment is bound like this:

(Note: I'm using C# with OpenTK, which is strongly typed, in my code examples.)

GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, depthTexture.ID, 0);

The depth Texture has an internal pixel format of DepthComponent32f, pixel format of DepthComponent and Float as pixel type. All the other properties have default values.

The second pass renders the framebuffers color image onto the screen using the following shader:

#version 400
uniform sampler2D finalImage;
in vec2 texCoords;
out vec4 fragColor;
void main(){
    fragColor = vec4(texture2D(finalImage, texCoords.xy).rgb, 1.0);
}

But now I want to read the depth Texture(DepthComponent) instead of the color Texture(RGBA).

I tried a lot of things like disabling TextureCompareMode, using shadow2DSampler with shadow2DProj(sampler, vec4(texCoords.xy, 0.0, 1.0)) or just textureProj(sampler, vec3(texCoords.xy, 0.0)). But it returns only 1 or 0, depends on which configuration I use.

To be sure that my depth Texture is ok, I've read the pixels back to a float array like this:

GL.ReadPixels(0, 0, depthTexture.Width, depthTexture.Height, PixelFormat.DepthComponent, PixelType.Float, float_array);

Everything seems to be correct, its showing me 1.0 for empty space and values between 0.99 and 1.0 for visible objects.

Edit Here is a code example how my process looks like:

Init code

depthTexture= new GLEXTexture2D(width, height);
        depthTexture.TextureCompareMode = TextureCompareMode.None;
        depthTexture.CreateMutable(PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float);
***CreateMutable Function***
ReserveTextureID();
GLEX.glBeginTexture2D(ID);
GL.TexImage2D(TextureTarget.Texture2D, 0, pInternalFormat, width, height, 0, pFormat, pType, IntPtr.Zero);
ApplyOptions();
MarkReserved(true);
GLEX.glEndTexture2D();

(Framebuffer attachment mentioned above)

Render pass 1

GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawBuffer.ID);
        GL.Viewport(0, 0, depthTexture.Width, depthTexture.Height);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
        GL.Enable(EnableCap.DepthTest);
        GL.ClearColor(Color.Gray);
        GL.UseProgram(geometryPassShader.ID);
        geometry_shaderUniformMVPM.SetValueMat4(false, geometryImageMVMatrix * geometryImageProjMatrix);
        testRectangle.Render(PrimitiveType.QuadStrip);
        GL.UseProgram(0);
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

Render pass 2

 GL.Viewport(0, 0, depthTexture.Width, depthTexture.Height);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
        GL.ClearColor(Color.White);
        GL.UseProgram(finalImageShader.ID);
        GL.ActiveTexture(TextureUnit.Texture0);

        depthTexture.Bind();
        final_shaderUniformMVPM.SetValueMat4(false, finalImageMatrix);
        screenQuad.Render(PrimitiveType.Quads);
        GL.UseProgram(0);
        GL.BindTexture(TextureTarget.Texture2D, 0);
1
There is nothing special when reading from a depth texture compared to reading from a color texture. Please provide a minimal not working example since it is impossible to tell how your textures are bound etc.BDL
@BDL added a code example of my process. Geometry shader is not included because its just a basic color shader and depth values are read correctly using ReadPixels.bitQUAKE
Unrelated, but if you set the clear color after you cleared the screen it will not have any effect.BDL

1 Answers

0
votes

A few hours later I found the solution. The Problem was the MinFilter. Like the khronos group said on glTexParameter:

The initial value of GL_TEXTURE_MIN_FILTER is GL_NEAREST_MIPMAP_LINEAR.

I changed the MinFilter of my depth Texture to GL_NEAREST (where GL_LINEAR is also legal) and now the depth values in the GLSL shader are right (after linearization of course).

Additional Info: There are some extensions for MagFilter like LINEAR_DETAIL_ALPHA_SGIS. I`ve tried some of these, the depth value correctness was not affected.