Foliage Wind Shader

A shader to simulate the movement of foliage in the wind.

Works on Godot 4

Apply the shader to a Sprite2D node, and add a noise texture, then set the parameters however you want.

The shader has 3 ways to generate movement:

  • Noise texture, applies motion to entire sprite based on noise texture.
  • Movement with Worley Noise, apply the movement to the entire sprite with the worley noise.
  • Edge and Mask, applies the noise texture only to the edges of the sprite, and also uses a custom mask texture to generate movement only in some areas of the sprite.

 

You can use any of these 3 ways 😀

Shader code
shader_type canvas_item;
render_mode blend_mix;

uniform bool pixel_mode = true;
uniform float pixel_amount = 32.0;
uniform float distortion : hint_range(0.0, 0.1) = 0.01;

/// Noise Texture System
uniform bool texture_noise_system = true;
uniform float noise_speed = 1.0;
uniform int noise_direction : hint_range(-1, 1) = -1;
uniform sampler2D noise_texture : source_color ,repeat_enable;

/// Worley System
uniform bool worley_noise_system = false;
uniform float worley_cell_density = 10.0;
uniform float worley_speed = 2.0;

/// Bordes Effect
uniform sampler2D mask_texture : source_color, filter_nearest;
uniform bool edge_and_mask = false;
uniform float alpha_value : hint_range(0.0, 1.0) = 1.0;

/// Worley Methods
vec2 random(vec2 uv) {
	return vec2(fract(sin(dot(uv.xy,
		vec2(12.9898,78.233))) * 43758.5453123));
}

float worley(vec2 uv, float columns, float rows, float time) {
	
	vec2 index_uv = floor(vec2(uv.x * columns, uv.y * rows));
	vec2 fract_uv = fract(vec2(uv.x * columns, uv.y * rows));
	
	float minimum_dist = 1.0;  
	
	for (int y= -1; y <= 1; y++) {
		for (int x= -1; x <= 1; x++) {
			vec2 neighbor = vec2(float(x),float(y));
			vec2 point = random(index_uv + neighbor);
			point = vec2( cos(time * point.x * worley_speed), sin(time * point.y * worley_speed) ) * 0.5 + 0.5;
			
			vec2 diff = neighbor + point - fract_uv;
			float dist = length(diff);
			minimum_dist = min(minimum_dist, dist);
		}
	}
	
	return minimum_dist;
}

void fragment() {
	vec4 uv_result = vec4(0.0);
	vec2 uv;
	
	/// Pixel Mode 
	if (pixel_mode){
		uv = floor(UV * pixel_amount) / pixel_amount;
	}else{
		uv = UV;
	}
	
	/// Noise Texture System
	if (texture_noise_system){
		vec4 noise_uv = texture(noise_texture, uv + TIME * noise_speed * float(noise_direction));
		uv_result += noise_uv;
	}
	
	/// Worley Noise System
	if (worley_noise_system){
		float worley = worley(uv, worley_cell_density, worley_cell_density, TIME);
		vec4 result = texture(TEXTURE, vec2(worley));
		uv_result += result;
	}
	
	/// Blend
	vec2 noise_uv = mix(uv, uv_result.rg, distortion);
	
	if (edge_and_mask){
		vec4 base = texture(TEXTURE, uv);
		vec4 blend = texture(mask_texture, noise_uv);
	
		vec4 final_color = mix(base, blend, blend.a);
		
		COLOR = final_color;
		COLOR.a = (texture(TEXTURE, noise_uv).a) * alpha_value;
	}
	else
	{
		COLOR = texture(TEXTURE, noise_uv);
		COLOR.a = (texture(TEXTURE, noise_uv).a) * alpha_value;
	}
}
Tags
foliage, pixelart, wind
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.

Related shaders

Foliage animation

Wind Waker 2d Water Shader Canvas_Item

Topdown wind shader

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
anonym lover
anonym lover
6 months ago

I ♥ you