Flagwave Text

Vertex shader for flag-like wave and flutter. Superposes sine movement (labelled flutter) with a time based horizontally wandering peak function (wave) and modifies VERTEX. Both movement parts are parametrizable.

As 3rd component lighting is added, where the uniform parameter `u_x_light` moves the light across the object in x-direction.

The screenshot was realized using a `Light2D` with a `GradientTexture` parallel to a `Label`.

Change `render_mode` to `blend_mix` or `blend_add` depending on your usecase.

Shader code
shader_type canvas_item;
render_mode light_only;

const float PI = 3.14159265358979323846;

uniform float u_amp_flutter: hint_range(0, 100) = 10.0;
uniform float u_angle_flutter: hint_range(-180, 180) = 30.0;
uniform float u_speed_flutter: hint_range(0.1, 10) = 1.0;
uniform float u_amp_wave: hint_range(0, 100) = 10.0;
uniform float u_angle_wave: hint_range(-180, 180) = -30.0;
uniform float u_speed_wave: hint_range(0, 10) = 2.0;
uniform float u_len_wave: hint_range(10, 1000) = 100.0;
uniform float u_shape_wave: hint_range(1, 10) = 3;
uniform float u_width_wave: hint_range(0.1, 4) = 1;
uniform float u_x_light: hint_range(-1, 4) = 0.2;
uniform float u_shape_light: hint_range(0.5, 4) = 2;
uniform float u_width_light: hint_range(0.1, 2) = 1;



vec2 rotate(vec2 v, float angle) {
	mat2 rotation_matrix = mat2(
			vec2(cos(angle / 180.0 * PI), -sin(angle / 180.0 * PI)),
			vec2(sin(angle / 180.0 * PI), cos(angle / 180.0 * PI)));
	return v * rotation_matrix;
}

float lorentzian(float x, float x0, float w, float shp) {
	// modified lorentzian peak function with half-width w and exponent shp
	// around center of x0. Normalized to be 1 at x0.
	return pow(w, 2) / (pow(abs(x - x0), shp) + pow(w, 2));
}

float lorentzian_periodic(float x, float x0, float w, float shp, float per) {
	return lorentzian(mod(x - per/ 2.0 - x0, per), per / 2.0, w, shp);
}

void light() {
	float x = FRAGCOORD.x / 200.0 / u_width_light;
	float x0 = u_x_light * 4.0 / u_width_light;
	LIGHT.a = lorentzian(x, x0, 1, u_shape_light);
}

void vertex() {
	float x = mod(VERTEX.x / u_len_wave, 1.0) * 4.0 - 2.0;
	float x0 = TIME * u_speed_wave;
	float amp_wave = u_amp_wave * lorentzian_periodic(x, x0, u_width_wave, u_shape_wave, 4);
	vec2 wave = rotate(vec2(amp_wave, 0), u_angle_wave);
	float amp_flutter = u_amp_flutter * sin(u_speed_flutter * TIME);
	vec2 flutter = rotate(vec2(amp_flutter, 0), u_angle_flutter);
	VERTEX = VERTEX + flutter + wave;
}
Tags
flag, flutter, wave, waving
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.
guest

0 Comments
Inline Feedbacks
View all comments