Update actual image from shaders

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

Lets say i have an sprite with an image which have three colors - red, green and pink.
Now if i change the color of red part to blue using a shader like this →

shader_type canvas_item;

uniform vec4 oldColor : hint_color;
uniform vec4 newColor : hint_color;

void fragment(){
	vec4 curr_color = texture(TEXTURE,UV);

	if(curr_color == oldColor){
		COLOR = newColor;
	}
	else{
		COLOR = curr_color;
	}
}

It will successfully change , now if i try to change lets say green to yellow, it will also work but it will reset the blue color back to red.
So I think this can be due to that the shader is not updating the actual image, since I am using img.get_pixel() to get the color value where I click and update the oldColor variable of the shader from my gdscript.
So what it is doing is it is seeing that the blue color as red because the actual color on Image may still be red and the blue is just like an overlay.

So how do i update the image so that the colors get updated in the shader as well ?

:bust_in_silhouette: Reply From: Inces

But wait, You are trying to change 2 colors into 2 different colors with this single if statement ?
Think of fragmentfunction like of process function. It is iterating all pixels every frame, not just once. So when You input new uniform data, it will start to override old one every frame. Thus your if statement can only change one color to another color.

can I somehow update the texture(the first line of fragment()) to be a new image with changed colors after I change one Color ?

musa | 2023-01-10 03:50

Now I see what You were trying to do. Shaders can’t return non-visual feedback of any data You input to them. saving image or get_pixel will also not be able to retrieve changed data.
Maybe You should consider using masks instead. Like feed the shader with alpha textures of face, shirt, pants, shoes and resolve color assignment for each masked part of the sprite.

uniform sampler2D mask_face 
uniform vec4 color_face : hint_color;

void fragment():
     float face = texture(mask_face,UV).r;
     COLOR.xyz = mix(COLOR.xyz,color_face,face);

Inces | 2023-01-10 13:55