Godot Version
4.51 stable
Question
I created a simple shader to change color. If I add a texture rectangle to the scene and set the material in the inspector everything works fine. But I've spent the last four hours trying to get it to work at runtime. I switched from the original project to just isolate the problem but am unable to find it.
O created a scene it has a Panel at the top level. The panel has two child texture rectangles each with the shader applied one to turn red blue, and one to turn red green.
In the scene’s ready method I try and add a new texture rectangle and add the ShaderMaterial that is used by the other texture rectangles that were configured in the editor. I’m able to set the parameter values for the shader, the values being the same as the first texture rectangle that was added to the panel, but it has no effect. For reference see the attached image, the blue desk and green chair are configured in the editor. The red cabinet is set to the same shader values as the red desk that is blue in the final image, however it remains untouched.
Here’s the code in question:
public override void _Ready()
{
TextureRect rect = new TextureRect();
ShaderMaterial material = ResourceLoader.Load<ShaderMaterial>("res://color_material.tres");
material.SetShaderParameter("target_color", new Color(255, 0, 0)); // Example: Red
material.SetShaderParameter("replacement_color", new Color(0, 0, 255));
material.SetShaderParameter("tolerance", 0.1);
Texture2D texture = ResourceLoader.Load<Texture2D>("res://cabinet.png");
rect.Texture = texture;
rect.SetMaterial(material); //= material;
rect.Position = new Vector2(128,128);
AddChild(rect);
var m = (ShaderMaterial)rect.Material;
var x = m.GetShaderParameter("target_color");
GD.Print("Target Color:" + x);
var y = m.GetShaderParameter("replacement_color");
GD.Print("Replacement Color:" + y);
var z = m.GetShaderParameter("tolerance");
GD.Print("Tolerance:" + z);
}
Note the print statements show the correct values when the project is run.
In case it matters, here’s the shader:
shader_type canvas_item;
uniform vec4 target_color : source_color;
uniform vec4 replacement_color : source_color;
uniform float tolerance : hint_range(0.0, 1.0) = 0.1;
void fragment() {
vec4 current_color = texture(TEXTURE, UV);
// Calculate distance between current pixel and target color
if (distance(current_color.rgb, target_color.rgb) <= tolerance) {
// Replace color while maintaining transparency
COLOR = vec4(replacement_color.rgb, current_color.a);
} else {
COLOR = current_color;
}
}
//void light() {
// // Called for every pixel for every light affecting the CanvasItem.
// // Uncomment to replace the default light processing function with this one.
//}
Any help would be greatly appreciated as I have spent a long time on this and tried many things.

