Files
tgcc/core/daynight/environment_dust.gdshader

76 lines
2.7 KiB
Plaintext

shader_type canvas_item;
uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap;
global uniform float global_wind_speed;
global uniform float global_wind_fade;
uniform vec4 dust_color : source_color = vec4(1.0, 0.456, 0.125, 0.6);
uniform vec2 wind_speed = vec2(-0.2, 0.05);
uniform float wind_oscillation : hint_range(0.0, 1.0) = 0.3;
uniform float dust_speed : hint_range(0.01, 1.0) = 0.15;
uniform float size_min : hint_range(0.001, 0.1) = 0.02;
uniform float size_max : hint_range(0.01, 0.5) = 0.2;
uniform float dust_density : hint_range(0.01, 10.0) = 1.0;
// Softness
// 0.0 = Sfumatura totale dal centro esatto fino al bordo.
// 0.5 = Metà pallino è solido, l'altra metà sfuma.
// 0.9 = Pallino dai bordi durissimi.
uniform float solid_core : hint_range(0.0, 0.99) = 0.1;
vec3 hash33(vec3 p3) {
p3 = fract(p3 * vec3(0.1031, 0.1030, 0.0973));
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.xxy + p3.yzz) * p3.zyx);
}
void fragment() {
vec4 scene_color = texture(screen_texture, SCREEN_UV);
float base_time = TIME * dust_speed;
vec2 osc = vec2(sin(TIME * 0.5), cos(TIME * 0.3)) * wind_oscillation;
float wind_active = global_wind_fade * step(0.0001, abs(global_wind_speed));
vec2 final_wind = ((wind_speed + osc) * dust_speed) * wind_active;
float final_particle_alpha = 0.0;
//Thresolds (near, medium, far)
vec3 layer_scales = vec3(20.0, 50.0, 100.0) / dust_density;
vec3 layer_thresholds = vec3(0.96, 0.98, 0.99);
vec3 layer_speeds = vec3(1.0, 0.6, 0.3);
for (int i = 0; i < 3; i++) {
float scale = layer_scales[i];
float threshold = layer_thresholds[i];
float speed_mult = layer_speeds[i];
vec2 st = (SCREEN_UV * scale) - (final_wind * speed_mult * base_time * 50.0);
vec2 ipos = floor(st);
vec2 fpos = fract(st);
vec3 rand = hash33(vec3(ipos, float(i)));
if (rand.z > threshold) {
float blink = sin(TIME * (2.0 + rand.x)) * 0.5 + 0.5;
float d = length(fpos - vec2(0.5));
float size = size_min + (size_max - size_min) * rand.x;
float scaled_size = size * (0.5 + 0.5 * blink);
float core = scaled_size * solid_core;
float particle_softness = 1.0 - smoothstep(core, scaled_size, d);
float intensity = (rand.z - threshold) / (1.0 - threshold);
final_particle_alpha += particle_softness * blink * intensity;
}
}
final_particle_alpha = clamp(final_particle_alpha, 0.0, 1.0);
vec4 dust_colored_particle = dust_color * final_particle_alpha;
COLOR = scene_color + dust_colored_particle;
}