material-maker icon indicating copy to clipboard operation
material-maker copied to clipboard

Mask node

Open novalis opened this issue 3 years ago • 2 comments

Feature/enhancement description:

I have a grayscale node which only ever takes values 0 or 1. This is used to select between two different complicated textures. Naively, I can use a Blend node for this. But this renders both complicated textures for each pixel, even though only one is needed. Instead, what I want is:

vec4 result;
if (black_and_white_input == 1.0) {
  //all of the computation needed for complicated texture 1 
  result = result_of_texture1_computation;
} else {
   //all of the computation needed for complicated texture 2 
  result = result_of_texture2_computation;
}

When I manually do this in my godot shader (that is, replace the blend node with an if which only computes one of the textures for each pixel), I roughly double my fps.

Of course, in theory, just offering a blend mode which does the if would allow a sufficiently smart compiler to optimize this. That's what I tried first, but Godot's compiler (and/or Android's on my Pixel 5) is not sufficiently smart.

novalis avatar Oct 04 '22 19:10 novalis

Branching statements such as if/else in shaders do not (usually) get optimized away because GPU calculations are meant to be parallelized, of course putting the whole calculation behind what is essentially a (static) if statement would work decently enough but again it's not ideal for GPUs. I didn't yet look into how the nodes work in this tool (or shaders in Godot for that matter), but as long as a node's dependencies are actually only used when needed, this could work.

Unreal Engine's Static Switch does something similar, but it compiles a new shader based on the switch's value: https://docs.unrealengine.com/5.1/en-US/material-parameter-expressions-in-unreal-engine/#staticswitchparameter

As an off note: I would suggest a different name than "Mask" for this type of node, as masking is traditionally associated with blending based on a mask or masking individual color channels.

ZeroComfort avatar Nov 23 '22 09:11 ZeroComfort

A simple way of gathering all code for an input is to set it to "function" (button on the right side of the input in the node editor). I'll try this in new nodes I want to add for 1.2.

RodZill4 avatar Nov 24 '22 05:11 RodZill4