How to set shader render_mode in the Inspector?

Godot Version

4.6

Question

I’m writing a shader and the render_mode plays a part.

I’d like to have the ability to set the mode using a uniform in the Inspector to select between:
blend_mix, blend_add, blend_mul, or blend_sub

I’m also setting the ALBEDO, ALPHA, and EMISSION in the shader.

I know I can’t use a uniform keyword and then set the render_mode in code - but is there another way?

For example, I found this code snippet:

uniform int blend_mode : hint_range(0, 1) = 0; // 0 for Mix, 1 for Additive
uniform vec3 albedo : source_color;

void fragment() {
    vec4 final_color = vec4(albedo, 1.0);
    
    // Simulate Render Modes (e.g., Mix vs Add)
    if (blend_mode == 1) {
        // Additive
        ALBEDO = final_color.rgb * final_color.a;
    } else {
        // Normal Mix
        ALBEDO = final_color.rgb;
    }
}

This code only sets the ALBEDO - is that the only thing affected by “blend” modes - or do I need to be concerned about the EMISSION and ALPHA too?

Also, this only addresses blend_mix and blend_add and I also would like blend_mul and blend_sub…

Have multiple shaders (or materials) with different render modes and swap from script as needed.

Thanks but I’m trying to set it up so that when I’m working with the shader at design time I can rapidly switch between render modes using the inspector instead of swapping the modes in the shader code editor.

You can swap shaders via a tool script.

If I did that, my edits would be per script rather than in a single script.

I’m trying to make one shader script with render_mode options.

Maybe I should re-phrase this post and ask for help recreating the Blend render modes in code.

You can’t. Render mode changes requires shader source code change and recompilation.

Use the alternative I suggested.

If you don’t write your own script, you can use a visual shader instead. It will let change the render mode from the inspector, but under the hood it will do precisely what I described - change the source code and recompile.

Yes, I know - I wrote that in my OP.

That’s why I asked about writing code to reproduce the render mode Blend capabilities.

Shader functions are not responsible for blending. It happens after the shader is done doing its calculations. You can’t “emulate” it by shader code.

Just make multiple shader versions and swap them with a tool script. To avoid code duplication - use shader includes.

(I’m not trying to be belligerent, just tying to learn and understand the contradictions I see while searching - thanks for being patient)

You’re saying code like this won’t replicate the mix and add render modes?

shader_type spatial;

uniform int blend_mode : hint_range(0, 1) = 0; // 0 for Mix, 1 for Additive
uniform vec3 albedo : source_color;

void fragment() {
    vec4 final_color = vec4(albedo, 1.0);
    
    // Simulate Render Modes (e.g., Mix vs Add)
    if (blend_mode == 1) {
        // Additive
        ALBEDO = final_color.rgb * final_color.a;
    } else {
        // Normal Mix
        ALBEDO = final_color.rgb;
    }
}

The purpose of blending modes is to specify how is shader output blended with what’s already in the framebuffer. Shader doesn’t “know” what’s in the framebuffer and hence its code cannot perform that blending operation.

This snippet certainly won’t replicate additive blending. It will use mix in both cases as that’s the default mode.