【发布时间】: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之前,您不需要再次绑定它,但是正如您所说的深度缓冲区看起来填充正确,我不认为这就是问题所在。
标签: opengl buffer glsl depth fbo