Waving Chequered Flag
Waving flag with adjustable check size, colours, wave parameters, edge softness and psuedo specular shading.
Just apply shader to ColorRect or similar.
Shader code
shader_type canvas_item;
uniform vec4 color_dark : source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform vec4 color_light : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform int checks_horizontal : hint_range(2, 32) = 12;
uniform int checks_vertical : hint_range(2, 32) = 7;
uniform float wave_amplitude_y : hint_range(0.0, 0.25) = 0.05;
uniform float wave_frequency_y : hint_range(0.1, 5.0) = 1.2;
uniform float wave_speed_y : hint_range(0.0, 5.0) = 1.8;
uniform float wave_amplitude_x : hint_range(0.0, 0.25) = 0.01;
uniform float wave_frequency_x : hint_range(0.1, 5.0) = 2.5;
uniform float wave_speed_x : hint_range(0.0, 5.0) = 2.0;
uniform float specular_strength : hint_range(0.0, 0.5) = 0.5;
uniform float specular_falloff : hint_range(0.1, 2.0) = 1.5;
uniform float edge_softness : hint_range(0.001, 0.02) = 0.008;
void fragment() {
vec2 uv = UV;
float phase_y = uv.x * wave_frequency_y * 6.28318 + TIME * wave_speed_y;
float wave_y = sin(phase_y);
float wave_offset_y = wave_y * wave_amplitude_y;
float phase_x = uv.y * wave_frequency_x * 6.28318 + TIME * wave_speed_x;
float wave_x = sin(phase_x);
float wave_offset_x = wave_x * wave_amplitude_x;
float margin_y = wave_amplitude_y + 0.05;
float margin_x = wave_amplitude_x + 0.05;
float flag_height = 1.0 - (margin_y * 2.0);
float flag_width = 1.0 - (margin_x * 2.0);
float flag_y = (uv.y - margin_y) / flag_height;
float flag_x = (uv.x - margin_x) / flag_width;
float warped_y = flag_y + wave_offset_y;
float warped_x = flag_x + wave_offset_x;
// Check if we're within flag bounds
float top_edge = smoothstep(0.0 - edge_softness, 0.0 + edge_softness, warped_y);
float bottom_edge = smoothstep(1.0 + edge_softness, 1.0 - edge_softness, warped_y);
float left_edge = smoothstep(0.0 - edge_softness, 0.0 + edge_softness, warped_x);
float right_edge = smoothstep(1.0 + edge_softness, 1.0 - edge_softness, warped_x);
float alpha = top_edge * bottom_edge * left_edge * right_edge;
if (alpha < 0.01) {
discard;
}
float dist_from_peak_y = 1.0 - wave_y;
float dist_from_peak_x = 1.0 - wave_x;
float highlight_y = exp(-dist_from_peak_y / specular_falloff);
float highlight_x = exp(-dist_from_peak_x / specular_falloff);
float specular = (highlight_y + highlight_x) * 0.5 * specular_strength;
vec2 checker_uv = vec2(warped_x, warped_y);
float check_x = floor(checker_uv.x * float(checks_horizontal));
float check_y = floor(checker_uv.y * float(checks_vertical));
float checker = mod(check_x + check_y, 2.0);
vec4 base_color = mix(color_dark, color_light, checker);
vec3 final_rgb = base_color.rgb + vec3(specular);
COLOR = vec4(final_rgb, base_color.a * alpha);
}




