You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

帧缓冲纹理全空白问题排查:双帧缓冲交替渲染异常

双帧缓冲交替渲染纹理空白问题解决

问题现象

使用两个帧缓冲交替渲染(第一帧输出到FBO0,第二帧输出到FBO1,循环往复),期望通过逐帧平均像素值得到灰色调画面。但实际运行时,第一帧能正常显示随机像素,后续帧因读取的前一帧纹理完全空白,导致画面持续减半变暗。

核心原因

Sampler2D Uniform传值错误:OpenGL中sampler2D类型的uniform需要接收纹理单元索引(比如0对应GL_TEXTURE0),而非纹理对象的ID。原代码直接将纹理ID传给last uniform,导致着色器无法正确定位纹理,读取到的是默认空白纹理(像素值为0)。

解决方案

  1. 将前一帧的纹理绑定到指定纹理单元
  2. 将纹理单元的索引传给着色器的last uniform

代码修改点

绘制部分代码修正

原错误写法:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:35:39