Files
2026-09-05 22:54:54 +02:00

58 lines
2.4 KiB
Plaintext

shader_type spatial;
render_mode specular_disabled;
// Blender UV2.x is a discrete palette role. Every part is one opaque surface.
uniform vec4 fur_color : source_color = vec4(0.78, 0.54, 0.31, 1.0);
uniform vec4 muzzle_color : source_color = vec4(0.93, 0.89, 0.82, 1.0);
uniform vec4 outfit_color : source_color = vec4(0.29, 0.42, 0.62, 1.0);
uniform vec4 linen_color : source_color = vec4(0.94, 0.90, 0.83, 1.0);
uniform vec4 scarf_color : source_color = vec4(0.45, 0.58, 0.75, 1.0);
uniform vec4 trousers_color : source_color = vec4(0.47, 0.58, 0.71, 1.0);
uniform vec4 leather_color : source_color = vec4(0.44, 0.29, 0.22, 1.0);
uniform vec4 coat_color : source_color = vec4(1.0);
uniform float profession_tint : hint_range(0.0, 1.0) = 0.0;
vec3 paint_to_srgb(vec3 linear_color) {
return mix(12.92 * linear_color, 1.055 * pow(max(linear_color, vec3(0.0)), vec3(1.0 / 2.4)) - 0.055,
step(vec3(0.0031308), linear_color));
}
vec3 paint_to_linear(vec3 srgb_color) {
return mix(srgb_color / 12.92, pow((srgb_color + 0.055) / 1.055, vec3(2.4)),
step(vec3(0.04045), srgb_color));
}
void fragment() {
int role = int(round(UV2.x));
vec3 coat = mix(outfit_color.rgb, coat_color.rgb, profession_tint);
// glTF vertex paint is linear; Compatibility expects fragment ALBEDO in sRGB.
vec3 paint = OUTPUT_IS_SRGB ? paint_to_srgb(COLOR.rgb) : COLOR.rgb;
if (role == 1) { paint = fur_color.rgb; }
else if (role == 2) { paint = muzzle_color.rgb; }
else if (role == 3) { paint = coat; }
else if (role == 4) { paint = linen_color.rgb; }
else if (role == 5) { paint = scarf_color.rgb; }
else if (role == 6) { paint = trousers_color.rgb; }
else if (role == 7) { paint = leather_color.rgb; }
else if (role == 8) {
paint = OUTPUT_IS_SRGB
? paint_to_srgb(paint_to_linear(fur_color.rgb) * vec3(0.42, 0.36, 0.31))
: fur_color.rgb * vec3(0.42, 0.36, 0.31);
}
else if (role == 9) {
paint = OUTPUT_IS_SRGB ? paint_to_srgb(paint_to_linear(coat) * 0.45) : coat * 0.45;
}
ALBEDO = paint;
ROUGHNESS = 1.0;
}
void light() {
float facing = dot(NORMAL, LIGHT);
float mid = smoothstep(-0.10, 0.01, facing);
float bright = smoothstep(0.48, 0.55, facing);
vec3 tone = mix(vec3(0.25, 0.30, 0.37), vec3(0.65, 0.68, 0.71), mid);
tone = mix(tone, vec3(1.0, 0.97, 0.88), bright);
// Godot multiplies the accumulated diffuse light by ALBEDO after light().
DIFFUSE_LIGHT += tone * LIGHT_COLOR * ATTENUATION / PI;
}