add rain puddle
This commit is contained in:
@@ -230,7 +230,7 @@ blur = NodePath("Blur")
|
||||
environment_shadows = NodePath("EnvironmentCloudsShadows")
|
||||
|
||||
[node name="Particles_Fireflies" type="GPUParticles3D" parent="." unique_id=947538133]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0)
|
||||
emitting = false
|
||||
amount = 60
|
||||
lifetime = 4.0
|
||||
|
||||
@@ -25,6 +25,8 @@ var timer_next_lightning: float = 0.0
|
||||
var is_raining: bool = false
|
||||
var rain_intensity: float = 0.0
|
||||
var rain_tween: Tween
|
||||
var puddle_tween: Tween
|
||||
var puddle_amount: float = 0.0
|
||||
|
||||
var snow_tween: Tween
|
||||
var snow_particles_tween: Tween
|
||||
@@ -81,6 +83,10 @@ func _ready() -> void:
|
||||
func _process(delta: float) -> void:
|
||||
|
||||
_follow_camera()
|
||||
|
||||
var is_night = day_time >= 2.5
|
||||
if particles_fireflies:
|
||||
particles_fireflies.emitting = thereare_fireflies and is_night
|
||||
|
||||
var base_tint: Color
|
||||
var base_sky_top: Color
|
||||
@@ -228,8 +234,9 @@ func _follow_camera() -> void:
|
||||
|
||||
func toggle_fireflies(value: bool):
|
||||
thereare_fireflies = value
|
||||
var is_night = day_time >= 2.5
|
||||
if particles_fireflies:
|
||||
particles_fireflies.emitting = thereare_fireflies
|
||||
particles_fireflies.emitting = thereare_fireflies and is_night
|
||||
|
||||
#disable fireflies and set default values and materials
|
||||
func set_fireflies():
|
||||
@@ -390,6 +397,11 @@ func set_rain():
|
||||
if particles_rain:
|
||||
particles_rain.visible = true
|
||||
particles_rain.emitting = false
|
||||
RenderingServer.global_shader_parameter_set("global_rain_puddle_amount", 0.0)
|
||||
|
||||
func set_puddle_amount(value: float):
|
||||
puddle_amount = value
|
||||
RenderingServer.global_shader_parameter_set("global_rain_puddle_amount", value)
|
||||
|
||||
func toggle_rain(value: bool):
|
||||
is_raining = value
|
||||
@@ -403,17 +415,24 @@ func toggle_rain(value: bool):
|
||||
if rain_tween and rain_tween.is_valid():
|
||||
rain_tween.kill()
|
||||
|
||||
if puddle_tween and puddle_tween.is_valid():
|
||||
puddle_tween.kill()
|
||||
|
||||
if is_raining:
|
||||
particles_rain.amount_ratio = 0.0
|
||||
particles_rain.emitting = true
|
||||
rain_tween = create_tween()
|
||||
rain_tween.tween_property(particles_rain, "amount_ratio", 1.0, environment_config.rain_fade_time)
|
||||
puddle_tween = create_tween()
|
||||
puddle_tween.tween_method(set_puddle_amount, puddle_amount, 1.0, environment_config.puddle_form_time)
|
||||
else:
|
||||
rain_tween = create_tween()
|
||||
rain_tween.tween_property(particles_rain, "amount_ratio", 0.0, environment_config.rain_fade_time)
|
||||
rain_tween.tween_callback(func():
|
||||
particles_rain.emitting = false
|
||||
trigger_after_rain())
|
||||
puddle_tween = create_tween()
|
||||
puddle_tween.tween_method(set_puddle_amount, puddle_amount, 0.0, environment_config.puddle_dry_time)
|
||||
|
||||
func trigger_morning() -> void:
|
||||
spawn_single_godray()
|
||||
|
||||
@@ -1,27 +1,21 @@
|
||||
shader_type spatial;
|
||||
render_mode blend_mix, depth_draw_never;
|
||||
|
||||
// --- Snow globals ---
|
||||
//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 ---
|
||||
//Rain globals
|
||||
global uniform float global_rain_intensity;
|
||||
global uniform float global_rain_puddle_amount;
|
||||
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;
|
||||
@@ -30,6 +24,10 @@ 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;
|
||||
uniform float puddle_noise_scale : hint_range(0.01, 0.5) = 0.08;
|
||||
uniform float puddle_threshold : hint_range(0.0, 0.8) = 0.45;
|
||||
|
||||
uniform sampler2D noise_texture : filter_linear_mipmap, repeat_enable;
|
||||
|
||||
float ripple_ring(vec2 uv, float time_offset) {
|
||||
float d = length(uv);
|
||||
@@ -44,7 +42,7 @@ void fragment() {
|
||||
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 =====================
|
||||
//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);
|
||||
@@ -66,7 +64,7 @@ void fragment() {
|
||||
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 =====================
|
||||
//Rain
|
||||
float rain_int = clamp(global_rain_intensity, 0.0, 1.0);
|
||||
float rain_factor = 0.0;
|
||||
vec3 rain_albedo = vec3(0.0);
|
||||
@@ -77,11 +75,11 @@ void fragment() {
|
||||
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
|
||||
//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
|
||||
//Ripples on horizontal surfaces
|
||||
float ripple = 0.0;
|
||||
for (float i = 0.0; i < ripple_layers; i += 1.0) {
|
||||
float phase = i * 2.17;
|
||||
@@ -94,11 +92,11 @@ void fragment() {
|
||||
}
|
||||
ripple /= ripple_layers;
|
||||
|
||||
// Flowing water on inclined surfaces (30-45 degrees)
|
||||
//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
|
||||
//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);
|
||||
@@ -106,26 +104,71 @@ void fragment() {
|
||||
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)
|
||||
//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)
|
||||
//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;
|
||||
rain_albedo = vec3(0.05, 0.05, 0.06);
|
||||
rain_metallic = 0.15 * rain_int;
|
||||
rain_factor = darkness + effect * 0.15;
|
||||
}
|
||||
|
||||
//Puddles
|
||||
float puddle_factor = 0.0;
|
||||
float puddle_amt = clamp(global_rain_puddle_amount, 0.0, 1.0);
|
||||
|
||||
if (puddle_amt > 0.01 && facing_up > 0.85) {
|
||||
float puddle_mask = smoothstep(0.85, 0.95, facing_up);
|
||||
|
||||
// Large-scale distribution: sparse zones where puddles can form
|
||||
float distribution = texture(noise_texture, world_pos.xz * puddle_noise_scale * 0.15 + vec2(13.7, 7.3)).r;
|
||||
float sparse_mask = smoothstep(0.55 - puddle_amt * 0.3, 0.35 - puddle_amt * 0.2, distribution);
|
||||
|
||||
// Multi-scale noise for organic puddle shapes
|
||||
float n1 = texture(noise_texture, world_pos.xz * puddle_noise_scale).r;
|
||||
float n2 = texture(noise_texture, world_pos.xz * puddle_noise_scale * 2.7 + vec2(5.7, 3.1)).r;
|
||||
float n3 = texture(noise_texture, world_pos.xz * puddle_noise_scale * 5.3 + vec2(11.2, 8.9)).r;
|
||||
float puddle_noise = n1 * 0.5 + n2 * 0.3 + n3 * 0.2;
|
||||
|
||||
// Puddles expand as puddle_amount increases
|
||||
float threshold = puddle_threshold + (1.0 - puddle_amt) * 0.35;
|
||||
float puddle_shape = smoothstep(threshold, threshold - 0.08, puddle_noise);
|
||||
puddle_factor = puddle_shape * sparse_mask * puddle_mask * puddle_amt;
|
||||
|
||||
// Ripples inside puddles
|
||||
if (puddle_factor > 0.1 && rain_int > 0.01) {
|
||||
float puddle_ripple = 0.0;
|
||||
for (float i = 0.0; i < 2.0; i += 1.0) {
|
||||
float phase = i * 3.14;
|
||||
vec2 r_uv = fract(world_pos.xz * ripple_scale * 0.8 + vec2(phase * 0.7)) - 0.5;
|
||||
puddle_ripple += ripple_ring(r_uv, phase * 2.3);
|
||||
}
|
||||
puddle_ripple *= 0.5 * rain_int;
|
||||
|
||||
vec2 p_normal_offset = vec2(dFdx(puddle_ripple), dFdy(puddle_ripple)) * 0.6;
|
||||
rain_normal = vec3(p_normal_offset.x + 0.5, p_normal_offset.y + 0.5, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
//Combine
|
||||
//Puddles override rain when stronger
|
||||
if (puddle_factor > rain_factor) {
|
||||
rain_albedo = vec3(0.01, 0.01, 0.02);
|
||||
rain_rough = 0.02;
|
||||
rain_metallic = 0.5 * puddle_amt;
|
||||
rain_factor = puddle_factor;
|
||||
}
|
||||
|
||||
// ===================== COMBINE =====================
|
||||
if (snow_factor > rain_factor) {
|
||||
ALBEDO = snow_albedo;
|
||||
ROUGHNESS = snow_rough;
|
||||
|
||||
@@ -1,21 +1,7 @@
|
||||
[gd_resource type="ShaderMaterial" format=3]
|
||||
[gd_resource type="ShaderMaterial" format=3 uid="uid://cn5vw7unbqgve"]
|
||||
|
||||
[ext_resource type="Shader" path="res://core/daynight/weather_overlay.gdshader" id="1_weather"]
|
||||
[ext_resource type="NoiseTexture2D" uid="uid://bpswbjh4jj1ou" path="res://core/daynight/noise.tres" id="2_noise"]
|
||||
[ext_resource type="Shader" uid="uid://dh3j2jp6defuk" path="res://core/daynight/weather_overlay.gdshader" id="1_weather"]
|
||||
|
||||
[resource]
|
||||
render_priority = 0
|
||||
shader = ExtResource("1_weather")
|
||||
shader_parameter/noise_texture = ExtResource("2_noise")
|
||||
shader_parameter/snow_noise_scale = 0.15
|
||||
shader_parameter/snow_edge_softness = 0.2
|
||||
shader_parameter/snow_roughness_variation = 0.15
|
||||
shader_parameter/snow_color_variation = 0.05
|
||||
shader_parameter/ripple_scale = 1.5
|
||||
shader_parameter/ripple_speed = 2.0
|
||||
shader_parameter/ripple_layers = 3.0
|
||||
shader_parameter/streak_scale = 2.0
|
||||
shader_parameter/streak_speed = 0.8
|
||||
shader_parameter/wetness_darkening = 0.25
|
||||
shader_parameter/wet_roughness = 0.05
|
||||
shader_parameter/rain_normal_strength = 0.4
|
||||
|
||||
@@ -73,6 +73,8 @@ extends Resource
|
||||
@export_group("Rain")
|
||||
@export var rain_mode_color: Color = Color(0.5, 0.6, 0.7, 1.0)
|
||||
@export var rain_fade_time: float = 5.0
|
||||
@export var puddle_form_time: float = 15.0
|
||||
@export var puddle_dry_time: float = 20.0
|
||||
|
||||
@export_group("Lightning and Thunders")
|
||||
@export var lightning_min_time: float = 5.0
|
||||
|
||||
@@ -103,3 +103,7 @@ global_rain_intensity={
|
||||
"type": "float",
|
||||
"value": 0.0
|
||||
}
|
||||
global_rain_puddle_amount={
|
||||
"type": "float",
|
||||
"value": 0.0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user