Unify foggy water presentation and remove shoreline ribbons

This commit is contained in:
Alexander Sellite 2026-08-13 16:25:43 -04:00
parent 3576daba16
commit 405bdaa2d2
8 changed files with 209 additions and 10 deletions

View file

@ -313,7 +313,12 @@ func _validate_starter_water_bodies() -> void:
assert(pond.fish_pool == PondPool) assert(pond.fish_pool == PondPool)
assert(ocean.fish_pool == OceanPool) assert(ocean.fish_pool == OceanPool)
assert(region.get_node_or_null("ShorelineRibbons/Pond") == null) assert(region.get_node_or_null("ShorelineRibbons/Pond") == null)
assert(region.get_node_or_null("ShorelineRibbons/Ocean") != null) var shoreline_geometry := (
region.get_node_or_null("ShorelineRibbons/Ocean") as MeshInstance3D
)
assert(shoreline_geometry != null)
assert(not shoreline_geometry.visible)
assert(shoreline_geometry.material_override == null)
var pond_material := ( var pond_material := (
region.get_node("WaterBodies/Pond/VisualWater") as MeshInstance3D region.get_node("WaterBodies/Pond/VisualWater") as MeshInstance3D
).material_override as ShaderMaterial ).material_override as ShaderMaterial

View file

@ -23,8 +23,6 @@ const SaltWaterMaterial: ShaderMaterial = preload(
const FreshWaterMaterial: ShaderMaterial = preload( const FreshWaterMaterial: ShaderMaterial = preload(
"res://world/materials/stylized_water_fresh.tres" "res://world/materials/stylized_water_fresh.tres"
) )
func _initialize() -> void: func _initialize() -> void:
call_deferred("_run") call_deferred("_run")
@ -254,10 +252,28 @@ func _validate_environment_presentation() -> void:
var water_shader: Shader = preload( var water_shader: Shader = preload(
"res://world/materials/stylized_water.gdshader" "res://world/materials/stylized_water.gdshader"
) )
var sky_shader: Shader = preload(
"res://world/environment/netfishing_sky.gdshader"
)
assert("uniform float fog_horizon_occlusion" in sky_shader.code)
assert("fog_horizon_color.rgb" in sky_shader.code)
assert("fog_disabled" in water_shader.code) assert("fog_disabled" in water_shader.code)
assert("surface_view_position = view_vertex.xyz" in water_shader.code)
assert("surface_view_distance = length(surface_view_position)" in water_shader.code)
assert(
"max(weather_fog_end, weather_fog_begin + 1.0),\n"
+ "\t\tsurface_view_distance"
in water_shader.code
)
assert("weather_fog_near_amount" in water_shader.code)
assert("float weather_fog_alpha = mix(" in water_shader.code)
assert("ALPHA = clamp(water_alpha, 0.1, weather_fog_alpha)" in water_shader.code)
assert(is_zero_approx(float( assert(is_zero_approx(float(
SaltWaterMaterial.get_shader_parameter("weather_fog_amount") SaltWaterMaterial.get_shader_parameter("weather_fog_amount")
))) )))
assert(is_equal_approx(float(
SaltWaterMaterial.get_shader_parameter("surface_highlight_night_floor")
), WorldTimeVisualController.DEFAULT_SURFACE_HIGHLIGHT_FLOOR))
var day_water_brightness := float( var day_water_brightness := float(
SaltWaterMaterial.get_shader_parameter("environment_brightness") SaltWaterMaterial.get_shader_parameter("environment_brightness")
) )
@ -288,6 +304,9 @@ func _validate_environment_presentation() -> void:
assert(night_moon_direction.y > 0.85) assert(night_moon_direction.y > 0.85)
assert(night_moon_direction.is_equal_approx(-night_sun_direction)) assert(night_moon_direction.is_equal_approx(-night_sun_direction))
assert(runtime_environment.ambient_light_energy < day_ambient_energy) assert(runtime_environment.ambient_light_energy < day_ambient_energy)
assert(is_zero_approx(float(
runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
)))
var night_water_brightness := float( var night_water_brightness := float(
SaltWaterMaterial.get_shader_parameter("environment_brightness") SaltWaterMaterial.get_shader_parameter("environment_brightness")
) )
@ -311,6 +330,18 @@ func _validate_environment_presentation() -> void:
assert(float( assert(float(
SaltWaterMaterial.get_shader_parameter("weather_fog_amount") SaltWaterMaterial.get_shader_parameter("weather_fog_amount")
) > 0.99) ) > 0.99)
assert(is_equal_approx(float(
SaltWaterMaterial.get_shader_parameter("weather_fog_near_amount")
), WorldTimeVisualController.FOGGY_NIGHT_WATER_NEAR_FOG_AMOUNT))
assert(is_equal_approx(float(
SaltWaterMaterial.get_shader_parameter("surface_highlight_night_floor")
), WorldTimeVisualController.FOGGY_NIGHT_SURFACE_HIGHLIGHT_FLOOR))
assert(is_equal_approx(float(
runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
), 1.0))
assert((
runtime_sky_material.get_shader_parameter("fog_horizon_color") as Color
).is_equal_approx(WorldTimeVisualController.NIGHT_FOG))
var night_rendered_fog_color := ( var night_rendered_fog_color := (
runtime_environment.fog_light_color.srgb_to_linear() runtime_environment.fog_light_color.srgb_to_linear()
) )
@ -322,7 +353,17 @@ func _validate_environment_presentation() -> void:
var night_water_fog_color := ( var night_water_fog_color := (
SaltWaterMaterial.get_shader_parameter("weather_fog_color") as Color SaltWaterMaterial.get_shader_parameter("weather_fog_color") as Color
) )
assert(night_water_fog_color.is_equal_approx(night_rendered_fog_color)) var corrected_night_fog_color := night_rendered_fog_color
corrected_night_fog_color.r *= (
WorldTimeVisualController.FOGGY_DARK_WATER_FOG_CORRECTION.r
)
corrected_night_fog_color.g *= (
WorldTimeVisualController.FOGGY_DARK_WATER_FOG_CORRECTION.g
)
corrected_night_fog_color.b *= (
WorldTimeVisualController.FOGGY_DARK_WATER_FOG_CORRECTION.b
)
assert(night_water_fog_color.is_equal_approx(corrected_night_fog_color))
var foggy_sky_horizon := ( var foggy_sky_horizon := (
runtime_sky_material.get_shader_parameter("sky_horizon_color") as Color runtime_sky_material.get_shader_parameter("sky_horizon_color") as Color
) )
@ -355,12 +396,35 @@ func _validate_environment_presentation() -> void:
runtime_environment.adjustment_saturation, runtime_environment.adjustment_saturation,
night_adjustment_saturation, night_adjustment_saturation,
)) ))
visuals.apply_time_immediately(8.0)
assert(is_equal_approx(float(
SaltWaterMaterial.get_shader_parameter("weather_fog_near_amount")
), WorldTimeVisualController.FOGGY_NIGHT_WATER_NEAR_FOG_AMOUNT))
assert(is_equal_approx(float(
runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
), 1.0))
visuals.apply_time_immediately(20.0)
assert(is_zero_approx(float(
SaltWaterMaterial.get_shader_parameter("weather_fog_near_amount")
)))
assert(is_zero_approx(float(
runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
)))
visuals.apply_weather_immediately(WorldWeatherService.Weather.SUNNY) visuals.apply_weather_immediately(WorldWeatherService.Weather.SUNNY)
visuals.apply_time_immediately(20.0) visuals.apply_time_immediately(20.0)
assert(not runtime_environment.fog_enabled) assert(not runtime_environment.fog_enabled)
assert(is_zero_approx(float( assert(is_zero_approx(float(
SaltWaterMaterial.get_shader_parameter("weather_fog_amount") SaltWaterMaterial.get_shader_parameter("weather_fog_amount")
))) )))
assert(is_zero_approx(float(
SaltWaterMaterial.get_shader_parameter("weather_fog_near_amount")
)))
assert(is_equal_approx(float(
SaltWaterMaterial.get_shader_parameter("surface_highlight_night_floor")
), WorldTimeVisualController.DEFAULT_SURFACE_HIGHLIGHT_FLOOR))
assert(is_zero_approx(float(
runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
)))
var dusk_horizon: Color = runtime_sky_material.get_shader_parameter( var dusk_horizon: Color = runtime_sky_material.get_shader_parameter(
"sky_horizon_color" "sky_horizon_color"
) as Color ) as Color

View file

@ -330,6 +330,11 @@ func _validate_weather_presentation() -> void:
"weather_fog_amount" "weather_fog_amount"
) )
) > 0.99) ) > 0.99)
assert(is_zero_approx(float(
WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
"weather_fog_near_amount"
)
)))
var water_fog_color := ( var water_fog_color := (
WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter( WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
"weather_fog_color" "weather_fog_color"
@ -344,6 +349,11 @@ func _validate_weather_presentation() -> void:
rendered_fog_color.a = 1.0 rendered_fog_color.a = 1.0
rendered_fog_color = rendered_fog_color.linear_to_srgb() rendered_fog_color = rendered_fog_color.linear_to_srgb()
assert(water_fog_color.is_equal_approx(rendered_fog_color)) assert(water_fog_color.is_equal_approx(rendered_fog_color))
assert(is_equal_approx(float(
WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
"surface_highlight_night_floor"
)
), WorldTimeVisualControllerType.DEFAULT_SURFACE_HIGHLIGHT_FLOOR))
assert(runtime_environment.fog_depth_begin <= 4.01) assert(runtime_environment.fog_depth_begin <= 4.01)
assert(is_equal_approx(runtime_environment.fog_depth_end, 18.0)) assert(is_equal_approx(runtime_environment.fog_depth_end, 18.0))
assert(is_equal_approx(runtime_environment.fog_sky_affect, 1.0)) assert(is_equal_approx(runtime_environment.fog_sky_affect, 1.0))
@ -394,6 +404,11 @@ func _validate_weather_presentation() -> void:
"weather_fog_amount" "weather_fog_amount"
) )
) > 0.99) ) > 0.99)
assert(is_zero_approx(float(
WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
"weather_fog_near_amount"
)
)))
var rainy_water_fog_color := ( var rainy_water_fog_color := (
WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter( WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
"weather_fog_color" "weather_fog_color"
@ -404,6 +419,11 @@ func _validate_weather_presentation() -> void:
WorldTimeVisualControllerType.RAIN_WATER_FOG_COLOR WorldTimeVisualControllerType.RAIN_WATER_FOG_COLOR
) )
) )
assert(is_equal_approx(float(
WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
"surface_highlight_night_floor"
)
), WorldTimeVisualControllerType.DEFAULT_SURFACE_HIGHLIGHT_FLOOR))
assert(is_equal_approx(runtime_environment.fog_sky_affect, 0.68)) assert(is_equal_approx(runtime_environment.fog_sky_affect, 0.68))
assert( assert(
float(runtime_sky_material.get_shader_parameter("cloud_coverage")) float(runtime_sky_material.get_shader_parameter("cloud_coverage"))

View file

@ -7,6 +7,8 @@ uniform vec4 sky_horizon_color : source_color = vec4(0.663, 0.843, 0.847, 1.0);
uniform vec4 ground_bottom_color : source_color = vec4(0.157, 0.361, 0.439, 1.0); uniform vec4 ground_bottom_color : source_color = vec4(0.157, 0.361, 0.439, 1.0);
uniform vec4 ground_horizon_color : source_color = vec4(0.549, 0.749, 0.765, 1.0); uniform vec4 ground_horizon_color : source_color = vec4(0.549, 0.749, 0.765, 1.0);
uniform float horizon_blend_width : hint_range(0.005, 0.15, 0.005) = 0.01; uniform float horizon_blend_width : hint_range(0.005, 0.15, 0.005) = 0.01;
uniform vec4 fog_horizon_color : source_color = vec4(0.13, 0.21, 0.32, 1.0);
uniform float fog_horizon_occlusion : hint_range(0.0, 1.0) = 0.0;
uniform vec3 sun_direction = vec3(0.0, 1.0, 0.0); uniform vec3 sun_direction = vec3(0.0, 1.0, 0.0);
uniform vec4 sun_color : source_color = vec4(1.0, 0.86, 0.46, 1.0); uniform vec4 sun_color : source_color = vec4(1.0, 0.86, 0.46, 1.0);
@ -86,6 +88,14 @@ void sky() {
base_color, moon_color.rgb, moon_disc * moon_visible_strength base_color, moon_color.rgb, moon_disc * moon_visible_strength
); );
base_color = apply_weather_clouds(base_color, view_direction); base_color = apply_weather_clouds(base_color, view_direction);
// Compatibility fog does not fully erase the color split between a custom
// sky's upper and lower hemispheres. Dense low-light fog supplies one
// uniform sky color here so that split cannot masquerade as an ocean edge.
base_color = mix(
base_color,
fog_horizon_color.rgb,
fog_horizon_occlusion
);
COLOR = base_color; COLOR = base_color;
} }

View file

@ -15,6 +15,8 @@ shader_parameter/sky_horizon_color = Color(0.663, 0.843, 0.847, 1)
shader_parameter/ground_bottom_color = Color(0.157, 0.361, 0.439, 1) shader_parameter/ground_bottom_color = Color(0.157, 0.361, 0.439, 1)
shader_parameter/ground_horizon_color = Color(0.549, 0.749, 0.765, 1) shader_parameter/ground_horizon_color = Color(0.549, 0.749, 0.765, 1)
shader_parameter/horizon_blend_width = 0.01 shader_parameter/horizon_blend_width = 0.01
shader_parameter/fog_horizon_color = Color(0.13, 0.21, 0.32, 1)
shader_parameter/fog_horizon_occlusion = 0.0
shader_parameter/sun_direction = Vector3(0, 1, 0) shader_parameter/sun_direction = Vector3(0, 1, 0)
shader_parameter/sun_color = Color(1, 0.86, 0.46, 1) shader_parameter/sun_color = Color(1, 0.86, 0.46, 1)
shader_parameter/sun_visibility = 1.0 shader_parameter/sun_visibility = 1.0

View file

@ -56,12 +56,14 @@ uniform vec4 environment_tint : source_color = vec4(1.0);
uniform float environment_brightness : hint_range(0.1, 1.2, 0.01) = 1.0; uniform float environment_brightness : hint_range(0.1, 1.2, 0.01) = 1.0;
uniform vec4 weather_fog_color : source_color = vec4(0.025, 0.038, 0.045, 1.0); uniform vec4 weather_fog_color : source_color = vec4(0.025, 0.038, 0.045, 1.0);
uniform float weather_fog_amount : hint_range(0.0, 1.0, 0.01) = 0.0; uniform float weather_fog_amount : hint_range(0.0, 1.0, 0.01) = 0.0;
uniform float weather_fog_near_amount : hint_range(0.0, 1.0, 0.01) = 0.0;
uniform float weather_fog_begin : hint_range(0.0, 500.0, 0.5) = 20.0; uniform float weather_fog_begin : hint_range(0.0, 500.0, 0.5) = 20.0;
uniform float weather_fog_end : hint_range(1.0, 1000.0, 0.5) = 95.0; uniform float weather_fog_end : hint_range(1.0, 1000.0, 0.5) = 95.0;
uniform float weather_fog_curve : hint_range(0.1, 4.0, 0.01) = 1.4; uniform float weather_fog_curve : hint_range(0.1, 4.0, 0.01) = 1.4;
varying vec3 world_position; varying vec3 world_position;
varying float surface_view_depth; varying float surface_view_depth;
varying vec3 surface_view_position;
float hash_21(vec2 point) { float hash_21(vec2 point) {
@ -208,6 +210,12 @@ void vertex() {
vec4 view_vertex = VIEW_MATRIX * world_vertex; vec4 view_vertex = VIEW_MATRIX * world_vertex;
world_position = world_vertex.xyz; world_position = world_vertex.xyz;
surface_view_depth = -view_vertex.z; surface_view_depth = -view_vertex.z;
// Godot's depth fog measures radial view-space distance. Keep the existing
// forward depth for distant-water presentation, but pass the linear view
// position so weather fog can derive the same per-fragment radial metric as
// opaque world geometry. Calculating length here would interpolate four
// corner distances across the oversized ocean plane and over-fog its center.
surface_view_position = view_vertex.xyz;
} }
@ -549,25 +557,35 @@ void fragment() {
visible_highlight_color, visible_highlight_color,
clamp(visible_highlight, 0.0, 1.0) clamp(visible_highlight, 0.0, 1.0)
); );
float surface_view_distance = length(surface_view_position);
float weather_fog_distance = smoothstep( float weather_fog_distance = smoothstep(
weather_fog_begin, weather_fog_begin,
max(weather_fog_end, weather_fog_begin + 1.0), max(weather_fog_end, weather_fog_begin + 1.0),
surface_view_depth surface_view_distance
); );
weather_fog_distance = pow( weather_fog_distance = pow(
clamp(weather_fog_distance, 0.0, 1.0), clamp(weather_fog_distance, 0.0, 1.0),
weather_fog_curve weather_fog_curve
); );
float weather_fog_mix = weather_fog_amount * weather_fog_distance; float distance_fog_mix = weather_fog_amount * weather_fog_distance;
float weather_fog_mix = 1.0 - (
(1.0 - weather_fog_near_amount)
* (1.0 - distance_fog_mix)
);
water_color = mix( water_color = mix(
water_color, water_color,
weather_fog_color.rgb, weather_fog_color.rgb,
weather_fog_mix weather_fog_mix
); );
water_alpha = mix(water_alpha, 0.96, weather_fog_mix); float weather_fog_alpha = mix(
0.96,
1.0,
weather_fog_near_amount
);
water_alpha = mix(water_alpha, weather_fog_alpha, weather_fog_mix);
ALBEDO = water_color; ALBEDO = water_color;
ALPHA = clamp(water_alpha, 0.1, 0.96); ALPHA = clamp(water_alpha, 0.1, weather_fog_alpha);
METALLIC = 0.0; METALLIC = 0.0;
SPECULAR = 0.0; SPECULAR = 0.0;
ROUGHNESS = 1.0; ROUGHNESS = 1.0;

File diff suppressed because one or more lines are too long

View file

@ -14,6 +14,11 @@ const FOG_DAYLIGHT_FOG_LIGHT_BRIGHTNESS: float = 0.42
const FOG_DAYLIGHT_WATER_BRIGHTNESS: float = 0.42 const FOG_DAYLIGHT_WATER_BRIGHTNESS: float = 0.42
const FOG_DAYLIGHT_POST_BRIGHTNESS: float = 0.50 const FOG_DAYLIGHT_POST_BRIGHTNESS: float = 0.50
const RAIN_DAYLIGHT_POST_BRIGHTNESS: float = 0.52 const RAIN_DAYLIGHT_POST_BRIGHTNESS: float = 0.52
const DEFAULT_SURFACE_HIGHLIGHT_FLOOR: float = 0.72
const FOGGY_NIGHT_SURFACE_HIGHLIGHT_FLOOR: float = 0.25
const FOGGY_NIGHT_WATER_NEAR_FOG_AMOUNT: float = 1.0
const FOGGY_DARK_WATER_FOG_CORRECTION := Color(1.15, 1.025, 1.0, 1.0)
const FOGGY_BRIGHT_WATER_FOG_CORRECTION := Color(0.99, 1.005, 1.01, 1.0)
const RAIN_WATER_FOG_COLOR := Color(0.025, 0.038, 0.045) const RAIN_WATER_FOG_COLOR := Color(0.025, 0.038, 0.045)
const SALT_WATER_MATERIAL: ShaderMaterial = preload( const SALT_WATER_MATERIAL: ShaderMaterial = preload(
"res://world/materials/stylized_water.tres" "res://world/materials/stylized_water.tres"
@ -259,6 +264,7 @@ func _apply_time(time_hours: float) -> void:
rain_fog_amount + foggy_fog_amount, rain_fog_amount + foggy_fog_amount,
1.0, 1.0,
) )
var foggy_horizon_occlusion := _foggy_horizon_occlusion_amount(hour)
_environment.fog_enabled = weather_fog_amount > 0.001 _environment.fog_enabled = weather_fog_amount > 0.001
var fog_scene_brightness: float = lerpf( var fog_scene_brightness: float = lerpf(
1.0, 1.0,
@ -280,6 +286,11 @@ func _apply_time(time_hours: float) -> void:
"ground_horizon_color", "ground_horizon_color",
ground_horizon, ground_horizon,
) )
_sky_material.set_shader_parameter("fog_horizon_color", fog_color)
_sky_material.set_shader_parameter(
"fog_horizon_occlusion",
foggy_fog_amount * foggy_horizon_occlusion,
)
_apply_sky_clouds(daylight, warmth) _apply_sky_clouds(daylight, warmth)
_environment.background_energy_multiplier = ( _environment.background_energy_multiplier = (
lerpf(0.52, 0.85, daylight) lerpf(0.52, 0.85, daylight)
@ -323,6 +334,7 @@ func _apply_time(time_hours: float) -> void:
warmth, warmth,
rain_fog_amount, rain_fog_amount,
foggy_fog_amount, foggy_fog_amount,
foggy_horizon_occlusion,
_fog_render_color(fog_color, fog_light_energy), _fog_render_color(fog_color, fog_light_energy),
) )
_environment.adjustment_brightness = ( _environment.adjustment_brightness = (
@ -381,6 +393,7 @@ func _apply_water_environment(
warmth: float, warmth: float,
rain_fog_amount: float, rain_fog_amount: float,
foggy_fog_amount: float, foggy_fog_amount: float,
foggy_horizon_occlusion: float,
fog_render_color: Color, fog_render_color: Color,
) -> void: ) -> void:
var water_tint := _blended_color( var water_tint := _blended_color(
@ -412,6 +425,44 @@ func _apply_water_environment(
fog_render_color, fog_render_color,
foggy_color_weight, foggy_color_weight,
) )
var fog_correction_amount := (
foggy_fog_amount * foggy_horizon_occlusion
)
var bright_fog_amount := maxf(daylight, warmth)
var fog_color_correction := FOGGY_DARK_WATER_FOG_CORRECTION.lerp(
FOGGY_BRIGHT_WATER_FOG_CORRECTION,
bright_fog_amount,
)
water_fog_color.r *= lerpf(
1.0,
fog_color_correction.r,
fog_correction_amount,
)
water_fog_color.g *= lerpf(
1.0,
fog_color_correction.g,
fog_correction_amount,
)
water_fog_color.b *= lerpf(
1.0,
fog_color_correction.b,
fog_correction_amount,
)
var foggy_surface_highlight_floor := lerpf(
FOGGY_NIGHT_SURFACE_HIGHLIGHT_FLOOR,
DEFAULT_SURFACE_HIGHLIGHT_FLOOR,
daylight,
)
var surface_highlight_floor := lerpf(
DEFAULT_SURFACE_HIGHLIGHT_FLOOR,
foggy_surface_highlight_floor,
foggy_fog_amount,
)
var water_near_fog_amount := (
FOGGY_NIGHT_WATER_NEAR_FOG_AMOUNT
* foggy_fog_amount
* foggy_horizon_occlusion
)
for material: ShaderMaterial in [ for material: ShaderMaterial in [
SALT_WATER_MATERIAL, SALT_WATER_MATERIAL,
FRESH_WATER_MATERIAL, FRESH_WATER_MATERIAL,
@ -422,10 +473,18 @@ func _apply_water_environment(
water_brightness, water_brightness,
) )
material.set_shader_parameter("weather_fog_color", water_fog_color) material.set_shader_parameter("weather_fog_color", water_fog_color)
material.set_shader_parameter(
"surface_highlight_night_floor",
surface_highlight_floor,
)
material.set_shader_parameter( material.set_shader_parameter(
"weather_fog_amount", "weather_fog_amount",
weather_fog_amount, weather_fog_amount,
) )
material.set_shader_parameter(
"weather_fog_near_amount",
water_near_fog_amount,
)
material.set_shader_parameter( material.set_shader_parameter(
"weather_fog_begin", "weather_fog_begin",
_weather_value(42.0, 32.0, 20.0, 3.0), _weather_value(42.0, 32.0, 20.0, 3.0),
@ -449,6 +508,28 @@ func _fog_render_color(fog_color: Color, fog_light_energy: float) -> Color:
return linear_fog_color.linear_to_srgb() return linear_fog_color.linear_to_srgb()
func _foggy_horizon_occlusion_amount(hour: float) -> float:
# Day and dusk already blend cleanly. During night and most of dawn, make
# the manually fogged transparent water fully occluding so the dark scene
# below it cannot reintroduce a horizon band. Brief edge fades avoid a pop
# where the dawn/night phases meet their neighboring phases.
if hour >= WorldTimeService.DUSK_END_HOUR - 0.1:
return smoothstep(
WorldTimeService.DUSK_END_HOUR - 0.1,
WorldTimeService.DUSK_END_HOUR,
hour,
)
if hour < WorldTimeService.DAWN_START_HOUR:
return 1.0
if hour < WorldTimeService.DAWN_END_HOUR:
return 1.0 - smoothstep(
WorldTimeService.DAWN_END_HOUR - 0.1,
WorldTimeService.DAWN_END_HOUR,
hour,
)
return 0.0
func _apply_sky_clouds(daylight: float, warmth: float) -> void: func _apply_sky_clouds(daylight: float, warmth: float) -> void:
var cloud_light := _blended_color( var cloud_light := _blended_color(
NIGHT_CLOUD_LIGHT, NIGHT_CLOUD_LIGHT,