Keep fog local to world geometry

This commit is contained in:
Alexander Sellite 2026-08-03 16:36:34 -04:00
parent b7e5b7806c
commit ffaa2ac37c
5 changed files with 107 additions and 90 deletions

View file

@ -17,6 +17,12 @@ const FishableWaterRegionType = preload(
const WeatherIconType = preload("res://ui/weather_icon.gd") const WeatherIconType = preload("res://ui/weather_icon.gd")
const Catalog: FishPoolType = preload("res://fish/pools/fish_catalog.tres") 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: func _initialize() -> void:
@ -243,6 +249,14 @@ func _validate_environment_presentation() -> void:
< 0.01 < 0.01
) )
var day_ambient_energy: float = runtime_environment.ambient_light_energy 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) visuals.apply_time_immediately(0.0)
var night_horizon: Color = runtime_sky_material.get_shader_parameter( var night_horizon: Color = runtime_sky_material.get_shader_parameter(
"sky_horizon_color" "sky_horizon_color"
@ -265,6 +279,47 @@ 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)
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) visuals.apply_time_immediately(20.0)
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"

View file

@ -1,5 +1,5 @@
shader_type spatial; 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; 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_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 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 vec4 environment_tint : source_color = vec4(1.0);
uniform float distant_fog_begin : hint_range(0.0, 2000.0, 1.0) = 42.0; uniform float environment_brightness : hint_range(0.1, 1.2, 0.01) = 1.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;
varying vec3 world_position; varying vec3 world_position;
varying float surface_view_depth; varying float surface_view_depth;
@ -237,14 +235,7 @@ void fragment() {
water_color = mix(water_color, deep_color.rgb, distant_mix * 0.72); water_color = mix(water_color, deep_color.rgb, distant_mix * 0.72);
water_alpha = mix(water_alpha, 0.96, distant_mix); water_alpha = mix(water_alpha, 0.96, distant_mix);
float fog_distance_mix = smoothstep( water_color *= environment_tint.rgb * environment_brightness;
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);
ALBEDO = water_color; ALBEDO = water_color;
ALPHA = clamp(water_alpha, 0.1, 0.96); ALPHA = clamp(water_alpha, 0.1, 0.96);

View file

@ -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/open_water_drift_strength = 0.045
shader_parameter/distant_alpha_start = 260.0 shader_parameter/distant_alpha_start = 260.0
shader_parameter/distant_alpha_end = 1400.0 shader_parameter/distant_alpha_end = 1400.0
shader_parameter/distant_fog_color = Color(0.54902, 0.74902, 0.764706, 1) shader_parameter/environment_tint = Color(1, 1, 1, 1)
shader_parameter/distant_fog_begin = 42.0 shader_parameter/environment_brightness = 1.0
shader_parameter/distant_fog_end = 170.0
shader_parameter/distant_fog_strength = 0.18

View file

@ -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/open_water_drift_strength = 0.045
shader_parameter/distant_alpha_start = 260.0 shader_parameter/distant_alpha_start = 260.0
shader_parameter/distant_alpha_end = 1400.0 shader_parameter/distant_alpha_end = 1400.0
shader_parameter/environment_tint = Color(1, 1, 1, 1)
shader_parameter/environment_brightness = 1.0

View file

@ -12,6 +12,9 @@ const RAIN_DROP_SIZE := Vector3(0.014, 0.34, 0.014)
const SALT_WATER_MATERIAL: ShaderMaterial = preload( const SALT_WATER_MATERIAL: ShaderMaterial = preload(
"res://world/materials/stylized_water.tres" "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_TOP := Color(0.204, 0.498, 0.643)
const DAY_SKY_HORIZON := Color(0.663, 0.843, 0.847) 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_AMBIENT := Color(0.28, 0.35, 0.48)
const NIGHT_FOG := Color(0.13, 0.21, 0.32) const NIGHT_FOG := Color(0.13, 0.21, 0.32)
const NIGHT_SUN := Color(0.35, 0.44, 0.62) 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_TOP := Color(0.31, 0.30, 0.42)
const WARM_SKY_HORIZON := Color(0.96, 0.48, 0.22) 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_AMBIENT := Color(0.92, 0.58, 0.40)
const WARM_FOG := Color(0.74, 0.39, 0.27) const WARM_FOG := Color(0.74, 0.39, 0.27)
const WARM_SUN := Color(1.0, 0.58, 0.30) 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 WARM_SUN_DISC := Color(1.0, 0.45, 0.16)
const MOON_DISC := Color(0.78, 0.88, 1.0) 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 _time_service: WorldTimeService
var _weather_service: WorldWeatherService var _weather_service: WorldWeatherService
var _world_environment: WorldEnvironment var _world_environment: WorldEnvironment
@ -219,45 +220,31 @@ func _apply_time(time_hours: float) -> void:
var fog_color: Color = _blended_color( var fog_color: Color = _blended_color(
NIGHT_FOG, DAY_FOG, WARM_FOG, daylight, warmth NIGHT_FOG, DAY_FOG, WARM_FOG, daylight, warmth
) )
var weather_tint: Color = _weather_color() _sky_material.set_shader_parameter(
var tint_strength: float = _weather_value( "sky_top_color", sky_top
0.0, 0.30, 0.48, 0.62
) )
_sky_material.set_shader_parameter( _sky_material.set_shader_parameter(
"sky_top_color", sky_top.lerp(weather_tint, tint_strength) "sky_horizon_color",
) sky_horizon,
_sky_material.set_shader_parameter(
"sky_horizon_color", sky_horizon.lerp(weather_tint, tint_strength)
) )
_sky_material.set_shader_parameter( _sky_material.set_shader_parameter(
"ground_bottom_color", "ground_bottom_color",
ground_bottom.lerp(weather_tint, tint_strength * 0.62), ground_bottom,
) )
_sky_material.set_shader_parameter( _sky_material.set_shader_parameter(
"ground_horizon_color", "ground_horizon_color",
ground_horizon.lerp( ground_horizon,
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),
) )
_environment.background_energy_multiplier = ( _environment.background_energy_multiplier = (
lerpf(0.52, 0.85, daylight) lerpf(0.52, 0.85, daylight)
* _weather_value(1.0, 0.82, 0.66, 0.74) * _weather_value(1.0, 0.82, 0.66, 1.0)
)
_environment.ambient_light_color = ambient.lerp(
weather_tint, tint_strength * 0.45
) )
_environment.ambient_light_color = ambient
_environment.ambient_light_energy = ( _environment.ambient_light_energy = (
lerpf(0.66, 1.08, daylight) lerpf(0.66, 1.08, daylight)
* _weather_value(1.0, 0.88, 0.76, 0.82) * _weather_value(1.0, 0.88, 0.76, 0.82)
) )
_environment.fog_light_color = fog_color.lerp( _environment.fog_light_color = fog_color
weather_tint, tint_strength * 0.82
)
_environment.fog_light_energy = ( _environment.fog_light_energy = (
lerpf(0.56, 0.82, daylight) lerpf(0.56, 0.82, daylight)
* _weather_value(1.0, 0.92, 0.82, 1.05) * _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( _environment.fog_aerial_perspective = _weather_value(
0.35, 0.48, 0.62, 0.92 0.35, 0.48, 0.62, 0.92
) )
_environment.fog_sky_affect = _weather_value( _environment.fog_sky_affect = 0.0
0.35, 0.48, 0.68, 0.94
)
_environment.fog_depth_curve = _weather_value( _environment.fog_depth_curve = _weather_value(
1.6, 1.5, 1.4, 1.18 1.6, 1.5, 1.4, 1.18
) )
_environment.fog_depth_begin = _weather_value( _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( _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 = ( _environment.adjustment_brightness = (
lerpf(0.93, 0.98, daylight) 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 = ( _environment.adjustment_saturation = (
lerpf(0.82, 0.91, daylight) 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( _sun.rotation_degrees = Vector3(
-360.0 * fposmod(hour - WorldTimeService.DAY_START_HOUR, 24.0) / 24.0, -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( _sky_material.set_shader_parameter(
"sun_visibility", "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( _sky_material.set_shader_parameter(
"moon_direction", -_sun.global_transform.basis.z.normalized() "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_color", MOON_DISC)
_sky_material.set_shader_parameter( _sky_material.set_shader_parameter(
"moon_visibility", "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( _sun.light_color = _blended_color(
NIGHT_SUN, DAY_SUN, WARM_SUN, daylight, warmth NIGHT_SUN, DAY_SUN, WARM_SUN, daylight, warmth
@ -319,25 +304,30 @@ func _apply_time(time_hours: float) -> void:
_update_rain_amount() _update_rain_amount()
func _apply_water_haze(weather_tint: Color) -> void: func _apply_water_environment(
if SALT_WATER_MATERIAL == null: daylight: float,
return warmth: float,
SALT_WATER_MATERIAL.set_shader_parameter( ) -> void:
"distant_fog_color", var water_tint := _blended_color(
_environment.fog_light_color.lerp(weather_tint, 0.18), NIGHT_WATER_TINT,
Color.WHITE,
WARM_WATER_TINT,
daylight,
warmth,
) )
SALT_WATER_MATERIAL.set_shader_parameter( var water_brightness := (
"distant_fog_begin", lerpf(0.34, 1.0, daylight)
_environment.fog_depth_begin, * _weather_value(1.0, 0.90, 0.78, 1.0)
)
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),
) )
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( func _on_weather_changed(
@ -381,25 +371,6 @@ func _weather_state_value(
return sunny 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: func _update_rain_amount() -> void:
if _rain == null: if _rain == null:
return return