2011-07-13 194 views
4

我想完成GLSL着色器,它可以纹理和着色我的顶点对象。事实上,它为我工作在2 3情况:用于纹理,颜色和纹理/颜色的片段着色器GLSL

1)如果我只分配一个纹理(但没有具体的颜色 - 这样的颜色为“白色”),我只是得到一个纹理对象 - 工程

2)如果我有一个质地和分配一个颜色,我得到那个颜色调制的纹理对象 - 工程

3)如果我只分配了颜色,但没有质感,我得到一个黑色的物体 - 没有按不工作

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

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 Shader中不是真正的选项, - 任何想法来完成这个?或者是否真的有必要为这两种情况制作两种不同的着色器?

回答

5

喜欢你,我会拿起那个“如果”是要避免在目前的移动硬件中的建议,但在计算器上先前优化的讨论似乎表明,这不是一个显著的障碍。所以不要把它写下来。在任何情况下,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。

我不知道的任何方式来确定(我)是否sampler2D指向一个实际的纹理单元;和(ii)一个特定的纹理单元是否有一个为其上载数据的缓冲区。

+1

我想你的意思'textureFlag'和'textureMask'有相同的变量名 –

+0

你完全正确。无论如何我还是在编辑中使用'mix'的替代方法。我很确定我有这些争论的正确方法。 – Tommy