Texture-Based Color Swapper
This shader can detect black & white spots on a 2D texture, and change their color.
Here’s how i use it to change 4 different Sprite2D’s colors. Each of them use the same .png as texture. They are also the children of the Control node this code goes in.
extends Control
var outerLayerColor = Vector2(.28, .53)
var innerLayerColor = Vector2(.21, .72)
var shader_material
func _ready() -> void:
randomize()
for uiElement in get_child_count(): # I'm using a Control node with 4 circle sprite children.
var variation = randf_range(.14,.40)
get_child(uiElement).material = ShaderMaterial.new()
get_child(uiElement).material.shader = preload("res://shaders/uiCircleColor.gdshader")
shader_material = get_child(uiElement).material as ShaderMaterial
shader_material.set_shader_parameter("outer_layer", Color.from_hsv(variation, outerLayerColor.x, outerLayerColor.y))
shader_material.set_shader_parameter("inner_layer", Color.from_hsv(variation, innerLayerColor.x, innerLayerColor.y))
print(shader_material.get_shader_parameter("outer_layer"))
print(shader_material.get_shader_parameter("inner_layer"))
shader_material.set_shader_parameter("white_threshold", .5)
shader_material.set_shader_parameter("black_threshold", 1)
Shader code
// A shader by edgyneer
shader_type canvas_item;
// Exported color variables for easy adjustment in code or the editor
uniform vec3 outer_layer = vec3(0.0, 1.0, 0.0);
uniform vec3 inner_layer = vec3(1.0, 0.0, 0.0);
// Threshold for detecting white and black colors
uniform float white_threshold = 0.9;
uniform float black_threshold = 0.1;
void fragment() {
vec4 tex_color = texture(TEXTURE, UV);
if (tex_color.r > white_threshold && tex_color.g > white_threshold && tex_color.b > white_threshold) {
// If the color is close to white, set it to the selected color
COLOR = vec4(outer_layer, tex_color.a);
} else if (tex_color.r < black_threshold && tex_color.g < black_threshold && tex_color.b < black_threshold) {
// If the color is close to black, set it to the selected color
COLOR = vec4(inner_layer, tex_color.a);
} else {
// Keep other colors the same
COLOR = tex_color;
}
}