【问题标题】:Combining two texture in fragment shader在片段着色器中组合两个纹理
【发布时间】:2012-02-16 21:12:11
【问题描述】:

我正在为我的游戏实施延迟着色。我已将漫反射纹理渲染到渲染目标,并将照明渲染到渲染目标。我知道这两者都很好,因为我可以毫无问题地将它们直接渲染到屏幕上。我想要做的是在着色器中结合漫反射贴图和光照贴图来创建最终图像。这是我当前的片段着色器,它会导致黑屏。

#version 110

uniform sampler2D diffuseMap;
uniform sampler2D lightingMap;

void main()
{
    vec4 color = texture(diffuseMap, gl_TexCoord[0].st);
    vec4 lighting = texture(lightingMap, gl_TexCoord[0].st);

    vec4 finalColor = color;

    gl_FragColor = finalColor;
}

这不应该与直接绘制漫反射贴图的结果相同吗?

我用这个方法设置了sampler2d

void ShaderProgram::setUniformTexture(const std::string& name, GLint t) {
    GLint var = getUniformLocation(name);
    glUniform1i(var, t);
}

GLint ShaderProgram::getUniformLocation(const std::string& name) {
    if(mUniformValues.find(name) != mUniformValues.end()) {
        return mUniformValues[name];
    }

    GLint var = glGetUniformLocation(mProgram, name.c_str());
    mUniformValues[name] = var;

    return var;
}

编辑:更多信息。这是我使用着色器的代码。我设置了两个纹理,并绘制了一个空白方块供着色器使用。正如我之前所说,我确定我的渲染目标正在工作,因为我可以使用与此处相同的 getTextureId 来很好地绘制它们。

    graphics->useShader(mLightingCombinedShader);
    mLightingCombinedShader->setUniformTexture("diffuseMap", mDiffuse->getTextureId());
    mLightingCombinedShader->setUniformTexture("lightingMap", mLightMap->getTextureId());
    graphics->drawPrimitive(mScreenRect, 0, 0);
        graphics->clearShader();



void GraphicsDevice::useShader(ShaderProgram* p) {
    glUseProgram(p->getId());
}

void GraphicsDevice::clearShader() {
    glUseProgram(0);
}

还有顶点着色器

#version 110 

varying vec2 texCoord;

void main() 
{ 
    texCoord = gl_MultiTexCoord0.xy;
    gl_Position = ftransform();

}

【问题讨论】:

  • 在合并两个纹理之前,确保你可以得到 一个 纹理。

标签: c++ opengl glsl


【解决方案1】:

在 GLSL 版本 110 中,您应该使用:

texture2D(diffuseMap, gl_TexCoord[0].st); // etc.

而不仅仅是纹理函数。

然后要组合纹理,只需将颜色相乘,即

gl_FragColor = color * lighting;

【讨论】:

  • 您没有真正提供足够的信息让我们能够帮助您解决这个问题。虽然当您确实显示纹理时,颜色的乘法应该可以工作
  • 好的。我在我的操作中添加了更多信息,但不确定要提供什么信息。由于着色器似乎很好,问题一定是在将纹理传递给着色器?难道是我无法将 VBO 纹理传递给着色器?
  • @rcapote 嗯...你能测试一下是否有什么东西能吸引人吗?将您的着色器代码简化为 gl_FragColor = vec4(1.0)(即仅绘制白色)。如果您的屏幕上有一个白框,那么我们就已经解决了一半
  • 是的,设置这样的颜色效果很好。我对该主题进行了更多阅读,发现我必须使用 glActiveTexture(GL_TEXTURE0); glBindTexture(...); glUniformValue1i(var, 0); 将纹理分配给纹理单元,然后才能在着色器中使用它。这给了我一个灰色的颜色,但没有太多。
  • @rcapote 它会给你所有的纹理灰色吗?
【解决方案2】:
glUniform1i(var, t);

glUniform 函数会影响当前正在使用的程序。也就是说,最后一个调用glUseProgram 的程序。如果你想为特定的程序设置制服,你必须先使用它。

【讨论】:

  • 是的,我在使用程序后设置了值。
【解决方案3】:

问题最终是我没有为我正在绘制的屏幕矩形启用纹理坐标。

【讨论】:

    猜你喜欢
    • 2013-09-17
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多