58 lines
2.4 KiB
Plaintext
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;
|
|
}
|