4
votes

I want to accomplish a GLSL Shader, that can texture and color my vertex objects. In fact, it works for me in 2 from 3 cases:

1) If I only have an texture assigned (but no specific color - so the color is "white"), I simply get an textured object - works

2) If I have an texture and an color assigned, I get an textured Object modulated with that color - works

3) If I only have an color assigned but no texture, I get an black object - doesn't work

My Shader looks like this:

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

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

I guess that, texture2D(...,...) returns zero if no texture is assigned - so that seems to be the problem. Is there a way in GLSL I can check, if no texture is assigned (in this case, I want simply gl_FragColor = colorVarying;)

"If" isn't really an option in an GLSL Shader, if I understanded correctly - any ideas to accomplish this? Or is it really necessary to make 2 different shaders for both cases?

1

1 Answers

5
votes

Like you I'd picked up the general advice that 'if' is to be avoided on current mobile hardware, but a previous optimisation discussion on StackOverflow seemed to suggest it wasn't a significant hurdle. So don't write it off. In any case, the GLSL compiler is reasonably smart and may chose to switch which code it actually runs depending on the values set for uniforms, though in that case all you're getting is the same as if you'd just supplied alternative shaders.

That said, if you're absolutely certain you want to use the same shader for all purposes and want to avoid if statements then you probably want something like:

uniform lowp float textureFlag;

[...]

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

Or even:

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

With you setting textureFlag to 1.0 or 0.0 depending on whether you want the texture values to be factored in.

I'm not aware of any way to determine (i) whether a sampler2D is pointed to an actual texture unit; and (ii) whether a particular texture unit has a buffer bound to it for which data has been uploaded.