# Better solution for boolean mixing?

Sorry if this question has been asked in the past, but searching Google and here didn't yield relevant results, so here goes.

I'm working on a fragment shader that implements both conditional/boolean diffuse and bump mapping (that is to say, you don't need a diffuse texture or a normals texture, and if they're not present, they're simply changed to default values).

My current solution is to use a uniform float to say "mix amount". For example, computing the diffuse texel works as:

// Compute diffuse amount scaled by vCol
// If no texture is present (mDif = 0.0), then DiffuseTexel = vCol
// kT[0] is the diffuse texture
// vTex is the texture co-ordinates
// mDif is the uniform float containing the mix amount (either 0.0 or 1.0)
vec4 DiffuseTexel = vCol*mix(vec4(1.0), texture2D(kT[0], vTex), mDif);


While that works great and all, I was wondering if there's a better way of doing this, as I will never have any use for in-between values for funky effects. I know that perhaps the best solution is to simply write separate shaders for mDif=0.0 and mDif=1.0, but I'd like a more elegant solution than splicing shaders before compiling or writing multiple shader files and keeping each one updated.

Any ideas are greatly appreciated. =)

• I don't see anything wrong with this, it's probably way better than any branching, but I'm no shader expert so I'll let the professionals talk. Jun 27 '13 at 22:45
• @LaurentCouvidou: Branches will be compiled into conditional operations so should be as fast or faster than multiplying by 1 or 0... on some hardware with some drivers at some optimization levels. :) Jun 27 '13 at 23:50
• @LaurentCouvidou What's wrong with this (generally) is that mix() will fail in case specials come into play (Inf, NaN). Also, it might produce unexpected results when the range of values is high and the data type is narrow (e.g. half). It would be much nicer to have select(x, y, cond) but generally it is ok to use the ternary operator. The compiler wont be able to optimize it though (as the C standard guarantees that only one of the branches gets evaluated--the other could be out of bounds access, division by zero, have side effects or just be expensive). May 23 '17 at 18:48
• This gets a bit confusing on a GPU as both branches are always executed. But the threads in a warp are masked according to their condition values so that the possible exceptions (e.g. OOB) that would otherwise be raised are avoided. Still, the threads need to "step through" the masked code and time is spent. May 23 '17 at 18:52