Add default light profile for PortMaster
This commit is contained in:
parent
a62cce6404
commit
a3e0830bd1
16 changed files with 454 additions and 42 deletions
|
|
@ -13,6 +13,9 @@ const DISTANCE_FADE_START: float = 240.0
|
|||
const DISTANCE_FADE_END: float = 300.0
|
||||
const WRAP_RADIUS: float = FIELD_HALF_EXTENT
|
||||
const MAXIMUM_OPACITY: float = 1.0
|
||||
const LIGHT_CEILING_SIZE: float = 520.0
|
||||
const LIGHT_CEILING_ALTITUDE: float = 20.0
|
||||
const LIGHT_MAXIMUM_OPACITY: float = 0.72
|
||||
const BASE_VELOCITY := Vector2(0.825, -0.45)
|
||||
const BODY_OUTLINE: Array[Vector2] = [
|
||||
Vector2(-6.9, -0.8),
|
||||
|
|
@ -50,14 +53,25 @@ var _target: Node3D
|
|||
var _material: ShaderMaterial
|
||||
var _multimesh: MultiMesh
|
||||
var _cloud_mesh: MultiMeshInstance3D
|
||||
var _light_cloud_mesh: MeshInstance3D
|
||||
var _light_material: StandardMaterial3D
|
||||
var _drift_offset := Vector2.ZERO
|
||||
var _storm_amount: float = 0.0
|
||||
var _light_performance_profile: bool = false
|
||||
|
||||
|
||||
func setup(target: Node3D) -> void:
|
||||
func setup(
|
||||
target: Node3D,
|
||||
light_performance_profile: bool = false,
|
||||
) -> void:
|
||||
_target = target
|
||||
_build_cloud_field()
|
||||
_update_cloud_transforms()
|
||||
_light_performance_profile = light_performance_profile
|
||||
if _light_performance_profile:
|
||||
_build_light_cloud_ceiling()
|
||||
_update_light_position()
|
||||
else:
|
||||
_build_cloud_field()
|
||||
_update_cloud_transforms()
|
||||
set_process(true)
|
||||
|
||||
|
||||
|
|
@ -65,8 +79,19 @@ func set_storm_amount(amount: float, color: Color) -> void:
|
|||
_storm_amount = clampf(amount, 0.0, 1.0)
|
||||
var should_be_visible: bool = _storm_amount > 0.001
|
||||
if should_be_visible and not visible:
|
||||
_update_cloud_transforms()
|
||||
if _light_performance_profile:
|
||||
_update_light_position()
|
||||
else:
|
||||
_update_cloud_transforms()
|
||||
visible = should_be_visible
|
||||
if _light_performance_profile:
|
||||
if _light_material != null:
|
||||
var light_color: Color = color
|
||||
light_color.a = (
|
||||
_storm_amount * LIGHT_MAXIMUM_OPACITY
|
||||
)
|
||||
_light_material.albedo_color = light_color
|
||||
return
|
||||
if _material == null:
|
||||
return
|
||||
_material.set_shader_parameter("weather_opacity", _storm_amount)
|
||||
|
|
@ -78,12 +103,19 @@ func get_storm_amount() -> float:
|
|||
|
||||
|
||||
func get_patch_count() -> int:
|
||||
return GRID_AXIS_COUNT * GRID_AXIS_COUNT
|
||||
return (
|
||||
1
|
||||
if _light_performance_profile
|
||||
else GRID_AXIS_COUNT * GRID_AXIS_COUNT
|
||||
)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not visible or _target == null or not is_instance_valid(_target):
|
||||
return
|
||||
if _light_performance_profile:
|
||||
_update_light_position()
|
||||
return
|
||||
_drift_offset += BASE_VELOCITY * delta
|
||||
_drift_offset = Vector2(
|
||||
_wrap_axis(_drift_offset.x),
|
||||
|
|
@ -128,6 +160,37 @@ func _build_cloud_field() -> void:
|
|||
visible = false
|
||||
|
||||
|
||||
func _build_light_cloud_ceiling() -> void:
|
||||
_light_material = StandardMaterial3D.new()
|
||||
_light_material.resource_name = "light_cloud_ceiling"
|
||||
_light_material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
_light_material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
_light_material.cull_mode = BaseMaterial3D.CULL_DISABLED
|
||||
_light_material.albedo_color = Color(0.22, 0.25, 0.26, 0.0)
|
||||
var ceiling_mesh := PlaneMesh.new()
|
||||
ceiling_mesh.size = Vector2.ONE * LIGHT_CEILING_SIZE
|
||||
ceiling_mesh.material = _light_material
|
||||
_light_cloud_mesh = MeshInstance3D.new()
|
||||
_light_cloud_mesh.name = "CloudCeiling"
|
||||
_light_cloud_mesh.position.y = LIGHT_CEILING_ALTITUDE
|
||||
_light_cloud_mesh.mesh = ceiling_mesh
|
||||
_light_cloud_mesh.cast_shadow = (
|
||||
GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||
)
|
||||
add_child(_light_cloud_mesh)
|
||||
visible = false
|
||||
|
||||
|
||||
func _update_light_position() -> void:
|
||||
if _target == null or not is_instance_valid(_target):
|
||||
return
|
||||
global_position = Vector3(
|
||||
_target.global_position.x,
|
||||
0.0,
|
||||
_target.global_position.z,
|
||||
)
|
||||
|
||||
|
||||
func _build_cloud_body_mesh() -> ArrayMesh:
|
||||
var outline := PackedVector2Array(BODY_OUTLINE)
|
||||
var surface_tool := SurfaceTool.new()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,14 @@ const FOLIAGE_MATERIAL_NAMES: Array[StringName] = [
|
|||
&"leaf_light",
|
||||
&"leaf_dark",
|
||||
]
|
||||
const NORMAL_SALT_WATER_MATERIAL: Material = preload(
|
||||
"res://world/materials/stylized_water.tres"
|
||||
)
|
||||
const NORMAL_FRESH_WATER_MATERIAL: Material = preload(
|
||||
"res://world/materials/stylized_water_fresh.tres"
|
||||
)
|
||||
const LIGHT_SALT_WATER_COLOR := Color(0.11, 0.345, 0.435)
|
||||
const LIGHT_FRESH_WATER_COLOR := Color(0.18, 0.46, 0.50)
|
||||
|
||||
@export_group("Owned Nodes")
|
||||
@export_node_path("MeshInstance3D")
|
||||
|
|
@ -60,6 +68,48 @@ func get_saltwater_shoreline_mesh() -> MeshInstance3D:
|
|||
return get_node_or_null(^"ShorelineRibbons/Ocean") as MeshInstance3D
|
||||
|
||||
|
||||
func set_light_performance_profile(enabled: bool) -> void:
|
||||
var pond := get_node_or_null(
|
||||
^"WaterBodies/Pond/VisualWater"
|
||||
) as MeshInstance3D
|
||||
var ocean := get_node_or_null(
|
||||
^"WaterBodies/Ocean/VisualWater"
|
||||
) as MeshInstance3D
|
||||
if pond != null:
|
||||
pond.material_override = (
|
||||
_create_light_water_material(
|
||||
LIGHT_FRESH_WATER_COLOR,
|
||||
&"light_fresh_water",
|
||||
)
|
||||
if enabled
|
||||
else NORMAL_FRESH_WATER_MATERIAL
|
||||
)
|
||||
if ocean != null:
|
||||
ocean.material_override = (
|
||||
_create_light_water_material(
|
||||
LIGHT_SALT_WATER_COLOR,
|
||||
&"light_salt_water",
|
||||
)
|
||||
if enabled
|
||||
else NORMAL_SALT_WATER_MATERIAL
|
||||
)
|
||||
var surface_motion := ocean as WaterSurfaceMotion
|
||||
if surface_motion != null:
|
||||
surface_motion.set_motion_enabled(not enabled)
|
||||
|
||||
|
||||
func _create_light_water_material(
|
||||
color: Color,
|
||||
material_name: StringName,
|
||||
) -> StandardMaterial3D:
|
||||
var material := StandardMaterial3D.new()
|
||||
material.resource_name = str(material_name)
|
||||
material.albedo_color = color
|
||||
material.roughness = 1.0
|
||||
material.shading_mode = BaseMaterial3D.SHADING_MODE_PER_VERTEX
|
||||
return material
|
||||
|
||||
|
||||
func get_spawn_surface_triangles(
|
||||
material_names: Array[StringName],
|
||||
minimum_global_y: float,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ func get_sun() -> DirectionalLight3D:
|
|||
return _sun
|
||||
|
||||
|
||||
func set_light_performance_profile(enabled: bool) -> void:
|
||||
_starter_island.set_light_performance_profile(enabled)
|
||||
|
||||
|
||||
func get_fishable_water_regions() -> Array[FishableWaterRegion]:
|
||||
var waters: Array[FishableWaterRegion] = []
|
||||
for region: WorldRegion in _get_regions():
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ func _process(_delta: float) -> void:
|
|||
)
|
||||
|
||||
|
||||
func set_motion_enabled(enabled: bool) -> void:
|
||||
set_process(enabled and amplitude > 0.0)
|
||||
if not enabled:
|
||||
position.y = _base_height
|
||||
|
||||
|
||||
static func get_default_height_offset() -> float:
|
||||
return calculate_height_offset(
|
||||
_current_time_seconds(),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ class_name WorldTimeVisualController
|
|||
extends Node
|
||||
|
||||
const UPDATE_INTERVAL_SECONDS: float = 0.1
|
||||
const LIGHT_UPDATE_INTERVAL_SECONDS: float = 0.25
|
||||
const SUN_YAW_DEGREES: float = -32.0
|
||||
const WEATHER_TRANSITION_SECONDS: float = 10.0
|
||||
const RAIN_EMITTER_OFFSET := Vector3(0.0, 7.0, 0.0)
|
||||
|
|
@ -11,6 +12,8 @@ const RAIN_VISIBILITY_AABB := AABB(
|
|||
Vector3(27.0, 12.0, 27.0),
|
||||
)
|
||||
const RAIN_PARTICLE_AMOUNT: int = 2240
|
||||
const LIGHT_RAIN_PARTICLE_AMOUNT: int = 256
|
||||
const LIGHT_RAIN_FIXED_FPS: int = 15
|
||||
const RAIN_VELOCITY_MIN: float = 16.0
|
||||
const RAIN_VELOCITY_MAX: float = 20.0
|
||||
const RAIN_DROP_SIZE := Vector3(0.014, 0.34, 0.014)
|
||||
|
|
@ -92,6 +95,7 @@ var _weather_to: WorldWeatherService.Weather = (
|
|||
WorldWeatherService.Weather.SUNNY
|
||||
)
|
||||
var _weather_transition: float = 1.0
|
||||
var _light_performance_profile: bool = false
|
||||
|
||||
|
||||
func setup(
|
||||
|
|
@ -101,6 +105,7 @@ func setup(
|
|||
weather_service: WorldWeatherService = null,
|
||||
rain_target: Node3D = null,
|
||||
rain_camera_provider: Callable = Callable(),
|
||||
light_performance_profile: bool = false,
|
||||
) -> void:
|
||||
_time_service = time_service
|
||||
_weather_service = weather_service
|
||||
|
|
@ -108,6 +113,7 @@ func setup(
|
|||
_sun = sun
|
||||
_rain_target = rain_target
|
||||
_rain_camera_provider = rain_camera_provider
|
||||
_light_performance_profile = light_performance_profile
|
||||
if not _prepare_runtime_environment():
|
||||
set_process(false)
|
||||
return
|
||||
|
|
@ -135,7 +141,12 @@ func _process(delta: float) -> void:
|
|||
1.0,
|
||||
)
|
||||
_elapsed += delta
|
||||
if _elapsed < UPDATE_INTERVAL_SECONDS:
|
||||
var update_interval: float = (
|
||||
LIGHT_UPDATE_INTERVAL_SECONDS
|
||||
if _light_performance_profile
|
||||
else UPDATE_INTERVAL_SECONDS
|
||||
)
|
||||
if _elapsed < update_interval:
|
||||
return
|
||||
_elapsed = 0.0
|
||||
_apply_time(_time_service.get_time_hours())
|
||||
|
|
@ -187,10 +198,16 @@ func _prepare_runtime_environment() -> bool:
|
|||
func _prepare_rain() -> void:
|
||||
_rain = GPUParticles3D.new()
|
||||
_rain.name = "LocalRain"
|
||||
_rain.amount = RAIN_PARTICLE_AMOUNT
|
||||
_rain.amount = (
|
||||
LIGHT_RAIN_PARTICLE_AMOUNT
|
||||
if _light_performance_profile
|
||||
else RAIN_PARTICLE_AMOUNT
|
||||
)
|
||||
_rain.amount_ratio = 0.0
|
||||
_rain.lifetime = 1.25
|
||||
_rain.fixed_fps = 30
|
||||
_rain.fixed_fps = (
|
||||
LIGHT_RAIN_FIXED_FPS if _light_performance_profile else 30
|
||||
)
|
||||
_rain.local_coords = false
|
||||
_rain.visibility_aabb = RAIN_VISIBILITY_AABB
|
||||
var process_material := ParticleProcessMaterial.new()
|
||||
|
|
@ -220,7 +237,7 @@ func _prepare_storm_clouds() -> void:
|
|||
_storm_clouds = LocalStormCloudLayerType.new()
|
||||
_storm_clouds.name = "LocalStormClouds"
|
||||
add_child(_storm_clouds)
|
||||
_storm_clouds.setup(_rain_target)
|
||||
_storm_clouds.setup(_rain_target, _light_performance_profile)
|
||||
|
||||
|
||||
func _apply_time(time_hours: float) -> void:
|
||||
|
|
@ -259,6 +276,33 @@ func _apply_time(time_hours: float) -> void:
|
|||
var fog_color: Color = _blended_color(
|
||||
NIGHT_FOG, DAY_FOG, WARM_FOG, daylight, warmth
|
||||
)
|
||||
if _light_performance_profile:
|
||||
var simple_cloud_color := _blended_color(
|
||||
NIGHT_CLOUD_SHADOW,
|
||||
DAY_CLOUD_SHADOW,
|
||||
WARM_CLOUD_SHADOW,
|
||||
daylight,
|
||||
warmth,
|
||||
)
|
||||
var simple_overcast: float = _weather_value(
|
||||
0.0,
|
||||
0.55,
|
||||
0.82,
|
||||
0.0,
|
||||
)
|
||||
sky_top = sky_top.lerp(simple_cloud_color, simple_overcast)
|
||||
sky_horizon = sky_horizon.lerp(
|
||||
simple_cloud_color.lightened(0.08),
|
||||
simple_overcast,
|
||||
)
|
||||
ground_bottom = ground_bottom.lerp(
|
||||
simple_cloud_color.darkened(0.12),
|
||||
simple_overcast * 0.65,
|
||||
)
|
||||
ground_horizon = ground_horizon.lerp(
|
||||
simple_cloud_color,
|
||||
simple_overcast * 0.75,
|
||||
)
|
||||
var foggy_fog_amount: float = _weather_value(0.0, 0.0, 0.0, 1.0)
|
||||
var rain_fog_amount: float = _weather_value(0.0, 0.0, 1.0, 0.0)
|
||||
var fog_daylight_amount: float = daylight * foggy_fog_amount
|
||||
|
|
@ -399,6 +443,8 @@ func _apply_water_environment(
|
|||
foggy_horizon_occlusion: float,
|
||||
fog_render_color: Color,
|
||||
) -> void:
|
||||
if _light_performance_profile:
|
||||
return
|
||||
var water_tint := _blended_color(
|
||||
NIGHT_WATER_TINT,
|
||||
Color.WHITE,
|
||||
|
|
@ -561,6 +607,15 @@ func _apply_sky_clouds(daylight: float, warmth: float) -> void:
|
|||
daylight,
|
||||
warmth,
|
||||
)
|
||||
if _light_performance_profile:
|
||||
_sky_material.set_shader_parameter("cloud_coverage", 0.0)
|
||||
_sky_material.set_shader_parameter("cloud_opacity", 0.0)
|
||||
if _storm_clouds != null:
|
||||
_storm_clouds.set_storm_amount(
|
||||
_weather_value(0.0, 0.42, 0.88, 0.0),
|
||||
lower_cloud_color,
|
||||
)
|
||||
return
|
||||
_sky_material.set_shader_parameter(
|
||||
"cloud_coverage",
|
||||
_weather_value(0.0, 0.58, 0.985, 0.0),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue