片段着色器GLSL纹理,颜色和纹理/颜色

Con*_*tin 4 glsl ios

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

1)如果我只分配了一个纹理(但没有特定的颜色 - 所以颜色是"白色"),我只是得到一个纹理对象 - 工作

2)如果我有一个纹理和一个颜色分配,我得到一个用该颜色调制的纹理对象 - 工作

3)如果我只分配了颜色但没有纹理,我会得到一个黑色物体 - 不起作用

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

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

void main(){
    gl_FragColor = texture2D(texture, texcoordVarying) * colorVarying;
}
Run Code Online (Sandbox Code Playgroud)

我想,如果没有分配纹理,texture2D(...,...)将返回零 - 所以这似乎是问题所在.如果没有分配纹理(在这种情况下,我只想要gl_FragColor = colorVarying;),我可以检查GLSL吗?

"如果"在GLSL着色器中不是一个真正的选项,如果我没有正确理解 - 有任何想法可以实现这一目标吗?或者是否真的有必要为两种情况制作2种不同的着色器?

Tom*_*mmy 5

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

也就是说,如果你绝对肯定你想为所有目的使用相同的着色器并且想要避免if语句那么你可能想要这样的东西:

uniform lowp float textureFlag;

[...]

gl_FragColor = textureFlag * texture2D(texture, texcoordVarying) * colorVarying + 
               (1.0 - textureFlag) * colorVarying;
Run Code Online (Sandbox Code Playgroud)

甚至:

gl_FragColor = mix(
                     colorVarying,
                     texture2D(texture, texcoordVarying) * colorVarying,
                     textureFlag
                  )
Run Code Online (Sandbox Code Playgroud)

将textureFlag设置为1.0或0.0,具体取决于是否要将纹理值考虑在内.

我不知道有任何方法可以确定(i)sampler2D是否指向实际的纹理单元; (ii)特定纹理单元是否具有与其上载数据的缓冲区.