Files
leonwww/flumi/Shaders/snowfall.gdshader

59 lines
2.2 KiB
Plaintext

// Modified version of https://godotshaders.com/shader/multilayer-snowfall-shader/
// All credits to the original author!!!
shader_type canvas_item;
uniform float spread : hint_range(0.0, 1.5) = 0.5;
uniform float size : hint_range(0.01, 5.0) = 0.5;
uniform vec4 snow_color : source_color = vec4(1.0);
uniform float snow_transparency: hint_range(-0.5, 1.0) = 0.2;
uniform float speed : hint_range(0.0, 10.0) = 0.5;
uniform float wind : hint_range(-2.0, 2.0) = 0.0;
uniform int num_of_layers = 40;
const mat3 NOISE_MATRIX = mat3(
vec3(13.323122, 23.5112, 21.71123),
vec3(21.1212, 28.7312, 11.9312),
vec3(21.8112, 14.7212, 61.3934)
);
vec3 generate_snowflake(vec2 coord, float layer_index, float time, float wind_strength) {
float layer_scale = 1.0 + layer_index * 0.5 / (max(size, 0.01) * 2.0);
vec2 scaled_coord = coord * layer_scale;
vec2 movement = vec2(
scaled_coord.y * (spread * mod(layer_index * 7.238917, 1.0) - spread * 0.5) +
(-wind_strength) * speed * time * 0.5,
-speed * time / (1.0 + layer_index * 0.5 * 0.03)
);
vec2 final_coord = scaled_coord + movement;
vec3 noise_input = vec3(floor(final_coord), 31.189 + layer_index);
vec3 noise_val = floor(noise_input) * 0.00001 + fract(noise_input);
vec3 random = fract((31415.9 + noise_val) / fract(NOISE_MATRIX * noise_val));
vec2 shape = abs(mod(final_coord, 1.0) - 0.5 + 0.9 * random.xy - 0.45);
shape += 0.01 * abs(2.0 * fract(10.0 * final_coord.yx) - 1.0);
float depth_offset = 5.0 * sin(time * 0.1);
float edge_softness = 0.005 + 0.05 * min(0.5 * abs(layer_index - 5.0 - depth_offset), 1.0);
float shape_value = 0.6 * max(shape.x - shape.y, shape.x + shape.y) + max(shape.x, shape.y) - 0.01;
return vec3(smoothstep(edge_softness, -edge_softness, shape_value) *
(random.x / (1.0 + 0.02 * layer_index * 0.5)));
}
void fragment() {
vec3 snow_accumulation = vec3(0.0);
for (int i = 0; i < num_of_layers; i++) {
snow_accumulation += generate_snowflake(UV, float(i), TIME, wind);
}
float snow_intensity = clamp(length(snow_accumulation), 0.0, 1.0);
vec4 transparency_color = vec4(snow_color.rgb * (1.0 + snow_transparency), snow_intensity);
COLOR = transparency_color;
}