当前位置: 首页 > 知识库问答 >
问题:

OpenGL访问GLSL 400中的DepthComponent Texture

尉迟宣
2023-03-14

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

该程序进行两次渲染。在第一步中,我将所有的几何体和颜色渲染到一个帧缓冲区中,在该帧缓冲区上我有一个颜色附件和一个分离附件。分离附件是这样绑定的:

(注意:在我的代码示例中,我将C#与OpenTK一起使用,OpenTK是强类型的。)

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

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

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

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

但现在我想读取深度纹理(DepthComponent),而不是颜色纹理(RGBA)。

我尝试了很多方法,比如禁用Texture CompareMode,使用带有的Shap2DProj(sample, vec4(texCoords.xy,0.0,1.0))的Shap2DSample,或者只是textureProj(sample, 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之间的值表示可见对象。

编辑这是我的流程的代码示例:

初始化代码

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

(上面提到的帧缓冲区附件)

渲染通过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);

共有1个答案

柴增
2023-03-14

几个小时后,我找到了解决方案。问题是MinFilter。就像khronos组在glTexParameter上说的那样:

GL_TEXTURE\u MIN_FILTER的初始值为GL_NEAREST\u MIPMAP\u LINEAR

我将深度纹理的MinFilter更改为GL_NEAREST(其中GL_LINEAR也是合法的),现在GLSL着色器中的深度值是正确的(当然是线性化之后)。

其他信息:MagFilter有一些扩展,比如线性\详细\阿尔法\ SGIS。我试过其中一些,深度值的正确性没有受到影响。

 类似资料:
  • 当调用glDraweElements()时,我得到了一个错误,我不知道为什么:/I是使用OpenGL的新手,我正在尝试了解它的工作原理。 注意:我正在使用此库将OBJ文件转换为OpenGL应该能够使用的数组:https://github.com/korre/java-obj-to-opengl/blob/master/MeshObjectLoader.java

  • 我目前正在遵循ThinMatrix的OpenGL教程,使用VAO和VBOS进行渲染。我几乎完全复制了代码(唯一的区别是我使工厂类成为静态的,而不仅仅是正常的)。我可以看到我的程序版本和他的程序版本之间唯一的技术区别是我使用lwjgl 3而不是lwjgl 2。 以下是我的源代码: 我遇到的问题是,每当我试图运行项目时,它就会崩溃,并显示以下错误消息: 环顾四周,我发现了这个stackoverflow

  • 我很难让mipmaps正常工作。我使用的是OpenGL 1.1,我没有glu,所以我使用以下纹理初始化代码: 变量: 是保存纹理mipmap像素数组列表的数组。mipmap处理正确(我单独测试了它们)是将原始图像缩小为1x1像素纹理的mipmaps数(原始纹理为256x256-因此在代码中此时为8)<代码>宽度和高度是原始纹理(256x256)的尺寸。 结果是它甚至没有使用纹理。一切都呈现出平坦的

  • 我试图在opengl中使用3d纹理来实现体绘制。每个体素都有一个rgba颜色值,当前渲染为面向屏幕的四元体。(用于测试目的)。我似乎无法让采样器在着色器中给我一个颜色值。四边形总是以黑色结尾。当我更改着色器以生成颜色(基于xyz坐标)时,效果很好。我正在用以下代码加载纹理: 颜色数组包含正确的数据,即前四个字节的值0, 0, 255, 255蓝色。在渲染之前,我将纹理绑定到第二个纹理单元,如下所示

  • 问题内容: 可以说我有一个MultiIndex系列: 我想应用一个使用行索引的函数: 我该怎么做?进行此类操作的推荐方法是什么?我希望获得一个新的Series,并将此函数所产生的值应用于每行并具有相同的MultiIndex。 问题答案: 我认为无法访问该索引;它将每行视为一个numpy对象,而不是一个Series,如您所见: 要解决此限制,请将索引提升为列,应用函数,然后使用原始索引重新创建Ser

  • 我有四张桌子, 道具,上市,优惠,联系 道具有很多列表,列表属于道具 公共函数列表(){返回$this- 报价属于挂牌, 然后通过“报价”联系人表提供以下联系人 我的问题是,如何访问买家()? 像$props之类的东西- 在道具模型中,我所做的是