Shader Dynamic branch not working?

I have set up this dynamic branching test


When toggled to Off, a frame takes 124 ms.
When toggled to On, a frame still takes 124 ms.
How come there is no performance improvement when the dynamic branch is set to off?

Update: If I change the order of the inputs, so that the more expensive input is declared last

the frame time now drops from 124ms to 70ms when the branch is toggled to off.
Thats almost 50% savings, I was hoping for more like 95% savings though, can anyone explain this behavior?

As far as I know, dynamic branching requires you to put all your logic for all branches inside the HLSL custom node.

So… I’m surprised you even got 50% savings. I would expect zero.

1 Like

Just my raised hand, but I too would like to understand this better.

I know a few years ago dynamic-branching was a very popular topic but I am still unaware of the in’s and out’s. ref: Dynamic flow control in materials (Ty @DeathreyCG for this and your ocean-thingie)

I don’t even know how to get it set up, if it requires a custom-node, or if there are best-practices…

Anyone that wants to chime in on this is welcome (please?). :smiley:

edit: Only guy I found on youtube, 6ys old… ref: https://www.youtube.com/@MPRX87

He seems to be doing what you are doing OP, just-embedding an IF statement in the custom-node…

Thanks, I read through Dynamic flow control in materials. The take away from that thread seems to be pretty much what Arkiras said… Which kinda sucks. Custom nodes are horrible to work with unless your using them for short snippets of code.

One possible way of working around this, would be to make an HLSL code generator. The input would be material functions, and the output would be a hlsl custom node. However this wouldnt be easy to do, and you may end up with somewhat inefficient code.

This is my understanding as well. As far as HLSL code generators go… You can already access the shader code in HLSL from the material window. It’s a little tedious since it contains a ton of other crap, but you could take your string of nodes, plug it into the emissive or something, then access the generated HLSL. Find the emissive section in the generated code and simply copy the code from there. It would still require some work to set up the inputs and outputs. Not sure if it’d save that much time over just writing the HLSL.

Isn’t there already a dynamic branching mode in unreals material editor built in? I’m using it right now… not sure if it saves on performance or not.

If you’re referring to the “if” node then that doesn’t do dynamic branching, it’s just a ternary.

If you’re talking about the “dynamic branch” node, it’s literally just the “if” node inside of another material function.

No im saying it has a
image

Double click it and look at what is inside

Spoiler

2 Likes

so why does it say its best used for 20 instructions or a texture sample? If it does nothing.

Beats me, that’s a question for Epic.

It is genuinely just a ternary operator though, you can just look at the generated HLSL code if you don’t believe me.

1 Like

i just tested using the custom node logic. Dynamic branching definently works there for sure.

EDIT … i just also tested the dynamic branching node we talked about… it works as well…

i made a test and checked the gpu ms… made one with like 8 textures and over 400 instructions and it goes from like 7.1 ms gpu to like 6.4…

and thats me running an rtx 3090… well 2… so im sure it would work even better for lower end.

How are you testing it?

just a poly plane in a scene with a random stupid material with loads of texture samplers and math. Did stat unit to check the gpu ms… id go back and forth on a material instance.

Post the material you’re testing

as i said id just alternate to a solid scalar of 1 vs that entire node chain… using a material instance to go back and forth with a parameter.

i tried both the dynamic branch node and the custom node… both with same results of performance saving.

Wouldn’t expect either of these to save anything at all. I can only assume it has something to do with your use of a static parameter for the alpha, it could just be compiling two versions of the shader.

This is my test:

Zero performance improvement:

image