GLSL 共享深度缓冲区似乎不起作用

Posted

技术标签:

【中文标题】GLSL 共享深度缓冲区似乎不起作用【英文标题】:GLSL shared depth buffer seems to not be working 【发布时间】:2014-03-19 09:43:59 【问题描述】:

在进行平铺前向着色时,我正在尝试为两个 FBOS 使用共享深度纹理。我正在做的是填充深度缓冲区的prez pass,然后我运行一个计算着色器只是为了进行一些计算,然后我运行我的前向着色器,我试图渲染到一个共享该深度缓冲区的FBO,并且有一个颜色缓冲区。问题是屏幕变黑。下面是我初始化两个 FBO 的方法:

void MainWindow::initalizeTiledForwardPrePassBuffer(int width, int height)

glGenFramebuffers(1,&m_prePassBuffer);
glBindFramebuffer(GL_FRAMEBUFFER,m_prePassBuffer);

glGenTextures(1,&m_depthTexture);
glGenTextures(1,&m_finalTexture);

// depth
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);


glBindTexture(GL_TEXTURE_2D, m_otherTexture);
///Used to be GL_RGBA only
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, m_otherTexture, 0);

// final
glBindTexture(GL_TEXTURE_2D, m_finalTexture);
///Used to be GL_RGBA only
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, m_finalTexture, 0);

GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

if (Status != GL_FRAMEBUFFER_COMPLETE) 
    printf("FB error, status: 0x%x\n", Status);


glBindFramebuffer(GL_FRAMEBUFFER, 0);

    void MainWindow::initializeTiledForwardColorBuffer(int width, int height)
    
    glGenFramebuffers(1,&m_forwardColorBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER,m_forwardColorBuffer);

glGenTextures(1,&m_forwardColorTexture);

glBindTexture(GL_TEXTURE_2D,m_forwardColorTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT14, GL_TEXTURE_2D, m_forwardColorTexture, 0);

// depth
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);

GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

if (Status != GL_FRAMEBUFFER_COMPLETE) 
    printf("FB error, status: 0x%x\n", Status);


glBindFramebuffer(GL_FRAMEBUFFER, 0);

这是我的预 Z 通行证:

ShaderMan.useTiledForwardPrePass();

///bind the prepasbuffer for drawing
bindTiledForwardPrePassBuffer();

///enable depth test and clear the buffers and then render the scene
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

//renderSceneToDepth();
renderOtherSceneToDepth();

glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);

还有前传

ShaderMan.useForwardShader();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_forwardColorBuffer);

    //glBindImageTexture(4, m_forwardColorTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY,     GL_RGBA32F);
GLenum DrawBuffers[] =  
    GL_COLOR_ATTACHMENT14
;
glDrawBuffers(ARRAY_SIZE_IN_ELEMENTS(DrawBuffers), DrawBuffers);

glDepthMask(GL_FALSE);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//bindMSAABufferForWriting();
bindForForwardPass();
//renderSceneForward();
renderOtherSceneForward();

glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBindFramebuffer(GL_READ_FRAMEBUFFER,m_forwardColorBuffer);

glReadBuffer(GL_COLOR_ATTACHMENT14);
glBlitFramebuffer(0, 0, window_width, window_height,
                  0, 0, window_width, window_height, GL_COLOR_BUFFER_BIT, GL_LINEAR);

我尝试在片段着色器中写入颜色缓冲区的方式很简单

//Other code.....
layout(location = 0)out vec3 finalColor;
void main()

    //Other code...
    finalColor = vec3(color).xyz;

更新

这是完整的预通道着色器 #版本 430

layout(location = 0)in vec3 position;

uniform mat4 modelViewProjection;

void main()

    gl_Position = modelViewProjection*vec4(position,1.0f);


#version 430


void main()



以及我如何绑定预传递缓冲区

void MainWindow::bindTiledForwardPrePassBuffer()

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER,m_prePassBuffer);

回答

问题显然是我的显卡不支持 14 个渲染目标,所以当我将纹理从 GL_COLOR_ATTACHMENT14 更改为 GL_COLOR_ATTACHMENT1 时,一切都按预期工作

【问题讨论】:

在您的前向传递中,您是否将深度缓冲区绑定为纹理,同时它也附加到 FBO? 我绑定深度纹理的唯一时间是当我需要在我的计算着色器通道期间读取它时,它位于预通道和前通道之间。然后我使用 glActivateTextuer(GL_TEXTURE3) 和 glBindTexture(GL_TEXTURE_2D,m_depthTexture) 但在计算着色器完成后我使用 glBindTexture(GL_TEXTURE_2D,0) 就在前向着色器传递开始之前 顺便说一句,在将深度纹理附加到m_forwardColorBuffer之前,您不需要再次绑定它,但是正如您所说的深度缓冲区看起来填充正确,我不认为这就是问题所在。 【参考方案1】:

首先,你是对的 layout(location = 0)out vec3 finalColor;

0 代表 drawBuffer[] 数组中的索引。抱歉错了……

更新:

我看不到您将附件插槽绑定在哪里以进行预通行证

GLenum DrawBuffers[] =  
    GL_COLOR_ATTACHMENT4 , GL_COLOR_ATTACHMENT5, GL_DEPTH_ATTACHMENT
;
glDrawBuffers(ARRAY_SIZE_IN_ELEMENTS(DrawBuffers), DrawBuffers);

同样在pre pass shader中,你不要根据DrawBuffer Array绑定所有的Attachment 你的片段着色器是空的吗?

layout(location = 0)out vec3 color4;
layout(location = 1)out vec3 color5;
layout(location = 2)out float fragmentdepth;

void main()

    //output something per fragment!!

此外,如果您打算使用深度纹理作为着色器的输入,您应该有, 相应的制服,我错了吗?

【讨论】:

啊,谢谢指正,我已经修好了,但似乎还是不行,所以我也一定是做错了什么。 你能显示 TiledForwardPrePass 着色器和 bindTiledForwardPrePassBuffer 吗? 我在新的更新中添加了代码,我只是将 prepassbuffer 绑定为 drawbuffer 并且 prepass 着色器只将所有内容写入深度 我尝试运行我的 prepass,然后将深度写入计算着色器中的图像,该图像显示深度缓冲区正在工作,所以我认为 prepass 正在做它应该做的事情。我想我解释得有点糟糕,我不打算将纹理用作着色器的输入,而是我想运行附加到一个 FBO 的 prepass 并填充深度缓冲区(只是检查了它的工作)然后在我正常的前向着色器通道中,我只想渲染到另一个附加了相同深度纹理和颜色缓冲区的 FBO。不幸的是,前向传递没有写入纹理 我不确定它是否相关,但将 vec3 输出到 4 分量纹理会将 alpha 设置为 1?尝试在片段着色器中输出 vec4

以上是关于GLSL 共享深度缓冲区似乎不起作用的主要内容,如果未能解决你的问题,请参考以下文章

功能 setsockopt 似乎不起作用

OpenGL GLSL - 投影矩阵不起作用

OpenGL累积缓冲区不起作用

OpenGL - 链接两个纹理不起作用

OpenGL顶点缓冲区对象不起作用

共享内存的访问控制不起作用?