Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch engine to use physical lighting #53

Merged
merged 1 commit into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions native/src/scripts/objects.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod building;
mod camera;
mod canon_upgrade;
mod debugger_3_d;
mod water_jet;
61 changes: 61 additions & 0 deletions native/src/scripts/objects/camera.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use godot::{builtin::Dictionary, classes::Camera3D, engine::Node3D, obj::Gd};
use godot_rust_script::{godot_script_impl, CastToScript, GodotScript, RsRef};
use itertools::Itertools;

use crate::{
info,
scripts::world::solar_setup::{ISolarSetup, SolarSetup},
warn,
};

#[derive(GodotScript, Debug)]
#[script(base = Camera3D)]
struct Camera {
#[export]
pub exposure_times: Dictionary,

#[export]
pub solar_setup_node: Option<Gd<Node3D>>,

solar_setup: Option<RsRef<SolarSetup>>,

base: Gd<Camera3D>,
}

#[godot_script_impl]
impl Camera {
pub fn _ready(&mut self) {
self.solar_setup = self.solar_setup_node.clone().map(|node| node.into_script());
}

pub fn _process(&mut self, _delta: f64) {
let Some(solar_setup) = self.solar_setup.as_mut() else {
warn!("Solar setup is not available!");
return;
};

let Some(mut attributes) = self.base.get_attributes() else {
warn!("Camera has no attributes!");
return;
};

let game_time = solar_setup.get_ingame_time_h();

let exposure = self
.exposure_times
.iter_shared()
.sorted_by(|(key_a, _), (key_b, _)| key_a.to::<f64>().total_cmp(&key_b.to::<f64>()))
.rev()
.find(|(key, _)| key.to::<f64>() <= game_time)
.map(|(_, value)| value.to::<f32>())
.unwrap_or(0.0);

if attributes.get_exposure_sensitivity() == exposure {
return;
}

info!("Updating camera exposure to {} at {}", exposure, game_time);

attributes.set_exposure_sensitivity(exposure);
}
}
2 changes: 1 addition & 1 deletion native/src/scripts/world.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mod buildings;
mod solar_setup;
pub mod solar_setup;
70 changes: 46 additions & 24 deletions native/src/scripts/world/solar_setup.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use godot::builtin::math::FloatExt;
use godot::builtin::Vector3;
use godot::engine::{light_3d, DirectionalLight3D, Node3D, Time};
use godot::obj::Gd;
Expand All @@ -7,7 +8,7 @@ use crate::util::logger;

#[derive(GodotScript, Debug)]
#[script(base = Node3D)]
struct SolarSetup {
pub struct SolarSetup {
/// Reference to the sun child node.
#[export]
pub sun: Option<Gd<DirectionalLight3D>>,
Expand All @@ -16,9 +17,7 @@ struct SolarSetup {
#[export]
pub moon: Option<Gd<DirectionalLight3D>>,

cached_moon_brightness: f32,

// duration from sun rise to sun set in minutes
/// duration from sun rise to sun set in minutes
#[export(range(min = 1.0, max = 120.0, step = 1.0))]
pub day_length: u64,

Expand All @@ -27,20 +26,9 @@ struct SolarSetup {

#[godot_script_impl]
impl SolarSetup {
pub fn _ready(&mut self) {
let Some(ref mut moon) = self.moon else {
logger::error!("no moon is assinged to solar setup!");
logger::error!("node path: {}", self.base.get_path());
return;
};

self.cached_moon_brightness = moon.get_param(light_3d::Param::ENERGY);
}

pub fn _physics_process(&mut self, _delta: f64) {
let day_length = self.day_length * 60 * 1000;
let time = Time::singleton().get_ticks_msec() % (day_length * 2);

let time = self.get_time();
let day_length = self.day_length_ms();
let sun_pos = time as f32 * (360.0 / (day_length * 2) as f32);

let Some(ref mut sun) = self.sun else {
Expand All @@ -59,20 +47,54 @@ impl SolarSetup {
self.base
.set_rotation_degrees(Vector3::new(sun_pos, 0.0, 0.0));

let sun_visible = sun_pos < 190.0;
let sun_zenit_distance = ((sun_pos - 90.0) / 90.0).abs().clamp(0.0, 1.0);

sun.set_param(
light_3d::Param::ENERGY,
if sun_pos > 190.0 { 0.0 } else { 1.0 },
if !sun_visible { 0.0 } else { 1.0 },
);
sun.set_shadow(sun_pos < 190.0);
sun.set_shadow(sun_visible);

if sun_visible {
sun.set_param(
light_3d::Param::INTENSITY,
100000.0.lerp(400.0, sun_zenit_distance),
);
sun.set_temperature((5500.0).lerp(1850.0, sun_zenit_distance));
}

moon.set_param(
light_3d::Param::ENERGY,
if sun_pos > 180.0 {
self.cached_moon_brightness
} else {
0.0
},
if sun_pos > 180.0 { 1.0 } else { 0.0 },
);
moon.set_shadow(sun_pos > 180.0);
}

/// Day length (sunrise to sunset) in ms.
fn day_length_ms(&self) -> u64 {
self.day_length * 60 * 1000
}

/// Get the current game time in ms.
pub fn get_time(&self) -> u64 {
let day_length = self.day_length_ms();

Time::singleton().get_ticks_msec() % (day_length * 2)
}

// get the current in-game time in seconds since sunrise.
pub fn get_ingame_time_s(&self) -> f64 {
self.get_ingame_time_m() * 60.0
}

// get the current in-game time in minutes since sunrise.
pub fn get_ingame_time_m(&self) -> f64 {
self.get_ingame_time_h() * 60.0
}

// get the current in-game time in hours since sunrise.
pub fn get_ingame_time_h(&self) -> f64 {
self.get_time() as f64 / (self.day_length_ms() as f64 * 2.0 / 24.0)
}
}
20 changes: 15 additions & 5 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,25 @@ common/physics_ticks_per_second=120
[rendering]

textures/vram_compression/import_s3tc_bptc=true
lights_and_shadows/use_physical_light_units=true
lights_and_shadows/directional_shadow/size=8192
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=4
lights_and_shadows/directional_shadow/16_bits=false
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=3
lights_and_shadows/positional_shadow/soft_shadow_filter_quality=3
global_illumination/gi/use_half_resolution=true
textures/decals/filter=2
global_illumination/voxel_gi/quality=1
environment/ssao/half_size=false
environment/ssil/half_size=false
anti_aliasing/screen_space_roughness_limiter/enabled=false
scaling_3d/mode=2
scaling_3d/scale=0.5
scaling_3d/fsr_sharpness=0.2
textures/decals/filter=5
textures/light_projectors/filter=5
environment/screen_space_reflection/roughness_quality=2
environment/subsurface_scattering/subsurface_scattering_quality=2
global_illumination/sdfgi/probe_ray_count=2
environment/volumetric_fog/volume_size=100
environment/volumetric_fog/volume_depth=100
anti_aliasing/quality/use_taa=true
occlusion_culling/use_occlusion_culling=true
lights_and_shadows/positional_shadow/atlas_16_bits=false
environment/defaults/default_environment="res://resources/Environments/default_env.tres"
threads/thread_model=2
24 changes: 20 additions & 4 deletions resources/Environments/WorldEnv.tres
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,33 @@ sky_material = ExtResource("1_inrw2")

[resource]
background_mode = 2
background_intensity = 20000.0
sky = SubResource("Sky_gwtol")
tonemap_mode = 3
tonemap_exposure = 0.7
tonemap_white = 6.0
ssr_enabled = true
ssr_max_steps = 80
ssr_fade_out = 1.0
ssr_depth_tolerance = 0.51
ssr_max_steps = 128
ssr_fade_in = 0.05
ssr_fade_out = 1.5
ssao_enabled = true
ssao_radius = 1.2
ssao_intensity = 1.1
ssao_horizon = 0.0
ssao_sharpness = 1.0
sdfgi_enabled = true
sdfgi_bounce_feedback = 1.0
glow_enabled = true
glow_levels/1 = 1.0
glow_levels/2 = 1.0
glow_levels/4 = 1.0
glow_levels/6 = 1.0
glow_levels/7 = 1.0
glow_intensity = 0.5
glow_blend_mode = 1
fog_light_color = Color(0.65, 0.84, 0.95, 1)
fog_density = 0.001
volumetric_fog_enabled = true
volumetric_fog_density = 0.0
volumetric_fog_length = 2000.0
adjustment_enabled = true
adjustment_saturation = 1.3
2 changes: 1 addition & 1 deletion resources/Materials/ocean_material.tres
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ shader_parameter/speed = 0.1
shader_parameter/Wave2_Dir = 0.569
shader_parameter/wave_height = 5.0
shader_parameter/Albedo = Color(0.129412, 0.180392, 0.262745, 1)
shader_parameter/Depth_Scale = 0.05
shader_parameter/Depth_Scale = 0.2
shader_parameter/Roughness = 0.2
shader_parameter/Noise = SubResource("NoiseTexture2D_06ugh")
shader_parameter/TextureUniform = SubResource("NoiseTexture2D_l65p1")
2 changes: 2 additions & 0 deletions resources/Objects/Spawner/fire_spawner.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10.1948, 0)

[node name="FireLightSource" type="OmniLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.01561, -3.39593)
light_intensity_lumens = 3000.0
light_temperature = 1850.0
light_color = Color(0.980392, 0.309804, 0.00392157, 1)
light_volumetric_fog_energy = 0.0

Expand Down
1 change: 0 additions & 1 deletion resources/Shaders/ocean_visualshader.tres
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,6 @@ void fragment() {

}
"
graph_offset = Vector2(263.253, -737.657)
varyings/vary_world_uv = "0,3"
varyings/vary_world_uv2 = "0,3"
nodes/vertex/0/position = Vector2(3340, -540)
Expand Down
5 changes: 4 additions & 1 deletion resources/TestScenes/ocean.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://djrh870bg3ckr"]
[gd_scene load_steps=9 format=3 uid="uid://djrh870bg3ckr"]

[ext_resource type="Material" uid="uid://bmp5rvu5slnnt" path="res://resources/Materials/ocean_material.tres" id="2"]
[ext_resource type="Material" uid="uid://7h8w8gb1xjbk" path="res://resources/Materials/ocean_backdrop.tres" id="2_en16t"]
Expand All @@ -20,6 +20,8 @@ background_mode = 2
sky = SubResource("4")
tonemap_mode = 3

[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_jtm2k"]

[sub_resource type="PlaneMesh" id="PlaneMesh_2q6u6"]
size = Vector2(512, 512)

Expand Down Expand Up @@ -79,6 +81,7 @@ shadow_enabled = true

[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("5")
camera_attributes = SubResource("CameraAttributesPractical_jtm2k")

[node name="CSGCombiner3D" type="CSGCombiner3D" parent="."]

Expand Down
41 changes: 28 additions & 13 deletions resources/main.tscn
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[gd_scene load_steps=18 format=3 uid="uid://cvh54xiw8586b"]
[gd_scene load_steps=20 format=3 uid="uid://cvh54xiw8586b"]

[ext_resource type="Script" path="res://src/HUD/HUDController.gd" id="1"]
[ext_resource type="Script" path="res://src/Objects/World/World.gd" id="3"]
[ext_resource type="Script" path="res://src/ViewPort.gd" id="3_2c332"]
[ext_resource type="Script" path="res://src/HUD/LoadingScreen.gd" id="4"]
[ext_resource type="Script" path="res://src/Objects/World/Backdrop.gd" id="6"]
[ext_resource type="Environment" uid="uid://bl607wqoa882d" path="res://resources/Environments/WorldEnv.tres" id="8"]
[ext_resource type="Script" path="res://native/src/scripts/objects/camera.rs" id="8_qw8ew"]
[ext_resource type="Script" path="res://src/Objects/Camera/CameraInterpolation.gd" id="10"]
[ext_resource type="Script" path="res://src/Objects/Terrain/Terrain.gd" id="11"]
[ext_resource type="Material" uid="uid://d3jryprnnxb6x" path="res://resources/Materials/terrain_material.tres" id="12"]
Expand All @@ -17,10 +18,15 @@
[ext_resource type="Script" path="res://native/src/scripts/world/buildings.rs" id="15_23gpq"]
[ext_resource type="PackedScene" uid="uid://cmv7rt4gqew38" path="res://resources/Objects/Helis/schweizer_300.tscn" id="16_e6k8r"]

[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_vnmmp"]

[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_lhcij"]
dof_blur_far_enabled = true
dof_blur_far_distance = 180.0
dof_blur_far_transition = -1.0
dof_blur_far_distance = 50.0
dof_blur_far_transition = 50.0
dof_blur_near_enabled = true
dof_blur_near_distance = 0.06
dof_blur_near_transition = 0.02

[node name="HUDController" type="Control"]
layout_mode = 3
Expand Down Expand Up @@ -65,7 +71,6 @@ stretch = true
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer" node_paths=PackedStringArray("current_camera_controller")]
handle_input_locally = false
use_occlusion_culling = true
scaling_3d_mode = 1
audio_listener_enable_3d = true
size = Vector2i(1152, 648)
size_2d_override_stretch = true
Expand All @@ -80,7 +85,7 @@ world_constants = ExtResource("15")

[node name="Environment" type="WorldEnvironment" parent="SubViewportContainer/SubViewport/World"]
environment = ExtResource("8")
camera_attributes = SubResource("CameraAttributesPractical_lhcij")
camera_attributes = SubResource("CameraAttributesPractical_vnmmp")

[node name="SolarSetup" type="Node3D" parent="SubViewportContainer/SubViewport/World/Environment" node_paths=PackedStringArray("sun", "moon")]
transform = Transform3D(1, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, -3.48787e-16, -3.48787e-16, 3.48787e-16, 1, 0, 0, 0)
Expand All @@ -93,32 +98,42 @@ day_length = 30
[node name="Sun" type="DirectionalLight3D" parent="SubViewportContainer/SubViewport/World/Environment/SolarSetup"]
transform = Transform3D(1, -3.48787e-16, 3.48787e-16, -3.48787e-16, -1, 8.74228e-08, 3.48787e-16, -8.74228e-08, -1, 2.08165e-12, -5.50338e-09, 0.1)
rotation_order = 0
light_color = Color(1, 0.952941, 0.843137, 1)
light_angular_distance = 0.5
shadow_enabled = true
directional_shadow_mode = 1
directional_shadow_split_1 = 0.3
directional_shadow_split_1 = 0.05
directional_shadow_split_2 = 0.3
directional_shadow_split_3 = 0.0
directional_shadow_split_3 = 0.4
directional_shadow_blend_splits = true
directional_shadow_fade_start = 0.6
directional_shadow_max_distance = 400.0
directional_shadow_max_distance = 500.0
directional_shadow_pancake_size = 40.0

[node name="Moon" type="DirectionalLight3D" parent="SubViewportContainer/SubViewport/World/Environment/SolarSetup"]
transform = Transform3D(1, -3.48787e-16, 3.48787e-16, 3.48787e-16, 1, -3.48787e-16, -3.48787e-16, 3.48787e-16, 1, 2.08165e-12, 1.45043e-10, -0.1)
rotation_order = 0
light_energy = 0.475
light_intensity_lux = 500.0
light_temperature = 4100.0
light_angular_distance = 0.5
shadow_enabled = true
directional_shadow_mode = 1
directional_shadow_split_1 = 0.3
directional_shadow_blend_splits = true
directional_shadow_fade_start = 0.6
directional_shadow_max_distance = 400.0

[node name="Camera" type="Camera3D" parent="SubViewportContainer/SubViewport/World"]
[node name="Camera" type="Camera3D" parent="SubViewportContainer/SubViewport/World" node_paths=PackedStringArray("solar_setup_node")]
transform = Transform3D(1, 0, 0, 0, 0.847724, 0.530437, 0, -0.530437, 0.847724, -45.4393, 5.66891, 25.269)
attributes = SubResource("CameraAttributesPractical_lhcij")
doppler_tracking = 2
current = true
near = 3.0
script = ExtResource("8_qw8ew")
exposure_times = {
0.0: 100.0,
12.0: 600.0,
14.0: 1500.0,
23.5: 600.0
}
solar_setup_node = NodePath("../Environment/SolarSetup")

[node name="Schweizer_300" parent="SubViewportContainer/SubViewport/World" node_paths=PackedStringArray("child_camera", "child_main_camera", "child_debug_camera") groups=["player"] instance=ExtResource("16_e6k8r")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -45.4393, -9.81614e-07, 17.9155)
Expand Down