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

Qt的paintGL函数无法激活多纹理单元,G缓冲采样结果全部相同求助

问题原因及修复方案

1. 采样器Uniform设置无效(核心原因)

Qt的QOpenGLShaderProgram::setUniformValue仅对当前已绑定的着色器程序生效,你在initShaders中完成反射通道着色器链接后,没有先绑定程序就设置采样器对应的纹理单元,导致所有sampler2D uniform默认使用值0,所有采样操作都会读取GL_TEXTURE0单元的纹理,自然三个纹理采样结果完全相同。
修复方法:修改initShaders中反射通道的初始化逻辑:

shaderReflectPass.link();
// 新增:先绑定着色器程序再设置uniform
shaderReflectPass.bind();
shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gPosition"), 0);
shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gNormal"), 1);
shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gColor"), 2);

2. paintGL中纹理绑定错误

你当前paintGL里的纹理绑定和你预设的采样器单元不匹配,且未绑定gPosition纹理:

  • GL_TEXTURE0对应gPosition,你错误绑定了gColor
  • GL_TEXTURE2对应gColor,你重复绑定了gColor
    修复方法:修改paintGL中的纹理绑定逻辑:
// 按采样器单元对应绑定纹理
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gPosition);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gNormal);

glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gColor);

3. 几何通道渲染逻辑错误

你目前仅在initializeGL中渲染一次几何数据到FBO,且渲染完成后没有解绑FBO,后续重绘、窗口 resize 时数据会丢失,且会渲染到离屏FBO而非窗口默认帧缓冲。
修复方法:将几何通道渲染逻辑挪到paintGL最前面,每次重绘先更新G缓冲数据,再做后期处理:

void fboTest::paintGL()
{
    // ------------ 几何通道:渲染到G缓冲 ------------
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);

    shaderGeoPass.bind();
    QMatrix4x4 model;
    QMatrix4x4 view;
    QMatrix4x4 projection;
    view.lookAt({0, 0, 3}, {0, 0, 0}, {0, 1, 0});
    projection.perspective(45.0f,static_cast<float>(SCR_WIDTH)/static_cast<float>(SCR_HEIGHT),0.1f,100.0f);

    // 渲染两个立方体
    glBindVertexArray(cubeVAO);
    model.translate(QVector3D(-1.0f, 0.0f, -1.0f));
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model);
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("view"), view);
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("projection"), projection);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    model.setToIdentity();
    model.translate(QVector3D(2.0f, 0.0f, 0.0f));
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model);
    glDrawArrays(GL_TRIANGLES, 0, 36);

    // 渲染地面
    glBindVertexArray(planeVAO);
    model.setToIdentity();
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    // ------------ 后期通道:渲染到窗口默认帧缓冲 ------------
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
    glDisable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // 绑定G缓冲纹理
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gPosition);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, gNormal);
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, gColor);

    shaderReflectPass.bind();
    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

同时删除initializeGL中原来的几何渲染相关代码,仅保留初始化逻辑即可。


内容的提问来源于stack exchange,提问作者laser_zd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 03:00:01