2D Wind Sway / Tree & Grass Motion Shader
A lightweight 2D shader that simulates natural wind motion for trees, grass, and other flexible objects in side-scroll or top-down environments.
The effect increases along the vertical UV axis, creating realistic bending where the top moves more than the base. Includes adjustable wind strength, speed, falloff control, and smooth edge fading to prevent texture artifacts.
Features
Realistic 2D wind sway animation
Adjustable intensity and falloff
Smooth distortion without visible seams
Works with AtlasTexture, Sprite2D Offset, and Texture Regions
Suitable for foliage, fabric, environment props, and animated backgrounds
How to Use
1- Copy the shader code into a CanvasItem Shader material.
2- Assign the material to a Sprite2D, Tile, or AtlasTexture element.
3- Configure wind parameters to match your art style.
Shader code
shader_type canvas_item;
uniform float wind_start_threshold : hint_range(0,1) = 0.1;
uniform float wind_end_threshold : hint_range(0,10) = 2;
uniform float wind_end_threshold_2 : hint_range(0,2) = .1;
uniform float wind_strength : hint_range(0,1.5) = .2;
uniform float wind_speed : hint_range(.2,5) = 1;
uniform float scale = 2.0;
void vertex() {
VERTEX *= scale;
}
void fragment() {
vec2 uv = (UV - REGION_RECT.xy) / REGION_RECT.zw * scale;
uv -= (scale - 1.) / scale;
float dist_amount = smoothstep(wind_start_threshold * pow((1.0 - uv.y), wind_end_threshold), wind_end_threshold_2, 1.-uv.y);
uv.x += sin(TIME * wind_speed) * pow((1.0 - uv.y), wind_end_threshold) * dist_amount * wind_strength ;
COLOR = texture(TEXTURE, uv * REGION_RECT.zw + REGION_RECT.xy);
vec2 border = step(vec2(0.0), uv) * step(uv, vec2(1.0));
COLOR.a *= border.x * border.y;
}



