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-scrolling or top-down environments.

The effect increases along the vertical Y axis, creating realistic bending where the top moves more than the base. It includes adjustable wind strength, speed, falloff control, and smooth edge fading.

How to Use

  1. Copy the shader code into a CanvasItem shader material.

  2. Configure the wind parameters to match your style.

Shader code
shader_type canvas_item;

uniform float start_y: hint_range(0, 1) = .3;
uniform float strength: hint_range(0, 1) = .15;
uniform float curve_scale: hint_range(0, 3) = 1.5;
uniform float speed : hint_range(0, 10) = 2;
uniform float wind_start: hint_range(-1.57, 1.57) = 0;
varying vec4 v_color;

void vertex() {
    v_color = COLOR;
    float scale = (pow(2.0, curve_scale) * strength * 2.0);
    VERTEX *= 1. + scale;
}

void fragment() {
    float scale = (pow(2.0, curve_scale) * strength * 2.0);
	float total_scale = 1.0 + scale;
	vec2 local_uv = (UV - REGION_RECT.xy) / REGION_RECT.zw;
	vec2 adjusted_local_uv = (local_uv - 0.5) * total_scale + 0.5;
	
	vec2 wind_uv = adjusted_local_uv;
	wind_uv.x += sin(TIME * speed + wind_start) * smoothstep(start_y , 1. + start_y , pow((1. - wind_uv.y),  .5 )) * pow((1. - wind_uv.y + 1.), curve_scale) * strength;
	if (wind_uv.x < 0.0 || wind_uv.x > 1.0 || wind_uv.y < 0.0 || wind_uv.y > 1.0) {
		discard;
	}
   
	vec2 wind_final_uv = wind_uv * REGION_RECT.zw + REGION_RECT.xy;
	COLOR = texture(TEXTURE, wind_final_uv) * v_color;
}
Live Preview
Tags
animated, custom, distortion, grass, tree, wind, wind sway
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from Purga

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments