Gray tint on texture when maxing multiple textures in shader

Godot Version

Godot 4.4 rc2

Question

I’m trying to write a shader for a character that we can use to overlay tattoo or scar textures on top of the skin texture.

Currently I have this shader:

shader_type spatial;

uniform sampler2D skin_texture;  // Текстура кожи
uniform vec4 skin_tint : source_color; // Оттенок кожи

uniform sampler2D tattoo_texture1;
uniform sampler2D tattoo_texture2;
uniform sampler2D tattoo_texture3;
uniform sampler2D tattoo_texture4;
uniform sampler2D tattoo_texture5;

// Цвета татуировок
uniform vec4 tattoo_color1 : source_color;
uniform vec4 tattoo_color2 : source_color;
uniform vec4 tattoo_color3 : source_color;
uniform vec4 tattoo_color4 : source_color;
uniform vec4 tattoo_color5 : source_color;

// Интенсивность наложения каждой татуировки
uniform float tattoo_blend1 : hint_range(0, 1);
uniform float tattoo_blend2 : hint_range(0, 1);
uniform float tattoo_blend3 : hint_range(0, 1);
uniform float tattoo_blend4 : hint_range(0, 1);
uniform float tattoo_blend5 : hint_range(0, 1);

void fragment() {
    // Загружаем текстуру кожи
    vec3 skin_color = texture(skin_texture, UV).rgb;

    // Получаем татуировки с одной UV
    vec4 tattoo1 = texture(tattoo_texture1, UV) * tattoo_color1;
    vec4 tattoo2 = texture(tattoo_texture2, UV) * tattoo_color2;
    vec4 tattoo3 = texture(tattoo_texture3, UV) * tattoo_color3;
    vec4 tattoo4 = texture(tattoo_texture4, UV) * tattoo_color4;
    vec4 tattoo5 = texture(tattoo_texture5, UV) * tattoo_color5;

    // Смешивание татуировок с кожей (учитываем прозрачность PNG и интенсивность)
    vec3 final_color = skin_color;

    final_color = mix(final_color, tattoo1.rgb, tattoo1.a * tattoo_blend1);
    final_color = mix(final_color, tattoo2.rgb, tattoo2.a * tattoo_blend2);
    final_color = mix(final_color, tattoo3.rgb, tattoo3.a * tattoo_blend3);
    final_color = mix(final_color, tattoo4.rgb, tattoo4.a * tattoo_blend4);
    final_color = mix(final_color, tattoo5.rgb, tattoo5.a * tattoo_blend5);
    ALBEDO = final_color;
}

But with this shader the base skin texture has a slightly more grey tint (pale texture) rather than the original color:

I tried changing the ALBEDO value to this, it fixed the paleness of the main texture, but the tattoo texture became semi-transparent:

ALBEDO = vec3(texture(skin_texture, UV).r,texture(skin_texture, UV).g,texture(skin_texture, UV).b) * final_color;

I can’t achieve this - so that the main texture is without a gray tint, and at the same time the tattoo texture is not semi-transparent.

It’s strange, but the texture shade will be gray even with a minimal shader, this does not happen in StandartMaterial3D, what is the reason for this?

On the left is the shader, on the right is the StandardMaterial3D:

You need to give the hint source_color to the sampler2D uniform that you are using for color. More info here Shading language — Godot Engine (stable) documentation in English

2 Likes