shader_type spatial; render_mode blend_mix, depth_draw_never, cull_disabled; // Snow globals global uniform float global_snow_start_time; global uniform float global_snow_accumulation_speed; global uniform float global_snow_melt_time; global uniform float global_snow_melt_speed; global uniform vec4 global_snow_color; // Rain globals global uniform float global_rain_intensity; // Snow parameters uniform float snow_edge_softness : hint_range(0.01, 0.5) = 0.15; uniform float snow_color_variation : hint_range(0.0, 0.15) = 0.05; // Rain wetness parameters uniform float wetness_darkening : hint_range(0.0, 0.5) = 0.25; uniform float wet_roughness : hint_range(0.0, 0.3) = 0.05; void fragment() { // Snow accumulation float snow_amount = 0.0; if (global_snow_start_time >= 0.0) { snow_amount = clamp((TIME - global_snow_start_time) * global_snow_accumulation_speed, 0.0, 1.0); } if (global_snow_melt_time >= 0.0) { float melt = clamp((TIME - global_snow_melt_time) * global_snow_melt_speed, 0.0, 1.0); snow_amount *= (1.0 - melt); } // UV-based snow mask: accumulates from the top of the quad float top_mask = 1.0 - UV.y; float snow_mask = smoothstep(1.0 - snow_amount, 1.0 - snow_amount + snow_edge_softness, top_mask); snow_mask *= step(0.01, snow_amount); // Snow color with slight variation float shade = fract(sin(dot(UV, vec2(12.9898, 78.233))) * 43758.5453); shade = mix(-snow_color_variation, snow_color_variation, shade); vec3 snow_albedo = clamp(global_snow_color.rgb + vec3(shade), 0.0, 1.0); // Rain wetness float rain_int = clamp(global_rain_intensity, 0.0, 1.0); float rain_factor = wetness_darkening * rain_int; // Combine: snow takes priority over rain if (snow_mask > rain_factor) { ALBEDO = snow_albedo; ROUGHNESS = 0.15; METALLIC = 0.0; ALPHA = snow_mask; } else if (rain_int > 0.01) { ALBEDO = vec3(0.0); ROUGHNESS = wet_roughness; METALLIC = 0.0; ALPHA = rain_factor; } else { ALPHA = 0.0; } }