GLSL 400中的OpenGL访问深度组件纹理
我正在尝试访问版本400的GLSL着色器中的DepthComponent纹理 该程序进行两次渲染。在第一个过程中我将所有几何体和颜色渲染到一个帧缓冲区,在该帧缓冲区上我有一个colortachment和DepthAttachment。DepthAttachment的绑定方式如下:GLSL 400中的OpenGL访问深度组件纹理,opengl,glsl,textures,depth,Opengl,Glsl,Textures,Depth,我正在尝试访问版本400的GLSL着色器中的DepthComponent纹理 该程序进行两次渲染。在第一个过程中我将所有几何体和颜色渲染到一个帧缓冲区,在该帧缓冲区上我有一个colortachment和DepthAttachment。DepthAttachment的绑定方式如下: GL.ReadPixels(0, 0, depthTexture.Width, depthTexture.Height, PixelFormat.DepthComponent, PixelType.Float, flo
GL.ReadPixels(0, 0, depthTexture.Width, depthTexture.Height, PixelFormat.DepthComponent, PixelType.Float, float_array);
(注意:在我的代码示例中,我将C#与OpenTK一起使用,OpenTK是强类型的。)
深度纹理的内部像素格式为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,将shadow2DSampler与shadow2DProj(sampler,vec4(texCoords.xy,0.0,1.0))
一起使用,或者只使用textureProj(sampler,vec3(texCoords.xy,0.0))
。但它只返回1或0,这取决于我使用的配置
为了确保我的深度纹理正常,我将像素读回浮点数组,如下所示:
GL.ReadPixels(0, 0, depthTexture.Width, depthTexture.Height, PixelFormat.DepthComponent, PixelType.Float, float_array);
一切似乎都是正确的,它向我显示空空间为1.0,可见对象为0.99到1.0之间的值
编辑
下面是我的流程的代码示例:
初始化代码
(上面提到的帧缓冲区附件)
渲染过程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);
几个小时后,我找到了解决办法。 问题出在过滤器上。正如khronos集团在其网站上所说:
GL\u TEXTURE\u MIN\u FILTER
的初始值为GL\u NEAREST\u MIPMAP\u LINEAR
我将深度纹理的MinFilter更改为GL_NEAREST
(其中GL_LINEAR
也是合法的),现在GLSL着色器中的深度值是正确的(当然是线性化之后)
其他信息:
MagFilter有一些扩展,如
LINEAR\u DETAIL\u ALPHA\u SGIS
。我试过其中一些,深度值的正确性没有受到影响。与从颜色纹理读取相比,从深度纹理读取没有什么特别之处。请提供一个最小的不起作用的示例,因为无法告诉您的纹理是如何绑定的等@BDL添加了我的过程的代码示例。不包括几何体着色器,因为它只是一个基本颜色着色器,使用ReadPixels可以正确读取深度值。不相关,但如果在清除屏幕后设置清晰颜色,则不会产生任何效果。如果有问题,请评论我的答案。如果一切顺利,我会把它作为答案。
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);