Replacement shader for the Camera (just like Unity's Camera.SetReplacementShader())?

Godot Version

4.2.2.stable

Hey! I’d like to make an effect in my game where, for some frames, one exact model is colored while everything else is black.

If I was using Unity, I’d use that Camera’s SetReplacementShader, which will draw every model with a certain tag with a different shader, and then use Shader Instance Parameter on the specific Mesh I’d want to color it while everything else defaults to black.

Is there any way to do something like that?

I don’t think there’s a direct way to do that but you could maybe do the following: Add the different MeshInstance3D to a group and use SceneTree.get_nodes_in_group() or SceneTree.set_group() to override their material with GeometryInstance3D.material_override or apply an overlay material with GeometryInstance3D.material_overlay (the later may be closer to what unity does)

You could use the signal SceneTree.node_added to add the different mesh instances to the group automatically. For example:

extends Node


func _ready() -> void:
    get_tree().node_added.connect(func(node:Node):
        if node is MeshInstance3D:
            node.add_to_group("replacement_shader")
    
    )
    
    
func apply_replacement() -> void:
    get_tree().set_group("replacement_shader", "material_overlay", preload("res://overlay_material.tres"))
    
    
func remove_replacement() -> void:
    get_tree().set_group("replacement_shader", "material_overlay", null)

I’ve not tested it but I think that if you add that as an autoload it should have a similar result as that unity’s function.