Shaders - Avoiding Branches. Can 'true / false' be instanced as '1 / 0'?
I'm writing a frag shader for tilemap-based terrain to combine different textures in a specific way, depending on what type of terrain is around the current tile.
To this end, I have code like (neighbourTypes[2] == thisType ? 2 : 0)
and if's and branches in many more locations in the original cpu-based code.
I know branches like this are bad for performance on GPU, and want to avoid them. Does anyone know how best to avoid brances in code like this? One thing I thought of was maybe performing (neighbourTypes[2] == thisType) * 2
which only works if the true or false resulting from neighbourTypes[2] == thisType
can be instanced to 1 or 0, but I have no idea if that works.
Can anyone share some tips how to avoid brances in situations like this?
Answer by fguinier · Jan 24, 2017 at 08:28 AM
Super good articles about shader optimisation : http://www.humus.name/Articles/Persson_LowlevelShaderOptimization.pdf http://www.humus.name/Articles/Persson_LowLevelThinking.pdf Enjoy :)
Oh those articles are very insightful indeed. (Although there are many abbreviations in there that are completely new to me.) A lot to digest, but good stuff, thanks!
Page 34 of the first one is a slide about branching, and using the '?' conditional specifically:
$$anonymous$$ost of the time branches are fine. For very tiny branches, a conditional assignment may be preferable. The easiest way to do that is to simply use the ?-operator. Semantically it is a branch though, rather than a conditional assignment, although simple expressions written that way tends to compile down to a conditional assignment.
So from this I gather that using the '?' (in my example) is already optimal or near-enough?
most likely yes :) Best is to check the assembly to be sure :)