I moved to Godot 4.0.2 yesterday and noticed strange behaviour with the COLOR
value in the fragment() function of my shader. I have a GPUParticles2D
particle system that has a basic shader applied to its material:
shader_type canvas_item;
render_mode blend_mix;
vec3 invert_color(vec3 col_in){
return 1.0 - col_in;
}
void fragment() {
vec4 img_col_rgba = texture(TEXTURE, UV); // original image
vec3 inv_img_col_rgb = invert_color(img_col_rgba.rgb); // inverted image
vec3 tint_col_rgb = COLOR.rgb; // tint color
vec3 inv_tint_col_rgb = invert_color(tint_col_rgb); // inverted tint color
vec3 rgb = invert_color(inv_img_col_rgb * inv_tint_col_rgb); // tint the image
vec4 rgba = vec4(rgb, img_col_rgba.a); // transfer old alpha value to the new image
COLOR = rgba; // apply changes
}
This shader is supposed to tint only the black part of the particle texture by inverting the texture colours, inverting the tint colour, mixing them together, and inverting the tinted texture once more. This results in the outer part of the particle being coloured, while the inside stays white.
This worked beautifully in Godot 3.5:
But in Godot 4.0.2 it seems to only tint the gray transition between white and black:
I noticed that the shader works as expected if I replace COLOR.rgb
in line 12 with a static colour like vec3(1, 0, 0)
.
And since the exact same code works in older Godot versions as well as in other engines like Unity, I'm assuming that the COLOR
changed its behaviour in Godot 4. Is this a bug or am I missing something? Is there maybe a better way to achieve this effect all together?