OPTIMIZE YOUR SHADERS!

Shaders are basically mathematical operations, and everyone knows that conditional statements are not shader friendly, and yeah, we can overcome then by basically turning then into math!

 

See this use case:

if (x == 10) {

 value += 1;

}

instead of this condition when can do:

value += 1 * when_eq(x,10);

 

In the above example the when_eq will return only 0 or 1, 1 only when x is 10 that means that value will increased by 0 when x not equal 10. Quite simple dont you think?

 

Shader code
// Those snippets are in vec4 type but you can change to another types like:
// vec3, vec2, float, int ..........

vec4 when_eq(vec4 x, vec4 y) {
  return 1.0 - abs(sign(x - y));
}

vec4 when_neq(vec4 x, vec4 y) {
  return abs(sign(x - y));
}

vec4 when_gt(vec4 x, vec4 y) {
  return max(sign(x - y), 0.0);
}

vec4 when_lt(vec4 x, vec4 y) {
  return max(sign(y - x), 0.0);
}

vec4 when_ge(vec4 x, vec4 y) {
  return 1.0 - when_lt(x, y);
}

vec4 when_le(vec4 x, vec4 y) {
  return 1.0 - when_gt(x, y);
}

//Here are some logical operators to use with the results from above:

vec4 and(vec4 a, vec4 b) {
  return a * b;
}

vec4 or(vec4 a, vec4 b) {
  return min(a + b, 1.0);
}

vec4 xor(vec4 a, vec4 b) {
  return (a + b) % 2.0;
}

vec4 not(vec4 a) {
  return 1.0 - a;
}
Tags
canvas, condition, conditionals, logical, math, operator, optimize, particles, shader, Spatial
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from nonunknown

Color Range Swap [UPDATED]

Related shaders

more shaders converted (enviroment)

Combine two Shaders

Subscribe
Notify of
guest

5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
dreamcaster
dreamcaster
2 years ago

Thanks for sharing, if you have any further tips and knowledge would you consider creating a cheat sheet git page?
-Nevermind I found the link 🙂

Last edited 2 years ago by dreamcaster
DethRaid
DethRaid
2 years ago

“everyone knows that conditional statements are not shader friendly” – not always. On desktop, if all the threads in a warp take the same branch, the branch doesn’t hurt you. On mobile (and desktop), if all threads in one dispatch or draw take the same branch, the branch doesn’t hurt you much either. You can use branches to skip parts of the shader and decrease overall execution time. Better to profile your shaders and see if the branches are an actual issue rather than just blindly avoiding them imo

Rytelier
1 year ago

I want to add that abs and sign statements literally use if conditions internally… so it adds MORE if statements into the mix.
Good idea would be just to remove everything from the article and add clarification. It’s very misleading right now.

Wilker
9 months ago

question: in a shader where all i’m gonna be manipulating is wether or not a pixel should be shown enough, which approach is cheaper? invoking discard on the fragment, or setting COLOR.w to zero?

Eadorin
Eadorin
3 months ago
Reply to  Wilker

I believe setting COLOR.w to zero is faster, as discard has to check the entire fragment tree, vs just applying a value.