Godot4.3: Sampler mask shader strange behavior when applied on animated sprite
Edit: Resolved.
TLDR:
I didn't understand how UV works in shader and it turned out UV is for the whole texture of a sprite sheet.
I ended up with a solution that uses sprite + animation player (this method forces me to set h_frame and v_frame property)
Then the shader now becomes
shader_type canvas_item;
group_uniforms Masking;
uniform sampler2D under_water_mask;
uniform bool under_water = false;
uniform vec2 number_of_slices = vec2(2, 2);
group_uniforms;
varying vec4 modulate;
void vertex() {
modulate = COLOR;
}
void fragment() {
if (under_water) {
vec2 uv = UV;
vec4 base_color = COLOR;
vec2 sprite_sheet_size = vec2(textureSize(TEXTURE,0));
vec2 frame_size;
frame_size.x = sprite_sheet_size.x/float(number_of_slices.x);
frame_size.y = sprite_sheet_size.y/float(number_of_slices.y);
vec2 current_point = sprite_sheet_size * UV;
float row = floor(current_point.y / frame_size.y);
float column = floor(current_point.x / frame_size.x);
vec2 max_point = (frame_size * vec2(column, row)) + frame_size;
vec2 new_uv = 1.0 - (max_point - current_point) / frame_size;
base_color.a *= texture(under_water_mask, new_uv).a;
COLOR = base_color * modulate;
}
}
Then in my gdsript i set the number_of_slices
with: character_sprite.material.set_shader_parameter("number_of_slices", Vector2(character_sprite.hframes, character_sprite.vframes))
Now I can mask all the sprites in my spritesheet with a mask.
Hi Everyone.
I'm trying to hide part of the animated sprite using a simple shader. Here is my shader:
void fragment() {
COLOR.a *= texture(under_water_mask, UV).a;
}```
But I saw a strange behavior. For some characters, the sampler's size keeps changing for a certain frame, you can see that in the videos below, some of the white rectangles are blinking (changing size).
See videos: (One video only displays the sampler for easy understanding, the other one displays the masked sprite)
My sampler is basically a simple GrandiantTexture2D, see:
One thing I found out is that for the ones that are blinking, the animations in the animated sprite are re-using some frames. For example, one of the character's texture has 3 frames and 2 animations, 1 animation uses frame a,b the other uses frame b,c.
Does anyone know what I'm missing here?