【发布时间】:2017-10-31 21:45:03
【问题描述】:
我正在尝试在 400 版的 GLSL 着色器中访问深度组件纹理。
程序执行两次渲染。在第一遍中,我将所有几何图形和颜色渲染到一个帧缓冲区,在该缓冲区上我有一个 ColorAttachment 和 DepthAttachment。 DepthAttachment 绑定如下:
(注意:在我的代码示例中,我使用 C# 和 OpenTK,它是强类型的。)
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, depthTexture.ID, 0);
深度纹理的内部像素格式为DepthComponent32f,像素格式为DepthComponent,像素类型为Float。所有其他属性都有默认值。
第二遍使用以下着色器将帧缓冲区彩色图像渲染到屏幕上:
#version 400
uniform sampler2D finalImage;
in vec2 texCoords;
out vec4 fragColor;
void main(){
fragColor = vec4(texture2D(finalImage, texCoords.xy).rgb, 1.0);
}
但现在我想读取深度纹理(DepthComponent)而不是颜色纹理(RGBA)。
我尝试了很多方法,例如禁用 TextureCompareMode、使用带有 shadow2DProj(sampler, vec4(texCoords.xy, 0.0, 1.0)) 或仅 textureProj(sampler, vec3(texCoords.xy, 0.0)) 的 shadow2DSampler。但它只返回 1 或 0,取决于我使用的配置。
为了确保我的深度纹理没问题,我已将像素读回浮点数组,如下所示:
GL.ReadPixels(0, 0, depthTexture.Width, depthTexture.Height, PixelFormat.DepthComponent, PixelType.Float, float_array);
一切似乎都是正确的,它向我显示 1.0 表示空白空间和 0.99 到 1.0 之间的可见对象值。
编辑 这是我的流程的代码示例:
初始化代码
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附件)
渲染通道 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);
渲染通道 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);
【问题讨论】:
-
从深度纹理读取与从颜色纹理读取相比没有什么特别之处。请提供一个最小的无效示例,因为无法判断您的纹理是如何绑定的等等。
-
@BDL 添加了我的流程的代码示例。不包括几何着色器,因为它只是一个基本的颜色着色器,并且使用 ReadPixels 可以正确读取深度值。
-
不相关,但如果你在清屏后设置清色,它不会有任何效果。
标签: opengl glsl textures depth