Files
tekton/scripts/shaders/character_skin.gdshader
T

82 lines
2.8 KiB
Plaintext

shader_type spatial;
render_mode depth_draw_always, cull_back;
uniform sampler2D albedo_texture : source_color;
uniform vec4 hat_color : source_color = vec4(1.0);
uniform vec4 gloves_color : source_color = vec4(1.0);
uniform vec4 cloth_color : source_color = vec4(1.0);
uniform vec4 skin_color : source_color = vec4(1.0);
uniform vec2 hat_uv_min = vec2(0.6, 0.1);
uniform vec2 hat_uv_max = vec2(1.0, 0.5);
uniform vec2 hat_uv_min2 = vec2(-1.0);
uniform vec2 hat_uv_max2 = vec2(-1.0);
uniform vec2 gloves_uv_min = vec2(0.6, 0.5);
uniform vec2 gloves_uv_max = vec2(1.0, 0.7);
uniform vec2 gloves_uv_min2 = vec2(-1.0);
uniform vec2 gloves_uv_max2 = vec2(-1.0);
uniform vec2 cloth_uv_min = vec2(0.0, 0.7);
uniform vec2 cloth_uv_max = vec2(1.0, 1.0);
uniform vec2 cloth_uv_min2 = vec2(-1.0);
uniform vec2 cloth_uv_max2 = vec2(-1.0);
uniform vec4 hat_match_color : source_color = vec4(0.0);
uniform vec4 gloves_match_color : source_color = vec4(0.0);
uniform vec4 cloth_match_color : source_color = vec4(0.0);
uniform float color_tolerance = 0.05;
uniform int highlight_part = -1; // -1: none, 0: hat, 1: gloves, 2: cloth, 3: skin
uniform float alpha_scissor_threshold : hint_range(0.0, 1.0) = 0.5;
uniform bool is_selected = false;
instance uniform int mesh_category : hint_range(-1, 3) = -1;
bool in_rect(vec2 uv, vec2 mi, vec2 ma) {
if (mi.x < 0.0) return false;
return uv.x >= mi.x && uv.x <= ma.x && uv.y >= mi.y && uv.y <= ma.y;
}
bool color_match(vec3 c1, vec3 c2) {
if (length(c2) < 0.01) return false; // Ignore black/empty targets
return distance(c1, c2) < color_tolerance;
}
void fragment() {
vec4 tex = texture(albedo_texture, UV);
if (tex.a < alpha_scissor_threshold) discard;
vec3 final_color = tex.rgb;
float emission_mult = 0.0;
if (is_selected) emission_mult = 0.4;
int cat = mesh_category;
// If no manual mesh assignment, use UV Detection + Color Match (Magic Wand)
if (cat == -1) {
if (in_rect(UV, hat_uv_min, hat_uv_max) || in_rect(UV, hat_uv_min2, hat_uv_max2) || color_match(tex.rgb, hat_match_color.rgb)) cat = 0;
else if (in_rect(UV, gloves_uv_min, gloves_uv_max) || in_rect(UV, gloves_uv_min2, gloves_uv_max2) || color_match(tex.rgb, gloves_match_color.rgb)) cat = 1;
else if (in_rect(UV, cloth_uv_min, cloth_uv_max) || in_rect(UV, cloth_uv_min2, cloth_uv_max2) || color_match(tex.rgb, cloth_match_color.rgb)) cat = 2;
else cat = 3;
}
if (cat == 0) {
final_color *= hat_color.rgb;
if (highlight_part == 0) emission_mult = 0.5;
} else if (cat == 1) {
final_color *= gloves_color.rgb;
if (highlight_part == 1) emission_mult = 0.5;
} else if (cat == 2) {
final_color *= cloth_color.rgb;
if (highlight_part == 2) emission_mult = 0.5;
} else {
final_color *= skin_color.rgb;
if (highlight_part == 3) emission_mult = 0.5;
}
ALBEDO = final_color;
EMISSION = final_color * emission_mult;
ALPHA = tex.a;
}