Modulate only certain pixels of sprite

Godot Version

v4.2.2.stable.official

Question

I have a white / grayscale sprite that I’d like to change the color of. I do want to keep the colors of the eyes of the character and some highlighting unchanged though.

My initial idea was to create a binary mask image where the pixels that I don’t want modulated are set to black, and the rest to white. I then pass the mask image to a fragment shader as a uniform, as well as the color to modulate with.
Here’s my shader code:

shader_type canvas_item;

uniform sampler2D mask;
uniform vec4 modulate: source_color;

void fragment() {
    vec4 color = texture(TEXTURE,UV);
    vec4 color_mask = texture(mask, UV);
    if (color_mask == vec4(1.)) {
        color *= modulate;
    }
    COLOR = color;
}

This kind of works, but it leaves these pixels around the eyes and the highlight unmodulated for some reason:

How do I fix this? Is this even the right approach for this problem?

I’d suggest using a special colour for the eyes though and converting that, that way it’ll stick out, or use a soft mask instead of a binary one, so use a texture with white where you want to blend

I’m not sure I understand, could you elaborate further please?

Instead of using a bitmap for the area to colour use a texture with soft edges and use it to change the colour by multiplication

How do I do that?

I’d say just color *= color_mask but I haven’t tried, you’d need to create the mask though, using perhaps some soft edge tool in an image editor

You might also need to change the filter for the mask texture, using uniform sampler2D mask: filter_nearest, try that first perhaps, it might cause blurring if filtered

1 Like

That was it, thanks!

1 Like