From ffaa2ac37c83b834216a56a042a6c17672540c5d Mon Sep 17 00:00:00 2001 From: Voyager Date: Mon, 3 Aug 2026 16:36:34 -0400 Subject: [PATCH] Keep fog local to world geometry --- tests/world_time_validation.gd | 55 ++++++++++ world/materials/stylized_water.gdshader | 17 +--- world/materials/stylized_water.tres | 6 +- world/materials/stylized_water_fresh.tres | 2 + world/world_time_visual_controller.gd | 117 ++++++++-------------- 5 files changed, 107 insertions(+), 90 deletions(-) diff --git a/tests/world_time_validation.gd b/tests/world_time_validation.gd index 4c25619..1fed6e7 100644 --- a/tests/world_time_validation.gd +++ b/tests/world_time_validation.gd @@ -17,6 +17,12 @@ const FishableWaterRegionType = preload( const WeatherIconType = preload("res://ui/weather_icon.gd") const Catalog: FishPoolType = preload("res://fish/pools/fish_catalog.tres") +const SaltWaterMaterial: ShaderMaterial = preload( + "res://world/materials/stylized_water.tres" +) +const FreshWaterMaterial: ShaderMaterial = preload( + "res://world/materials/stylized_water_fresh.tres" +) func _initialize() -> void: @@ -243,6 +249,14 @@ func _validate_environment_presentation() -> void: < 0.01 ) var day_ambient_energy: float = runtime_environment.ambient_light_energy + var day_water_brightness := float( + SaltWaterMaterial.get_shader_parameter("environment_brightness") + ) + assert(day_water_brightness > 0.99) + assert(is_equal_approx( + float(FreshWaterMaterial.get_shader_parameter("environment_brightness")), + day_water_brightness, + )) visuals.apply_time_immediately(0.0) var night_horizon: Color = runtime_sky_material.get_shader_parameter( "sky_horizon_color" @@ -265,6 +279,47 @@ func _validate_environment_presentation() -> void: assert(night_moon_direction.y > 0.85) assert(night_moon_direction.is_equal_approx(-night_sun_direction)) assert(runtime_environment.ambient_light_energy < day_ambient_energy) + var night_water_brightness := float( + SaltWaterMaterial.get_shader_parameter("environment_brightness") + ) + assert(night_water_brightness < day_water_brightness * 0.4) + assert(is_equal_approx( + float(FreshWaterMaterial.get_shader_parameter("environment_brightness")), + night_water_brightness, + )) + var night_water_tint := ( + SaltWaterMaterial.get_shader_parameter("environment_tint") as Color + ) + assert(night_water_tint.get_luminance() < 0.5) + var night_background_energy := runtime_environment.background_energy_multiplier + var night_adjustment_brightness := runtime_environment.adjustment_brightness + var night_adjustment_saturation := runtime_environment.adjustment_saturation + visuals.apply_weather_immediately(WorldWeatherService.Weather.FOGGY) + visuals.apply_time_immediately(0.0) + var foggy_sky_horizon := ( + runtime_sky_material.get_shader_parameter("sky_horizon_color") as Color + ) + assert(foggy_sky_horizon.is_equal_approx(night_horizon)) + assert(is_zero_approx(runtime_environment.fog_sky_affect)) + assert(is_equal_approx(runtime_environment.fog_depth_begin, 3.0)) + assert(is_equal_approx(runtime_environment.fog_depth_end, 28.0)) + assert(is_equal_approx( + float(SaltWaterMaterial.get_shader_parameter("environment_brightness")), + night_water_brightness, + )) + assert(is_equal_approx( + runtime_environment.background_energy_multiplier, + night_background_energy, + )) + assert(is_equal_approx( + runtime_environment.adjustment_brightness, + night_adjustment_brightness, + )) + assert(is_equal_approx( + runtime_environment.adjustment_saturation, + night_adjustment_saturation, + )) + visuals.apply_weather_immediately(WorldWeatherService.Weather.SUNNY) visuals.apply_time_immediately(20.0) var dusk_horizon: Color = runtime_sky_material.get_shader_parameter( "sky_horizon_color" diff --git a/world/materials/stylized_water.gdshader b/world/materials/stylized_water.gdshader index 7643c02..0bc45e1 100644 --- a/world/materials/stylized_water.gdshader +++ b/world/materials/stylized_water.gdshader @@ -1,5 +1,5 @@ shader_type spatial; -render_mode blend_mix, depth_draw_never, cull_back, unshaded; +render_mode blend_mix, depth_draw_never, cull_back, unshaded, fog_disabled; uniform sampler2D depth_texture : hint_depth_texture, repeat_disable, filter_nearest; @@ -35,10 +35,8 @@ uniform float open_water_drift_strength : hint_range(0.0, 0.08, 0.001) = 0.045; uniform float distant_alpha_start : hint_range(10.0, 2000.0, 1.0) = 260.0; uniform float distant_alpha_end : hint_range(20.0, 5000.0, 1.0) = 1400.0; -uniform vec4 distant_fog_color : source_color = vec4(0.549, 0.749, 0.765, 1.0); -uniform float distant_fog_begin : hint_range(0.0, 2000.0, 1.0) = 42.0; -uniform float distant_fog_end : hint_range(1.0, 5000.0, 1.0) = 170.0; -uniform float distant_fog_strength : hint_range(0.0, 1.0, 0.01) = 0.18; +uniform vec4 environment_tint : source_color = vec4(1.0); +uniform float environment_brightness : hint_range(0.1, 1.2, 0.01) = 1.0; varying vec3 world_position; varying float surface_view_depth; @@ -237,14 +235,7 @@ void fragment() { water_color = mix(water_color, deep_color.rgb, distant_mix * 0.72); water_alpha = mix(water_alpha, 0.96, distant_mix); - float fog_distance_mix = smoothstep( - distant_fog_begin, - max(distant_fog_end, distant_fog_begin + 1.0), - surface_view_depth - ); - float water_fog_mix = fog_distance_mix * distant_fog_strength; - water_color = mix(water_color, distant_fog_color.rgb, water_fog_mix); - water_alpha = mix(water_alpha, 0.96, water_fog_mix); + water_color *= environment_tint.rgb * environment_brightness; ALBEDO = water_color; ALPHA = clamp(water_alpha, 0.1, 0.96); diff --git a/world/materials/stylized_water.tres b/world/materials/stylized_water.tres index 9cec671..100c598 100644 --- a/world/materials/stylized_water.tres +++ b/world/materials/stylized_water.tres @@ -32,7 +32,5 @@ shader_parameter/open_water_drift_speed = Vector2(0.01, -0.007) shader_parameter/open_water_drift_strength = 0.045 shader_parameter/distant_alpha_start = 260.0 shader_parameter/distant_alpha_end = 1400.0 -shader_parameter/distant_fog_color = Color(0.54902, 0.74902, 0.764706, 1) -shader_parameter/distant_fog_begin = 42.0 -shader_parameter/distant_fog_end = 170.0 -shader_parameter/distant_fog_strength = 0.18 +shader_parameter/environment_tint = Color(1, 1, 1, 1) +shader_parameter/environment_brightness = 1.0 diff --git a/world/materials/stylized_water_fresh.tres b/world/materials/stylized_water_fresh.tres index 66cc373..6634e2a 100644 --- a/world/materials/stylized_water_fresh.tres +++ b/world/materials/stylized_water_fresh.tres @@ -21,3 +21,5 @@ shader_parameter/open_water_drift_speed = Vector2(0.01, -0.007) shader_parameter/open_water_drift_strength = 0.045 shader_parameter/distant_alpha_start = 260.0 shader_parameter/distant_alpha_end = 1400.0 +shader_parameter/environment_tint = Color(1, 1, 1, 1) +shader_parameter/environment_brightness = 1.0 diff --git a/world/world_time_visual_controller.gd b/world/world_time_visual_controller.gd index 46cd1db..c6a9ed4 100644 --- a/world/world_time_visual_controller.gd +++ b/world/world_time_visual_controller.gd @@ -12,6 +12,9 @@ const RAIN_DROP_SIZE := Vector3(0.014, 0.34, 0.014) const SALT_WATER_MATERIAL: ShaderMaterial = preload( "res://world/materials/stylized_water.tres" ) +const FRESH_WATER_MATERIAL: ShaderMaterial = preload( + "res://world/materials/stylized_water_fresh.tres" +) const DAY_SKY_TOP := Color(0.204, 0.498, 0.643) const DAY_SKY_HORIZON := Color(0.663, 0.843, 0.847) @@ -29,6 +32,7 @@ const NIGHT_GROUND_HORIZON := Color(0.075, 0.135, 0.22) const NIGHT_AMBIENT := Color(0.28, 0.35, 0.48) const NIGHT_FOG := Color(0.13, 0.21, 0.32) const NIGHT_SUN := Color(0.35, 0.44, 0.62) +const NIGHT_WATER_TINT := Color(0.34, 0.48, 0.58) const WARM_SKY_TOP := Color(0.31, 0.30, 0.42) const WARM_SKY_HORIZON := Color(0.96, 0.48, 0.22) @@ -37,13 +41,10 @@ const WARM_GROUND_HORIZON := Color(0.82, 0.34, 0.18) const WARM_AMBIENT := Color(0.92, 0.58, 0.40) const WARM_FOG := Color(0.74, 0.39, 0.27) const WARM_SUN := Color(1.0, 0.58, 0.30) +const WARM_WATER_TINT := Color(0.78, 0.62, 0.58) const WARM_SUN_DISC := Color(1.0, 0.45, 0.16) const MOON_DISC := Color(0.78, 0.88, 1.0) -const CLOUDY_TINT := Color(0.53, 0.61, 0.66) -const RAINY_TINT := Color(0.31, 0.42, 0.50) -const FOGGY_TINT := Color(0.62, 0.70, 0.72) - var _time_service: WorldTimeService var _weather_service: WorldWeatherService var _world_environment: WorldEnvironment @@ -219,45 +220,31 @@ func _apply_time(time_hours: float) -> void: var fog_color: Color = _blended_color( NIGHT_FOG, DAY_FOG, WARM_FOG, daylight, warmth ) - var weather_tint: Color = _weather_color() - var tint_strength: float = _weather_value( - 0.0, 0.30, 0.48, 0.62 + _sky_material.set_shader_parameter( + "sky_top_color", sky_top ) _sky_material.set_shader_parameter( - "sky_top_color", sky_top.lerp(weather_tint, tint_strength) - ) - _sky_material.set_shader_parameter( - "sky_horizon_color", sky_horizon.lerp(weather_tint, tint_strength) + "sky_horizon_color", + sky_horizon, ) _sky_material.set_shader_parameter( "ground_bottom_color", - ground_bottom.lerp(weather_tint, tint_strength * 0.62), + ground_bottom, ) _sky_material.set_shader_parameter( "ground_horizon_color", - ground_horizon.lerp( - weather_tint, - tint_strength * _weather_value(0.76, 0.82, 0.90, 1.0), - ), - ) - _sky_material.set_shader_parameter( - "horizon_blend_width", - _weather_value(0.01, 0.025, 0.035, 0.08), + ground_horizon, ) _environment.background_energy_multiplier = ( lerpf(0.52, 0.85, daylight) - * _weather_value(1.0, 0.82, 0.66, 0.74) - ) - _environment.ambient_light_color = ambient.lerp( - weather_tint, tint_strength * 0.45 + * _weather_value(1.0, 0.82, 0.66, 1.0) ) + _environment.ambient_light_color = ambient _environment.ambient_light_energy = ( lerpf(0.66, 1.08, daylight) * _weather_value(1.0, 0.88, 0.76, 0.82) ) - _environment.fog_light_color = fog_color.lerp( - weather_tint, tint_strength * 0.82 - ) + _environment.fog_light_color = fog_color _environment.fog_light_energy = ( lerpf(0.56, 0.82, daylight) * _weather_value(1.0, 0.92, 0.82, 1.05) @@ -265,26 +252,24 @@ func _apply_time(time_hours: float) -> void: _environment.fog_aerial_perspective = _weather_value( 0.35, 0.48, 0.62, 0.92 ) - _environment.fog_sky_affect = _weather_value( - 0.35, 0.48, 0.68, 0.94 - ) + _environment.fog_sky_affect = 0.0 _environment.fog_depth_curve = _weather_value( 1.6, 1.5, 1.4, 1.18 ) _environment.fog_depth_begin = _weather_value( - 42.0, 32.0, 20.0, 4.0 + 42.0, 32.0, 20.0, 3.0 ) _environment.fog_depth_end = _weather_value( - 170.0, 140.0, 95.0, 42.0 + 170.0, 140.0, 95.0, 28.0 ) - _apply_water_haze(weather_tint) + _apply_water_environment(daylight, warmth) _environment.adjustment_brightness = ( lerpf(0.93, 0.98, daylight) - * _weather_value(1.0, 0.97, 0.92, 0.96) + * _weather_value(1.0, 0.97, 0.92, 1.0) ) _environment.adjustment_saturation = ( lerpf(0.82, 0.91, daylight) - * _weather_value(1.0, 0.88, 0.78, 0.70) + * _weather_value(1.0, 0.88, 0.78, 1.0) ) _sun.rotation_degrees = Vector3( -360.0 * fposmod(hour - WorldTimeService.DAY_START_HOUR, 24.0) / 24.0, @@ -299,7 +284,7 @@ func _apply_time(time_hours: float) -> void: ) _sky_material.set_shader_parameter( "sun_visibility", - daylight * _weather_value(1.0, 0.65, 0.28, 0.15), + daylight * _weather_value(1.0, 0.65, 0.28, 1.0), ) _sky_material.set_shader_parameter( "moon_direction", -_sun.global_transform.basis.z.normalized() @@ -307,7 +292,7 @@ func _apply_time(time_hours: float) -> void: _sky_material.set_shader_parameter("moon_color", MOON_DISC) _sky_material.set_shader_parameter( "moon_visibility", - (1.0 - daylight) * _weather_value(1.0, 0.72, 0.36, 0.20), + (1.0 - daylight) * _weather_value(1.0, 0.72, 0.36, 1.0), ) _sun.light_color = _blended_color( NIGHT_SUN, DAY_SUN, WARM_SUN, daylight, warmth @@ -319,25 +304,30 @@ func _apply_time(time_hours: float) -> void: _update_rain_amount() -func _apply_water_haze(weather_tint: Color) -> void: - if SALT_WATER_MATERIAL == null: - return - SALT_WATER_MATERIAL.set_shader_parameter( - "distant_fog_color", - _environment.fog_light_color.lerp(weather_tint, 0.18), +func _apply_water_environment( + daylight: float, + warmth: float, +) -> void: + var water_tint := _blended_color( + NIGHT_WATER_TINT, + Color.WHITE, + WARM_WATER_TINT, + daylight, + warmth, ) - SALT_WATER_MATERIAL.set_shader_parameter( - "distant_fog_begin", - _environment.fog_depth_begin, - ) - SALT_WATER_MATERIAL.set_shader_parameter( - "distant_fog_end", - _environment.fog_depth_end, - ) - SALT_WATER_MATERIAL.set_shader_parameter( - "distant_fog_strength", - _weather_value(0.18, 0.34, 0.52, 0.74), + var water_brightness := ( + lerpf(0.34, 1.0, daylight) + * _weather_value(1.0, 0.90, 0.78, 1.0) ) + for material: ShaderMaterial in [ + SALT_WATER_MATERIAL, + FRESH_WATER_MATERIAL, + ]: + material.set_shader_parameter("environment_tint", water_tint) + material.set_shader_parameter( + "environment_brightness", + water_brightness, + ) func _on_weather_changed( @@ -381,25 +371,6 @@ func _weather_state_value( return sunny -func _weather_color() -> Color: - return _weather_state_color(_weather_from).lerp( - _weather_state_color(_weather_to), _weather_transition - ) - - -func _weather_state_color( - weather: WorldWeatherService.Weather, -) -> Color: - match weather: - WorldWeatherService.Weather.CLOUDY: - return CLOUDY_TINT - WorldWeatherService.Weather.RAINY: - return RAINY_TINT - WorldWeatherService.Weather.FOGGY: - return FOGGY_TINT - return Color.WHITE - - func _update_rain_amount() -> void: if _rain == null: return