add rain to materials
This commit is contained in:
141
core/daynight/weather_overlay.gdshader
Normal file
141
core/daynight/weather_overlay.gdshader
Normal file
@@ -0,0 +1,141 @@
|
||||
shader_type spatial;
|
||||
render_mode blend_mix, depth_draw_never;
|
||||
|
||||
// --- Snow globals ---
|
||||
global uniform float global_snow_start_time = -1.0;
|
||||
global uniform float global_snow_accumulation_speed = 0.1;
|
||||
global uniform float global_snow_melt_time = -1.0;
|
||||
global uniform float global_snow_melt_speed = 0.1;
|
||||
global uniform float global_snow_threshold = 0.5;
|
||||
global uniform vec4 global_snow_color = vec4(0.92, 0.96, 1.0, 1.0);
|
||||
|
||||
// --- Rain globals ---
|
||||
global uniform float global_rain_intensity;
|
||||
|
||||
// --- Shared ---
|
||||
uniform sampler2D noise_texture : filter_linear_mipmap, repeat_enable;
|
||||
|
||||
// --- Snow params ---
|
||||
uniform float snow_noise_scale : hint_range(0.01, 1.0) = 0.15;
|
||||
uniform float snow_edge_softness : hint_range(0.01, 0.5) = 0.2;
|
||||
uniform float snow_roughness_variation : hint_range(0.0, 0.3) = 0.15;
|
||||
uniform float snow_color_variation : hint_range(0.0, 0.15) = 0.05;
|
||||
|
||||
// --- Rain params ---
|
||||
uniform float ripple_scale : hint_range(0.1, 5.0) = 1.5;
|
||||
uniform float ripple_speed : hint_range(0.5, 5.0) = 2.0;
|
||||
uniform float ripple_layers : hint_range(1.0, 4.0) = 3.0;
|
||||
uniform float streak_scale : hint_range(0.1, 5.0) = 2.0;
|
||||
uniform float streak_speed : hint_range(0.1, 3.0) = 0.8;
|
||||
uniform float wetness_darkening : hint_range(0.0, 0.5) = 0.25;
|
||||
uniform float wet_roughness : hint_range(0.0, 0.3) = 0.05;
|
||||
uniform float rain_normal_strength : hint_range(0.0, 1.0) = 0.4;
|
||||
|
||||
float ripple_ring(vec2 uv, float time_offset) {
|
||||
float d = length(uv);
|
||||
float ring = sin(d * 30.0 - TIME * ripple_speed + time_offset) * 0.5 + 0.5;
|
||||
float fade = smoothstep(0.5, 0.0, d);
|
||||
return ring * fade;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec3 world_pos = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
vec3 world_normal = normalize((INV_VIEW_MATRIX * vec4(NORMAL, 0.0)).xyz);
|
||||
float facing_up = clamp(world_normal.y, 0.0, 1.0);
|
||||
float noise_val = texture(noise_texture, world_pos.xz * snow_noise_scale).r;
|
||||
|
||||
// ===================== SNOW =====================
|
||||
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);
|
||||
}
|
||||
|
||||
float snow_edge = smoothstep(
|
||||
global_snow_threshold - snow_edge_softness,
|
||||
global_snow_threshold + snow_edge_softness,
|
||||
facing_up + (noise_val - 0.5) * 0.4
|
||||
);
|
||||
float snow_coverage = smoothstep(0.0, 0.6, noise_val + snow_amount - 0.4);
|
||||
float snow_factor = snow_edge * snow_coverage * snow_amount;
|
||||
|
||||
float shade = mix(-snow_color_variation, snow_color_variation, noise_val);
|
||||
vec3 snow_albedo = clamp(global_snow_color.rgb + vec3(shade), 0.0, 1.0);
|
||||
float snow_rough = mix(0.15 - snow_roughness_variation, 0.15 + snow_roughness_variation, noise_val);
|
||||
|
||||
// ===================== RAIN =====================
|
||||
float rain_int = clamp(global_rain_intensity, 0.0, 1.0);
|
||||
float rain_factor = 0.0;
|
||||
vec3 rain_albedo = vec3(0.0);
|
||||
float rain_rough = wet_roughness;
|
||||
float rain_metallic = 0.0;
|
||||
vec3 rain_normal = vec3(0.5, 0.5, 1.0);
|
||||
|
||||
if (rain_int > 0.01 && facing_up > 0.3) {
|
||||
float surface_mask = smoothstep(0.3, 0.6, facing_up);
|
||||
|
||||
// Slope detection: 0 = flat, 1 = peak at ~30-45 degrees
|
||||
float slope_angle = 1.0 - facing_up;
|
||||
float slope_mask = smoothstep(0.1, 0.25, slope_angle) * smoothstep(0.75, 0.5, slope_angle);
|
||||
|
||||
// Ripples on horizontal surfaces
|
||||
float ripple = 0.0;
|
||||
for (float i = 0.0; i < ripple_layers; i += 1.0) {
|
||||
float phase = i * 2.17;
|
||||
vec2 cell_offset = vec2(
|
||||
texture(noise_texture, world_pos.xz * ripple_scale * 0.3 + vec2(phase)).r,
|
||||
texture(noise_texture, world_pos.xz * ripple_scale * 0.3 + vec2(0.0, phase)).r
|
||||
);
|
||||
vec2 ripple_uv = fract(world_pos.xz * ripple_scale + cell_offset) - 0.5;
|
||||
ripple += ripple_ring(ripple_uv, phase * 3.7);
|
||||
}
|
||||
ripple /= ripple_layers;
|
||||
|
||||
// Flowing water on inclined surfaces (30-45 degrees)
|
||||
vec3 down_dir = normalize(world_normal - vec3(0.0, 1.0, 0.0) * facing_up);
|
||||
float flow_speed = streak_speed * (1.0 + slope_angle * 2.0);
|
||||
|
||||
// Main flow rivulets
|
||||
float flow_coord = dot(world_pos, down_dir);
|
||||
float lateral_coord = dot(world_pos.xz, vec2(-down_dir.z, down_dir.x)) * streak_scale;
|
||||
vec2 flow_uv = vec2(lateral_coord, flow_coord * streak_scale - TIME * flow_speed);
|
||||
float flow_noise = texture(noise_texture, flow_uv * 0.4).r;
|
||||
float flow2 = texture(noise_texture, flow_uv * 0.7 + vec2(0.3, TIME * flow_speed * 0.3)).r;
|
||||
float rivulets = smoothstep(0.3, 0.7, flow_noise) * smoothstep(0.25, 0.6, flow2);
|
||||
|
||||
// Accumulation at bottom (lower world_pos.y gets more water)
|
||||
float height_factor = texture(noise_texture, world_pos.xz * 0.05).r;
|
||||
float accumulation = smoothstep(0.6, 0.2, fract(world_pos.y * 0.3 + height_factor * 0.5));
|
||||
rivulets = mix(rivulets, rivulets + accumulation * 0.3, slope_mask);
|
||||
|
||||
float streak = rivulets * slope_mask;
|
||||
|
||||
// Blend ripples (flat) and streaks (inclined)
|
||||
float flat_weight = smoothstep(0.3, 0.15, slope_angle);
|
||||
float effect = mix(streak, ripple, flat_weight) * rain_int * surface_mask;
|
||||
float darkness = wetness_darkening * rain_int * surface_mask;
|
||||
|
||||
vec2 normal_offset = vec2(dFdx(effect), dFdy(effect)) * rain_normal_strength;
|
||||
rain_normal = vec3(normal_offset.x + 0.5, normal_offset.y + 0.5, 1.0);
|
||||
rain_albedo = vec3(0.02, 0.02, 0.03);
|
||||
rain_metallic = 0.3 * rain_int;
|
||||
rain_factor = effect * 0.8 + darkness;
|
||||
}
|
||||
|
||||
// ===================== COMBINE =====================
|
||||
if (snow_factor > rain_factor) {
|
||||
ALBEDO = snow_albedo;
|
||||
ROUGHNESS = snow_rough;
|
||||
METALLIC = 0.0;
|
||||
ALPHA = snow_factor;
|
||||
} else {
|
||||
ALBEDO = rain_albedo;
|
||||
ROUGHNESS = rain_rough;
|
||||
METALLIC = rain_metallic;
|
||||
NORMAL_MAP = rain_normal;
|
||||
ALPHA = rain_factor;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user