Reputation: 1606
I would like to know how to blend colors in a specific way.
Let's imagine that I have a color (A) and an other color (B).
I would like to blend them in such a way that if I choose white for the (B) then the output color is (A) but if have any other color for (B) it outputs a blending of (A) and (B).
Any idea how to do that ?
Upvotes: 1
Views: 3770
Reputation: 11
To avoid branching in a shader
, one technique is to use lerp (linear interpolation
). That is, use the would-be conditional variable as the lerp factor, so if it's 0
it's one
color and if it's 1
it's the other
color.
Be sure to reverse the logic since the second argument is what it blends to if cond=1
. This also allows you to blend half way.
Example:
Instead of
Color result = (cond)? A:B;
use:
Color result=lerp(cond,B,A);
Upvotes: 1
Reputation: 54652
With GLSL, the simplest approach is probably to use a branch. If colA
and colB
are the two vectors (of type vec4
) holding your colors A and B:
if (any(lessThan(colB.xyz, vec3(1.0)))) {
outColor = colB;
} else {
outColor = colA;
}
Or, if you really want to avoid a branch, you could rely more on built-in functions. For example, using the observation that if all components are in the range [0.0, 1.0], the dot product of the vector with itself is 3.0 for the vector (1.0, 1.0, 1.0), and smaller for all other vectors:
outColor = mix(colB, colA, step(3.0, dot(colB.xyz, colB.xyz)))
You will have to benchmark to find out which of these is faster.
There may be some concern about floating point precision in the comparisons for both variations above. I believe it should be fine, since 1.0 can be represented as a float exactly. But if you do run into problems, you may want to allow for some imprecision by changing the constants that colB
is compared against to slightly smaller values.
Upvotes: 2