# Getting rid of branching to check if a variable is within a range in GLSL

I have this GLSL function that I am trying to optimize because it is going to be ran on many pixels of an older devices GPU. There is no room for branching inefficiency. Essentially this function returns a 0 or a 1 based on the variables actualY shouldY and state

float val = 0.0;
if (actualY < shouldY) {
val = 1.0;
}

if (state >= 20.0 && state < 40.0) { //The equal/not equals is VERY important
return 1.0 - val;
}
return val;


Usually I am fairly good at removing branching from GLSL code but I really don't know what to do with the range check for the state variable.

• Are you sure that the code you've written results in branches? Most simple if statements are compiled to parallel evaluation with a multiply-add to select the desired output. You should check with the profiling tool that goes with your target GPU. – Dan Hulme Dec 22 '17 at 10:28

This could be done that way:

First condition is float val = 1.0-step(shouldY, ActualY);

Then, the condition: state >= 20.0 && state < 40.0 can be changed to

step(20.0, state) - step(40.0, state). This equals 0.0 if outside of range and 1.0 if inside.

Let a = step(20.0, state) - step(40.0, state)

Then we know that mix function:

genType mix(genType x,
genType y,
genType a);


Is $$x * (1 - a) + y * a = val * (1 - a) + (1 - val) * a = val - 2*a*val + a$$

So final code is:

float val = 1.0-step(shouldY, ActualY);
float a = step(20.0, state) - step(40.0, state);
return val - 2.0*a*val + a;