我想完成一个GLSL着色器,可以对我的顶点对象进行纹理和着色。事实上,它适用于3个案例中的2个:
1)如果我只分配了一个纹理(但没有特定的颜色 - 所以颜色是“白色”),我只是得到一个纹理对象 - 作品
2)如果我有一个纹理和一个颜色分配,我得到一个用该颜色调制的纹理对象 - 工作
3)如果我只分配了颜色但没有纹理,我会得到一个黑色物体 - 不起作用
My Shader看起来像这样:
varying lowp vec4 colorVarying;
varying mediump vec2 texcoordVarying;
uniform sampler2D texture;
void main(){
gl_FragColor = texture2D(texture, texcoordVarying) * colorVarying;
}
我想,如果没有分配纹理,texture2D(...,...)会返回零 - 所以这似乎是个问题。如果没有分配纹理(在这种情况下,我只想要gl_FragColor = colorVarying;)
我可以检查GLSL吗?“如果”在GLSL着色器中不是一个真正的选项,如果我没有正确理解 - 有任何想法可以实现这一目标吗?或者是否真的有必要为两种情况制作2个不同的着色器?
答案 0 :(得分:5)
和你一样,我接受了当前移动硬件上要避免'if'的一般建议,但之前关于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)特定纹理单元是否具有与其上载数据的缓冲区。