Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GLSL 400中的OpenGL访问深度组件纹理_Opengl_Glsl_Textures_Depth - Fatal编程技术网

GLSL 400中的OpenGL访问深度组件纹理

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

我正在尝试访问版本400的GLSL着色器中的DepthComponent纹理

该程序进行两次渲染。在第一个过程中我将所有几何体和颜色渲染到一个帧缓冲区,在该帧缓冲区上我有一个colortachment和DepthAttachment。DepthAttachment的绑定方式如下:

GL.ReadPixels(0, 0, depthTexture.Width, depthTexture.Height, PixelFormat.DepthComponent, PixelType.Float, float_array);
(注意:在我的代码示例中,我将C#与OpenTK一起使用,OpenTK是强类型的。)

深度纹理的内部像素格式为DepthComponent32f,像素格式为DepthComponentFloat,作为像素类型。所有其他属性都具有默认值

第二遍使用以下着色器将帧缓冲区彩色图像渲染到屏幕上:

#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);