Shader Conditionals to provide pseudo control flow in materials in UE4

I came across this article about how to avoid branching in graphics shaders. The basic idea is that if there is any comparison or branching done in a shader then depending on how the GPU chooses to deal with the code, then its possible that it could actually do both of the branches anyway before actually outputting the result.

DISCLAIMER: What I am doing here will in no way guarantee better performance. I have not actually benchmarked this and it could even result in worse performance. What I show though is a way that you can do these kinds of operations in UE4 using nodes to get the behaviour you want. You can use this to prototype ideas if you are not comfortable with editing HLSL code.

SC_landscapeTop

 

This technique involve some simple math to be able to compare to values and output a value of 0 or 1.

So instead of….


if (float A < float B){
x += 50;
}

 

…we can use a special function to compare float A and B to get a 0 or 1 output and then use that to drive a lerp or multiple or some other part of the shader.

x += 50 * A_less_than_B(A, B);

It turns branching into a multiply. This could result in more work being done, but the GPU is great at doing multiplies.

 

SHADERCONDITIONALS

So I’ve created some material functions that allow us to do…

== (equal_to)

!= (not_equal_to)

< (less_than)

> (greater_than)

<= (less_than_or_equal_to)

= (greater_than_or_equal_to)

…in the material editor with nodes.

The cool thing is that we can then combine the output of these functions into logical operations. Because they are 0 or 1 (and not inbetween) We can do & (AND), | (OR) and ! (NOT) operations.

SC_Landscape

Here is a little practical example. It is a landscape and we take its WorldPosition as input, mask it’s Z component (height) and compare that to a user threshold with the ‘greater_than’ operation. The 0 to 1 output is driving a lerp to choose between two colours. We could use an XY projected texture to feed into the threshold which would break up the straight edge for us.

Shader Conditional Editor

 

Now we can add an extra test for the top of the landscape and lerp it in with the previous result.

SC_editor2

This gives us the result we saw further up the page…..

SC_landscapeTop

Obviously these are constant colours which would be replaced by textures. This is very similar to what you would do with the landscape layer blend. This is a lot more manual but I much prefer using these nodes to the dreaded ‘if’ node in the UE4 Material Editor.

This is only one use for it. If you think of any then please let me know!

Leave a Comment