帧缓冲纹理全空白问题排查:双帧缓冲交替渲染异常
双帧缓冲交替渲染纹理空白问题解决
问题现象
使用两个帧缓冲交替渲染(第一帧输出到FBO0,第二帧输出到FBO1,循环往复),期望通过逐帧平均像素值得到灰色调画面。但实际运行时,第一帧能正常显示随机像素,后续帧因读取的前一帧纹理完全空白,导致画面持续减半变暗。
核心原因
Sampler2D Uniform传值错误:OpenGL中sampler2D类型的uniform需要接收纹理单元索引(比如0对应GL_TEXTURE0),而非纹理对象的ID。原代码直接将纹理ID传给last uniform,导致着色器无法正确定位纹理,读取到的是默认空白纹理(像素值为0)。
解决方案
- 将前一帧的纹理绑定到指定纹理单元
- 将纹理单元的索引传给着色器的
lastuniform
代码修改点
绘制部分代码修正
原错误写法:
renderShader.setInt("last", fbotex[1 - buffer]);
替换为以下代码:
// 激活纹理单元0 glActiveTexture(GL_TEXTURE0); // 绑定前一帧的纹理到该单元 glBindTexture(GL_TEXTURE_2D, fbotex[1 - buffer]); // 告诉着色器使用纹理单元0 renderShader.setInt("last", 0);
其他注意事项
- 原帧缓冲初始化代码的附件绑定、状态检查逻辑是正确的,无需修改
- 第一帧
frame==0时,着色器不会使用oldCol,因此无需额外处理初始纹理空白的情况
完整修正后的绘制代码
glBindFramebuffer(GL_FRAMEBUFFER, fbo[buffer]); glClear(GL_COLOR_BUFFER_BIT); renderShader.use(); renderShader.setInt("width", SCR_WIDTH); renderShader.setInt("height", SCR_HEIGHT); renderShader.setInt("frame", frame); // 绑定前一帧纹理到纹理单元0并设置uniform glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, fbotex[1 - buffer]); renderShader.setInt("last", 0); glBindVertexArray(renderVAO); glDrawArrays(GL_TRIANGLES, 0, 6); glUseProgram(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[buffer]); glBlitFramebuffer(0, 0, SCR_WIDTH * 2, SCR_HEIGHT * 2, 0, 0, SCR_WIDTH * 2, SCR_HEIGHT * 2, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, 0);
内容的提问来源于stack exchange,提问作者Grigori Iakimenko
相关产品推荐
相关产品推荐

