shadow_caster_receiver/
shadow_caster_receiver.rs1use std::f32::consts::PI;
4
5use bevy::{
6 color::palettes::basic::{BLUE, LIME, RED},
7 light::{CascadeShadowConfigBuilder, NotShadowCaster, NotShadowReceiver},
8 prelude::*,
9};
10
11fn main() {
12 println!(
13 "Controls:
14 C - toggle shadow casters (i.e. casters become not, and not casters become casters)
15 R - toggle shadow receivers (i.e. receivers become not, and not receivers become receivers)
16 L - switch between directional and point lights"
17 );
18 App::new()
19 .add_plugins(DefaultPlugins)
20 .add_systems(Startup, setup)
21 .add_systems(Update, (toggle_light, toggle_shadows))
22 .run();
23}
24
25fn setup(
27 mut commands: Commands,
28 mut meshes: ResMut<Assets<Mesh>>,
29 mut materials: ResMut<Assets<StandardMaterial>>,
30) {
31 let spawn_plane_depth = 500.0f32;
32 let spawn_height = 2.0;
33 let sphere_radius = 0.25;
34
35 let white_handle = materials.add(StandardMaterial {
36 base_color: Color::WHITE,
37 perceptual_roughness: 1.0,
38 ..default()
39 });
40 let sphere_handle = meshes.add(Sphere::new(sphere_radius));
41
42 commands.spawn((
44 Mesh3d(sphere_handle.clone()),
45 MeshMaterial3d(materials.add(Color::from(RED))),
46 Transform::from_xyz(-1.0, spawn_height, 0.0),
47 ));
48
49 commands.spawn((
51 Mesh3d(sphere_handle),
52 MeshMaterial3d(materials.add(Color::from(BLUE))),
53 Transform::from_xyz(1.0, spawn_height, 0.0),
54 NotShadowCaster,
55 ));
56
57 commands.spawn((
59 Mesh3d(meshes.add(Plane3d::default().mesh().size(20.0, 20.0))),
60 MeshMaterial3d(materials.add(Color::from(LIME))),
61 Transform::from_xyz(0.0, 1.0, -10.0),
62 NotShadowCaster,
63 NotShadowReceiver,
64 ));
65
66 commands.spawn((
68 Mesh3d(meshes.add(Plane3d::default().mesh().size(20.0, 20.0))),
69 MeshMaterial3d(white_handle),
70 ));
71
72 println!("Using DirectionalLight");
73
74 commands.spawn((
75 PointLight {
76 intensity: 0.0,
77 range: spawn_plane_depth,
78 color: Color::WHITE,
79 shadows_enabled: true,
80 ..default()
81 },
82 Transform::from_xyz(5.0, 5.0, 0.0),
83 ));
84
85 commands.spawn((
86 DirectionalLight {
87 illuminance: light_consts::lux::OVERCAST_DAY,
88 shadows_enabled: true,
89 ..default()
90 },
91 Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, PI / 2., -PI / 4.)),
92 CascadeShadowConfigBuilder {
93 first_cascade_far_bound: 7.0,
94 maximum_distance: 25.0,
95 ..default()
96 }
97 .build(),
98 ));
99
100 commands.spawn((
102 Camera3d::default(),
103 Transform::from_xyz(-5.0, 5.0, 5.0).looking_at(Vec3::new(-1.0, 1.0, 0.0), Vec3::Y),
104 ));
105}
106
107fn toggle_light(
108 input: Res<ButtonInput<KeyCode>>,
109 mut point_lights: Query<&mut PointLight>,
110 mut directional_lights: Query<&mut DirectionalLight>,
111) {
112 if input.just_pressed(KeyCode::KeyL) {
113 for mut light in &mut point_lights {
114 light.intensity = if light.intensity == 0.0 {
115 println!("Using PointLight");
116 1_000_000.0 } else {
118 0.0
119 };
120 }
121 for mut light in &mut directional_lights {
122 light.illuminance = if light.illuminance == 0.0 {
123 println!("Using DirectionalLight");
124 light_consts::lux::OVERCAST_DAY
125 } else {
126 0.0
127 };
128 }
129 }
130}
131
132fn toggle_shadows(
133 mut commands: Commands,
134 input: Res<ButtonInput<KeyCode>>,
135 mut queries: ParamSet<(
136 Query<Entity, (With<Mesh3d>, With<NotShadowCaster>)>,
137 Query<Entity, (With<Mesh3d>, With<NotShadowReceiver>)>,
138 Query<Entity, (With<Mesh3d>, Without<NotShadowCaster>)>,
139 Query<Entity, (With<Mesh3d>, Without<NotShadowReceiver>)>,
140 )>,
141) {
142 if input.just_pressed(KeyCode::KeyC) {
143 println!("Toggling casters");
144 for entity in queries.p0().iter() {
145 commands.entity(entity).remove::<NotShadowCaster>();
146 }
147 for entity in queries.p2().iter() {
148 commands.entity(entity).insert(NotShadowCaster);
149 }
150 }
151 if input.just_pressed(KeyCode::KeyR) {
152 println!("Toggling receivers");
153 for entity in queries.p1().iter() {
154 commands.entity(entity).remove::<NotShadowReceiver>();
155 }
156 for entity in queries.p3().iter() {
157 commands.entity(entity).insert(NotShadowReceiver);
158 }
159 }
160}