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; }