<p>The question asks about branch avoidance, so doing that while retaining comparison is still fair play(*).</p>

<p>Checking if some scalar or vector equals its <code>clamp</code>ed version is a terse, intuitive option:</p>

<p>Combine <code>float(clampN(d, dMin, dMax) == d)</code>, which yields 0.0 if false or 1.0 if true, with whatever way you use this resulting value, for example, <code>mix</code>. </p>

<p><code>d</code> can be scalar or any vector, while <code>dMin</code>/<code>dMax</code> are either scalars, or whatever <code>d</code> is.</p>

<p>If <code>&lt;</code> needs to be distinguished from <code>&lt;=</code>, it gets a bit more tedious as additional comparisons are needed for the min/max values or subtracting the value from an extremum and getting a <code>sign</code>, unless one can safely use some other approach such as introducing an epsilon value.</p>

<p>For either case, performance may differ (or match) other solutions; in part, because...</p>

<p>(*) I'm not aware of anything that'd prevent the shader compiler from introducing its own branching if it feels like so; conversely, nothing prevents the shader compiler from converting branching (if) into single-track code, if it can tackle the data flow to the extent to be certain that the results are the same. IIRC the latter is actually done for at least simple cases.</p>

CC BY-SA 4.0
2019-07-18T11:34:56.477Z
2019-07-18T11:34:56.477Z
Robert Monfera
<p>This could be done that way:</p>

<p>First condition is <code>float val = 1.0-step(shouldY, ActualY);</code></p>

<p>Then, the condition: <code>state &gt;= 20.0 &amp;&amp; state &lt; 40.0</code> can be changed to </p>

<p><code>step(20.0, state) - step(40.0, state)</code>. This equals 0.0 if outside of range and 1.0 if inside.</p>

<p>Let <code>a = step(20.0, state) - step(40.0, state)</code></p>

<p>Then we know that mix function:</p>

<pre><code>genType mix(genType x,
    genType y,
    genType a);
</code></pre>

<p>Is $$x * (1 - a) + y * a  = val * (1 - a) + (1 - val) * a  = val - 2*a*val + a$$</p>

<p>So final code is:</p>

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

CC BY-SA 3.0
2017-12-22T11:17:55.480Z
2017-12-22T12:31:26.967Z
2017-12-22T12:31:26.967Z
mdkdy
<p>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 <code>actualY</code> <code>shouldY</code> and <code>state</code></p>

<pre><code>float val = 0.0;
if (actualY &lt; shouldY) {
    val = 1.0;
}

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

<p>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.</p>

CC BY-SA 3.0
2017-12-22T10:28:15.673Z
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
<glsl>
Getting rid of branching to check if a variable is within a range in GLSL
J.Doe
# Getting rid of branching to check if a variable is within a range in GLSL

(Asked by: username_0 on 2017-12-22)

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.

**Tags:** glsl

> **Comments:**
> **username_1**: 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.  

---

## 2 answers

### Answer by username_3 on 2017-12-22. Score: 10 | Accepted answer

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;

```


---

### Answer by username_2 on 2019-07-18. Score: 0

The question asks about branch avoidance, so doing that while retaining comparison is still fair play(\*).

Checking if some scalar or vector equals its `clamp`ed version is a terse, intuitive option:

Combine `float(clampN(d, dMin, dMax) == d)`, which yields 0.0 if false or 1.0 if true, with whatever way you use this resulting value, for example, `mix`.

`d` can be scalar or any vector, while `dMin`/`dMax` are either scalars, or whatever `d` is.

If `<` needs to be distinguished from `<=`, it gets a bit more tedious as additional comparisons are needed for the min/max values or subtracting the value from an extremum and getting a `sign`, unless one can safely use some other approach such as introducing an epsilon value.

For either case, performance may differ (or match) other solutions; in part, because...

(\*) I'm not aware of anything that'd prevent the shader compiler from introducing its own branching if it feels like so; conversely, nothing prevents the shader compiler from converting branching (if) into single-track code, if it can tackle the data flow to the extent to be certain that the results are the same. IIRC the latter is actually done for at least simple cases.


---

