Skip to content

Commit

Permalink
Improve shadows
Browse files Browse the repository at this point in the history
Fixes #574.
  • Loading branch information
Indy2222 committed Aug 1, 2023
1 parent 752bd8d commit d745b23
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 15 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/camera/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ de_terrain.workspace = true

# Other
bevy.workspace = true
iyes_progress.workspace = true
parry3d.workspace = true
54 changes: 53 additions & 1 deletion crates/camera/src/camera.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use std::f32::consts::FRAC_PI_2;

use bevy::prelude::*;
use bevy::{
ecs::query::Has,
pbr::{CascadeShadowConfig, CascadeShadowConfigBuilder},
prelude::*,
};
use de_conf::{CameraConf, Configuration};
use de_core::{
cleanup::DespawnOnGameExit,
Expand All @@ -13,6 +17,7 @@ use de_core::{
use de_map::size::MapBounds;
use de_terrain::{TerrainCollider, MAX_ELEVATION};
use de_uom::{InverseSecond, Metre, Quantity, Radian, Second};
use iyes_progress::prelude::*;
use parry3d::{math::Vector, query::Ray};

/// Camera moves horizontally at speed `distance * CAMERA_HORIZONTAL_SPEED`.
Expand All @@ -36,6 +41,7 @@ const MIN_OFF_NADIR: Radian = Quantity::new_unchecked(0.001);
const MAX_OFF_NADIR: Radian = Quantity::new_unchecked(0.7 * FRAC_PI_2);
/// Never move camera focus point closer than this to a map edge.
const MAP_FOCUS_MARGIN: Metre = Quantity::new_unchecked(1.);
const SHADOWS_NUM_CASCADES: usize = 4;

pub(crate) struct CameraPlugin;

Expand Down Expand Up @@ -80,6 +86,9 @@ impl Plugin for CameraPlugin {
Movement,
(
zoom.in_set(InternalCameraSet::Zoom),
update_shadows
.after(InternalCameraSet::Zoom)
.run_if(resource_exists_and_changed::<CameraFocus>()),
pivot
.run_if(
resource_exists_and_changed::<DesiredOffNadir>()
Expand All @@ -93,6 +102,12 @@ impl Plugin for CameraPlugin {
.after(InternalCameraSet::Pivot),
)
.run_if(in_state(GameState::Playing)),
)
.add_systems(
Update,
setup_shadows
.track_progress()
.run_if(in_state(GameState::Loading)),
);
}
}
Expand Down Expand Up @@ -324,6 +339,30 @@ fn cleanup(mut commands: Commands) {
commands.remove_resource::<CameraFocus>();
}

fn setup_shadows(
mut commands: Commands,
focus: Res<CameraFocus>,
light: Query<(Entity, Has<CascadeShadowConfig>), With<DirectionalLight>>,
) -> Progress {
let Ok((entity, has_config)) = light.get_single() else {
return false.into();
};

if has_config {
return true.into();
}

let mut config = CascadeShadowConfigBuilder {
num_cascades: SHADOWS_NUM_CASCADES,
minimum_distance: 1.,
..default()
}
.build();
update_shadows_config(focus.as_ref(), &mut config);
commands.entity(entity).insert(config);
true.into()
}

fn update_focus(
mut focus: ResMut<CameraFocus>,
terrain: TerrainCollider,
Expand Down Expand Up @@ -440,6 +479,19 @@ fn zoom(
focus.update_distance(delta_scalar);
}

fn update_shadows(focus: Res<CameraFocus>, mut shadows: Query<&mut CascadeShadowConfig>) {
update_shadows_config(focus.as_ref(), shadows.single_mut().as_mut());
}

fn update_shadows_config(focus: &CameraFocus, shadows: &mut CascadeShadowConfig) {
let distnace = focus.distance().inner();

shadows.bounds[0] = 0.8 * distnace;
for i in 1..shadows.bounds.len() {
shadows.bounds[i] = shadows.bounds[i - 1] * (1.7f32).powi(i as i32);
}
}

fn pivot(
desired_off_nadir: Res<DesiredOffNadir>,
desired_azimuth: Res<DesiredAzimuth>,
Expand Down
16 changes: 2 additions & 14 deletions crates/loader/src/map.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use bevy::{
pbr::CascadeShadowConfigBuilder,
prelude::*,
tasks::{IoTaskPool, Task},
};
use de_camera::MoveFocusEvent;
use de_conf::Configuration;
use de_core::{
assets::asset_path,
cleanup::DespawnOnGameExit,
Expand Down Expand Up @@ -64,7 +62,6 @@ fn spawn_map(
mut commands: Commands,
task: Option<ResMut<MapLoadingTask>>,
mut move_focus_events: EventWriter<MoveFocusEvent>,
user_config: Res<Configuration>,
game_config: Res<GameConfig>,
) -> Progress {
let mut task = match task {
Expand Down Expand Up @@ -109,7 +106,7 @@ fn spawn_map(
move_focus_events.send(MoveFocusEvent::new(focus));
}

setup_light(&mut commands, user_config.as_ref());
setup_light(&mut commands);
commands.spawn((
TerrainBundle::flat(map.metadata().bounds()),
DespawnOnGameExit,
Expand Down Expand Up @@ -145,7 +142,7 @@ fn spawn_map(
true.into()
}

fn setup_light(commands: &mut Commands, conf: &Configuration) {
fn setup_light(commands: &mut Commands) {
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 0.6,
Expand All @@ -154,14 +151,6 @@ fn setup_light(commands: &mut Commands, conf: &Configuration) {
let mut transform = Transform::IDENTITY;
transform.look_at(Vec3::new(1., -1., 0.), Vec3::new(1., 1., 0.));

let cascade_shadow_config = CascadeShadowConfigBuilder {
num_cascades: 5,
maximum_distance: 1000.,
first_cascade_far_bound: conf.camera().min_distance().inner() * 2.,
..default()
}
.build();

commands.spawn((
DirectionalLightBundle {
directional_light: DirectionalLight {
Expand All @@ -170,7 +159,6 @@ fn setup_light(commands: &mut Commands, conf: &Configuration) {
shadows_enabled: true,
..Default::default()
},
cascade_shadow_config,
transform,
..Default::default()
},
Expand Down

0 comments on commit d745b23

Please sign in to comment.