-
Notifications
You must be signed in to change notification settings - Fork 2
Texture Atlas Animations
There are two common ways to achieve texture animations in Urho3D. Most of these revolve around a Texture Atlas and UV manipulation, they are similar in concept to a Sprite2D
's Sprite Sheet.
Sheets are simply a uniform vec2
where the x and y components are the amount of horizontal and vertical slices in the Texture Atlas. You can get the total amount of frames by multiplying these two components.
uniform vec2 sheet; //vec2(4.0, 4.0) the Texture Atlas has a 4x4 layout
float frames = sheet.x * sheet.y; //This will calculate 16 frames
Because texture animations tend to loop, it is of interest to us that we handle circular indexes in code. We can simply calculate the frame as follows.
uniform float f_idx;
float cur_frame = mod(f_idx, frames);
Once we set up this circular index, we can calculate the offsets of the frame as follows.
float x_frame = mod(cur_frame,sheet.x)*(1/sheet.x);
float y_frame = floor(frame/sheet.y)*(1/sheet.y);
vec2 pos_frame = vec2(x_frame, y_frame);
With the two previous functions, we can now build our Texture Animation as a vertex shader.
uniform vec2 sheet;
uniform float f_idx;
/*
TextureAnimation
=================
Uses uniform sheet and frame index, can be rewritten easily to avoid this.
Takes in UV coordinates.
Returns specific frame coordinates.
*/
vec2 TextureAnimation(vec2 texCoord)
{
//Calculate Frames and Current Frame
float frames = sheet.x * sheet.y;
float cur_frame = mod(f_idx, frames);
//Get x and y coordinates of the frame
float x_frame = mod(cur_frame,sheet.x)*(1/sheet.x);
float y_frame = floor(frame/sheet.y)*(1/sheet.y);
vec2 pos_frame = vec2(x_frame, y_frame);
//Apply it to the passed in UV Coordinates
return texCoord*(1.0/sheet)+pos_frame;
}
Animating programatically is done simply by passing in the sheet parameters and frame speed
Vector2 sheet = Vector2(4.0, 4.0); //Create a 4x4 sheet
material->SetShaderParameter("sheet", sheet)
material->SetShaderParameterAnimationSpeed("f_idx", 1.0f)
For further implentation details, check out ghidra’s commit.
Developers might want to pack a texture atlas in a non-uniform way to reduce memory consumption. However, the current function only handles square frames for simplicity.
Luckily, tools such as TexturePacker, zwoptex, or Shoebox generate metadata when that can be easily passed in to the shader to handle this. The game will then need to iterate through an array of coordinates in order to animate your packed texture atlas.
https://discourse.urho3d.io/t/animated-textures/1335
https://discourse.urho3d.io/t/animated-sprite-2d-and-loading-screen/2019
https://discourse.urho3d.io/t/solved-playing-spritesheet-animation/2428
Modify me