shader_type spatial; render_mode unshaded; // Original Trellis atlas texture uniform sampler2D albedo_tex : source_color; // Recolor mask: white = replaceable, black = keep original uniform sampler2D recolor_mask : hint_default_black; // Runtime tint color set by game code uniform vec4 tint_color : source_color = vec4(0.8, 0.8, 0.8, 1.0); // Subtle darkening on shadow side (0.0 = no shadow, 1.0 = full black) uniform float shadow_strength : hint_range(0.0, 1.0) = 0.15; uniform float shadow_threshold : hint_range(0.0, 1.0) = 0.3; void fragment() { vec4 original = texture(albedo_tex, UV); float mask = texture(recolor_mask, UV).r; // Recolor: blend tint with original, preserving luminance in masked regions // This keeps texture detail (shadows, edges, highlights) while changing the hue float luma = dot(original.rgb, vec3(0.299, 0.587, 0.114)); vec3 tinted = tint_color.rgb * (luma * 1.5 + 0.2); // scale luma to avoid too-dark vec3 base = mix(original.rgb, tinted, mask); // Gentle toon shadow — just a subtle darkening, not a color replacement vec3 light_dir = normalize(vec3(0.3, -1.0, 0.5)); float ndl = dot(NORMAL, -light_dir); float toon = smoothstep(shadow_threshold - 0.1, shadow_threshold + 0.1, ndl); vec3 color = base * mix(1.0 - shadow_strength, 1.0, toon); ALBEDO = color; }