How to replace a color anywhere on the screen?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Whom

I’m trying to create a shader to replace colors anywhere on the screen. As a starting point, I made a shader that should replace the color A with color B but I can’t make it work. The shader is attached to a ColorRect that is a child of a CanvasLayer. The only thing that happens is that the ColorRect becomes invisible. The scene tree looks like this:

Main
- Game
- CanvasLayer
-- ColorRect

This is my shader:

shader_type canvas_item;

uniform vec4 a: hint_color;
uniform vec4 b: hint_color;

void fragment() {
	vec4 c = texture(SCREEN_TEXTURE, SCREEN_UV);
	
	if (c == a) {
		COLOR = b;
	} else {
		COLOR = c;
	}
}

I’ve used similar shader for individual sprites without any problems. Only difference is that I replaced vec4 c = texture(TEXTURE, UV) with vec4 c = texture(SCREEN_TEXTURE, SCREEN_UV) so that it would work as a “full screen” shader. What am I missing here?

Edit: Weirdly enough, this hacky solution seems to work (?) but I still don’t understand why if (c == a) doesn’t work?

shader_type canvas_item;

uniform vec4 a: hint_color;
uniform vec4 b: hint_color;

void fragment() {
	vec4 c = texture(SCREEN_TEXTURE, SCREEN_UV);
	
	if (distance(c, a) <= 0.0001) {
	    c = b;
    }

    COLOR = c;
}
:bust_in_silhouette: Reply From: Whom

I found this and this. Those solutions seem to fix the issue for the most part but I’m still unable to replace certain colors no matter what I try.

:bust_in_silhouette: Reply From: aidave

I think you may need to use a Viewport for this and put your game inside it.

Put a ViewportContainer with the Shader, then a Viewport, then the Game.

Because I don’t think your canvas layer is getting the actual screen texture.

At least that’s how I got it to work…