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

时间:2011-07-13 23:08:07

标签: ios glsl

我想完成一个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个不同的着色器?

1 个答案:

答案 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)特定纹理单元是否具有与其上载数据的缓冲区。