Wind sway for foliage and flags
A gentle sway for trees, grass, flags, hair and banners. The top moves most and the base stays planted. It animates on its own, no script needed.
Settings:
- strength (0-0.15), speed.
Tip: give each copy a slightly different speed (each with its own material) so a row of trees does not move in sync.
Works with the Compatibility renderer and respects the node modulate.
This shader is part of the free 2D FX Essentials pack (9 sprite shaders with a demo scene): https://dimensionalmios.itch.io/almios-2d-fx-essentials
Shader code
shader_type canvas_item;
// Wind sway for foliage, flags, hair and banners. The top of the sprite sways
// most; the bottom row stays anchored.
uniform float strength : hint_range(0.0, 0.15) = 0.04;
uniform float speed : hint_range(0.0, 6.0) = 2.0;
uniform vec2 sheet_frames = vec2(1.0, 1.0); // a sprite sheet: its hframes and vframes, so the effect works per frame
// 0: every sprite sways in step. Up to 1: each one is shifted in time by its place in the
// world, so a row of bushes does not sway as one
uniform float position_phase : hint_range(0.0, 1.0) = 0.0;
varying vec4 vertex_tint; // modulate and self_modulate, applied at the end
varying float phase;
void vertex() {
vertex_tint = COLOR;
phase = MODEL_MATRIX[3].x * 0.02 * position_phase;
}
void fragment() {
// the frame of a sprite sheet (1 x 1: the whole texture, as before)
vec2 cell = min(floor(UV * sheet_frames), sheet_frames - 1.0);
vec2 uv = UV * sheet_frames - cell;
// (a whole number of turns per hour: no jump when TIME starts again every hour)
float sp = round(speed * 3600.0 / TAU) * TAU / 3600.0;
float sway = sin(TIME * sp + uv.y * 3.0 + phase) * strength * (1.0 - uv.y);
uv.x += sway;
COLOR = texture(TEXTURE, (cell + uv) / sheet_frames);
// what sways past the side of the frame is empty, not a smear of its edge column (or
// the frame next door)
// (faded over a pixel, not cut: a sprite opaque up to its side keeps a smooth edge)
float px = fwidth(uv.x) + 1e-5;
COLOR.a *= smoothstep(-px, 0.0, uv.x) * (1.0 - smoothstep(1.0, 1.0 + px, uv.x));
COLOR *= vertex_tint;
}



Comments 0
No comments yet.