繁体   English   中英

用于纹理、颜色和纹理/颜色的片段着色器 GLSL

[英]Fragment Shader GLSL for texture, color and texture/color

我想完成一个 GLSL 着色器,它可以对我的顶点对象进行纹理化和着色。 事实上,它在 3 个案例中的 2 个对我有用:

1)如果我只分配了一个纹理(但没有特定颜色 - 所以颜色是“白色”),我只是得到一个带纹理的 object - 有效

2)如果我分配了纹理和颜色,我会得到一个用该颜色调制的纹理 Object - 有效

3) 如果我只指定了颜色但没有纹理,我会得到黑色 object - 不起作用

我的着色器看起来像这样:

varying lowp vec4 colorVarying;
varying mediump vec2 texcoordVarying;
uniform sampler2D texture;

void main(){
    gl_FragColor = texture2D(texture, texcoordVarying) * colorVarying;
}

我猜想,如果没有分配纹理,则 texture2D(...,...) 返回零 - 所以这似乎是问题所在。 有没有办法在 GLSL 中检查,如果没有分配纹理(在这种情况下,我只想 gl_FragColor = colorVarying;)

如果我理解正确的话,“如果”在 GLSL 着色器中并不是一个真正的选项 - 有什么想法可以做到这一点吗? 还是真的有必要为这两种情况制作 2 个不同的着色器?

和你一样,我接受了一般建议,即在当前的移动硬件上要避免使用“如果”,但之前关于 StackOverflow 的优化讨论似乎表明这不是一个重大障碍。 所以不要把它写下来。 在任何情况下,GLSL 编译器都相当聪明,并且可能会根据为制服设置的值选择切换它实际运行的代码,尽管在这种情况下,您得到的一切都与您刚刚提供替代着色器一样。

也就是说,如果您绝对确定要为所有目的使用相同的着色器并希望避免使用 if 语句,那么您可能想要类似的东西:

uniform lowp float textureFlag;

[...]

gl_FragColor = textureFlag * texture2D(texture, texcoordVarying) * colorVarying + 
               (1.0 - textureFlag) * colorVarying;

甚至:

gl_FragColor = mix(
                     colorVarying,
                     texture2D(texture, texcoordVarying) * colorVarying,
                     textureFlag
                  )

将 textureFlag 设置为 1.0 或 0.0,具体取决于您是否希望将纹理值考虑在内。

我不知道有什么方法可以确定(i)sampler2D 是否指向实际的纹理单元; (ii) 一个特定的纹理单元是否有一个绑定到它的缓冲区,数据已被上传。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM