Mix UV Flipbook animation

Shader code
// ElSuicio, 2026.
// GODOT v4.7.1.stable.
// x.com/ElSuicio
// github.com/ElSuicio
// Contact email [interdreamsoft@gmail.com]

shader_type spatial;
render_mode unshaded;

group_uniforms _Flipbook;
uniform sampler2D _FlipbookTexture : source_color, filter_nearest, repeat_disable;
uniform float _Fps : hint_range(0.0, 120.0, 1e-0) = 1.0;
uniform sampler2D _CurveTexture : filter_linear, repeat_disable;
uniform int _TileWidth : hint_range(1, 128, 1) = 4;
uniform int _TileHeight : hint_range(1, 128, 1) = 4;
uniform bool _InvertX = false;
uniform bool _InvertY = false;

vec2 flipbook(
	in vec2 st,
	in int frame,
	in int cols,
	in int rows,
	in bool invert_x,
	in bool invert_y
)
{
	int grid_size = rows * cols;
	
	//frame = ((frame % grid_size) + grid_size) % grid_size;
	frame %= grid_size;
	
	int row = frame / cols; 
	int col = frame % cols;
	
	col = invert_x ? (cols - 1) - col : col;
	row = invert_y ? (rows - 1) - row : row;
	
	return (st + vec2(float(col), float(row))) * vec2(1.0 / float(cols), 1.0 / float(rows));
}

void fragment() {
	float time = TIME * _Fps;
	int frame = int(floor(time));
	
	vec2 st = flipbook(UV, frame, _TileWidth, _TileHeight, _InvertX, _InvertY);
	vec2 st2 = flipbook(UV, frame + 1, _TileWidth, _TileHeight, _InvertX, _InvertY);
	
	vec4 current = texture(_FlipbookTexture, st);
	vec4 next = texture(_FlipbookTexture, st2);
	
	//float t = time - floor(time); // fract(time).
	float t = texture(_CurveTexture, vec2(fract(time), 0.5)).r;
	
	vec4 color = current * (1.0 - t) + next * t; // mix(current, next, t).
	
	ALBEDO = color.rgb;
	//ALPHA = color.a;
}
Live Preview
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from ElSuicio

Related shaders

Comments 0

No comments yet.