Changes to Sprite via shader don't carry over to animations

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

I have added a shader to a Sprite so as to change a part of its color. While this works fine in the editor, this change isn’t shown in the animations of the Sprite. I first animated it in an AnimationPlayer, and then I further animated it in an AnimationTree. The AnimationTree is used to play advanced animations which are controlled from code. Here’s a video to illustrate what I mean.

When the game is ran, the changes from the shader aren’t shown in the Sprite. No part of the character’s animations show the changed color.

what is in AnimationPlayer ? Do You change shader_param inside it ? Or modulate ?

Inces | 2022-09-12 15:22

I tried adding the shader parameters as keys to AnimationPlayer, but that didn’t affect the animation. I also tried changing the shader parameters from code, but that didn’t change anything, ether.

Ertain | 2022-09-12 17:27

:bust_in_silhouette: Reply From: Inces

if shader works in editor, but doesn’t work at runtime, something is blocking it, conflicting with its code. Show your AnimationPlayer keyframes.

Here’s a screenshot of the keyframes of one of the animations.
Main character's animation in keyframes in the animation panel.

Ertain | 2022-09-12 22:33

You mean You don’t manipulate shader params in AnimationPlayer now ?

Could it be frames are treated as different textures for shader ? Can You try disabling this animation track ?

Inces | 2022-09-13 16:29

What do you mean by disabling the animation track? Disable the animated frames in the track?

Ertain | 2022-09-13 18:44

uncheck this box, to disable this channel, so Sprite will keep its original texture. I wonder if it will fix shader.

Inces | 2022-09-13 19:16

Could you elaborate on that? Which box should be unchecked?

Ertain | 2022-09-13 19:53

the only box in your printscreen :slight_smile: frame
I want Sprite to stay on one texture, I suspect shader may somehow not understand idea of replacing frames

Inces | 2022-09-13 20:33

I turned that track off. But for some reason, that track can still play in the AnimationTree. And the shader wasn’t applied, either; it still uses the original texture.

Ertain | 2022-09-13 23:49

Ah, that is true, AnimationTree uses AnimationPlayer as a data container, so we will have to disable this animation in AnimationTree to test shader

Inces | 2022-09-14 12:19

I tried changing the colors for other characters, and the only one that I could change the color on was the skeleton enemy. And I don’t know why.

Ertain | 2022-09-14 17:31

or can your shader code be calculated against background ?
Can You show shader code ?

Inces | 2022-09-14 18:20

Here’s the shader code:

shader_type canvas_item;

uniform vec4 origin:hint_color;
uniform vec4 new:hint_color;

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

    if (current_pixel == origin)
        COLOR = new;
    else
        COLOR = current_pixel;
}

Ertain | 2022-09-14 23:39

wow, that is performance heavy shader.
It is quite possible, that it is unable to compare 4 floating values perfectly at runtime.
You should use mask for this kind of tasks. Isolate trousers from your png, make them black against tranmsparent background and use this as a uniform Sampler2D to mark certain area of original sprite. With this You won’t need costly if statement, You will just multiply by color or use mix statement

uniform Sampler2D mask
uniform vec4 new
void fragment() :
        float maskpixel = texture(mask, UV).a
       COLOR = mix( COLOR, new, maskpixel)

Inces | 2022-09-15 15:13

I don’t quite follow your directions. Should your shader be applied to a node which is a child of the original Sprite?

Ertain | 2022-09-15 18:40