Skip to content

Commit 4f54bdd

Browse files
committed
fix(pcss example): separate light entities and adjust intensity instead of remove components
1 parent f1a6b87 commit 4f54bdd

File tree

1 file changed

+102
-52
lines changed

1 file changed

+102
-52
lines changed

examples/3d/pcss.rs

Lines changed: 102 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ enum AppSetting {
109109
SoftShadows(bool),
110110
}
111111

112+
/// Stores the entities of each spawned light in the example.
113+
#[derive(Resource)]
114+
struct DirectionalPointSpotLights {
115+
directional: Entity,
116+
point: Entity,
117+
spot: Entity,
118+
}
119+
112120
/// The example application entry point.
113121
fn main() {
114122
#[cfg(not(feature = "free_camera"))]
@@ -149,7 +157,7 @@ fn main() {
149157
/// Creates all the objects in the scene.
150158
fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_status: Res<AppStatus>) {
151159
spawn_camera(&mut commands, &asset_server);
152-
spawn_light(&mut commands, &app_status);
160+
spawn_lights(&mut commands, &app_status);
153161
spawn_gltf_scene(&mut commands, &asset_server);
154162
spawn_buttons(&mut commands);
155163
}
@@ -183,28 +191,49 @@ fn spawn_camera(commands: &mut Commands, asset_server: &AssetServer) {
183191
});
184192
}
185193

186-
/// Spawns the initial light.
187-
fn spawn_light(commands: &mut Commands, app_status: &AppStatus) {
188-
// Because this light can become a directional light, point light, or spot
189-
// light depending on the settings, we add the union of the components
190-
// necessary for this light to behave as all three of those.
191-
commands
194+
/// Spawns the initial light and placeholder for other lights.
195+
fn spawn_lights(commands: &mut Commands, app_status: &AppStatus) {
196+
let transform = Transform::from_rotation(Quat::from_array([
197+
0.6539259,
198+
-0.34646285,
199+
0.36505926,
200+
-0.5648683,
201+
]))
202+
.with_translation(vec3(57.693, 34.334, -6.422));
203+
// Spawn an initial directional light
204+
let directional = commands
205+
.spawn((
206+
create_directional_light(app_status, light_consts::lux::AMBIENT_DAYLIGHT),
207+
transform.clone(),
208+
))
209+
.id();
210+
// Spawn placeholder entities for point and spot lights.
211+
// They are located in the same place as the directional light.
212+
let point = commands
213+
.spawn((
214+
create_point_light(app_status, 0.),
215+
transform.clone(),
216+
// These two are needed for point lights.
217+
CubemapVisibleEntities::default(),
218+
CubemapFrusta::default(),
219+
))
220+
.id();
221+
222+
let spot = commands
192223
.spawn((
193-
create_directional_light(app_status),
194-
Transform::from_rotation(Quat::from_array([
195-
0.6539259,
196-
-0.34646285,
197-
0.36505926,
198-
-0.5648683,
199-
]))
200-
.with_translation(vec3(57.693, 34.334, -6.422)),
224+
create_spot_light(app_status, 0.),
225+
transform,
226+
// These two are needed for spot lights.
227+
VisibleMeshEntities::default(),
228+
Frustum::default(),
201229
))
202-
// These two are needed for point lights.
203-
.insert(CubemapVisibleEntities::default())
204-
.insert(CubemapFrusta::default())
205-
// These two are needed for spot lights.
206-
.insert(VisibleMeshEntities::default())
207-
.insert(Frustum::default());
230+
.id();
231+
232+
commands.insert_resource(DirectionalPointSpotLights {
233+
directional,
234+
point,
235+
spot,
236+
});
208237
}
209238

210239
/// Loads and spawns the glTF palm tree scene.
@@ -282,7 +311,7 @@ fn update_radio_buttons(
282311
/// Handles requests from the user to change the type of light.
283312
fn handle_light_type_change(
284313
mut commands: Commands,
285-
mut lights: Query<Entity, Or<(With<DirectionalLight>, With<PointLight>, With<SpotLight>)>>,
314+
lights: Res<DirectionalPointSpotLights>,
286315
mut events: MessageReader<WidgetClickEvent<AppSetting>>,
287316
mut app_status: ResMut<AppStatus>,
288317
) {
@@ -291,23 +320,33 @@ fn handle_light_type_change(
291320
continue;
292321
};
293322
app_status.light_type = light_type;
294-
295-
for light in lights.iter_mut() {
296-
let mut light_commands = commands.entity(light);
297-
light_commands
298-
.remove::<DirectionalLight>()
299-
.remove::<PointLight>()
300-
.remove::<SpotLight>();
301-
match light_type {
302-
LightType::Point => {
303-
light_commands.insert(create_point_light(&app_status));
304-
}
305-
LightType::Spot => {
306-
light_commands.insert(create_spot_light(&app_status));
307-
}
308-
LightType::Directional => {
309-
light_commands.insert(create_directional_light(&app_status));
310-
}
323+
commands
324+
.entity(lights.directional)
325+
.insert(create_directional_light(&app_status, 0.));
326+
commands
327+
.entity(lights.point)
328+
.insert(create_point_light(&app_status, 0.));
329+
commands
330+
.entity(lights.spot)
331+
.insert(create_spot_light(&app_status, 0.));
332+
match light_type {
333+
LightType::Directional => {
334+
commands
335+
.entity(lights.directional)
336+
.insert(create_directional_light(
337+
&app_status,
338+
light_consts::lux::AMBIENT_DAYLIGHT,
339+
));
340+
}
341+
LightType::Point => {
342+
commands
343+
.entity(lights.point)
344+
.insert(create_point_light(&app_status, POINT_LIGHT_INTENSITY));
345+
}
346+
LightType::Spot => {
347+
commands
348+
.entity(lights.spot)
349+
.insert(create_spot_light(&app_status, POINT_LIGHT_INTENSITY));
311350
}
312351
}
313352
}
@@ -348,7 +387,8 @@ fn handle_shadow_filter_change(
348387

349388
/// Handles requests from the user to toggle soft shadows on and off.
350389
fn handle_pcss_toggle(
351-
mut lights: Query<AnyOf<(&mut DirectionalLight, &mut PointLight, &mut SpotLight)>>,
390+
mut commands: Commands,
391+
lights: Res<DirectionalPointSpotLights>,
352392
mut events: MessageReader<WidgetClickEvent<AppSetting>>,
353393
mut app_status: ResMut<AppStatus>,
354394
) {
@@ -359,23 +399,33 @@ fn handle_pcss_toggle(
359399
app_status.soft_shadows = value;
360400

361401
// Recreating the lights is the simplest way to toggle soft shadows.
362-
for (directional_light, point_light, spot_light) in lights.iter_mut() {
363-
if let Some(mut directional_light) = directional_light {
364-
*directional_light = create_directional_light(&app_status);
402+
match app_status.light_type {
403+
LightType::Directional => {
404+
commands
405+
.entity(lights.directional)
406+
.insert(create_directional_light(
407+
&app_status,
408+
light_consts::lux::AMBIENT_DAYLIGHT,
409+
));
365410
}
366-
if let Some(mut point_light) = point_light {
367-
*point_light = create_point_light(&app_status);
411+
LightType::Point => {
412+
commands
413+
.entity(lights.point)
414+
.insert(create_point_light(&app_status, POINT_LIGHT_INTENSITY));
368415
}
369-
if let Some(mut spot_light) = spot_light {
370-
*spot_light = create_spot_light(&app_status);
416+
LightType::Spot => {
417+
commands
418+
.entity(lights.spot)
419+
.insert(create_spot_light(&app_status, POINT_LIGHT_INTENSITY));
371420
}
372421
}
373422
}
374423
}
375424

376425
/// Creates the [`DirectionalLight`] component with the appropriate settings.
377-
fn create_directional_light(app_status: &AppStatus) -> DirectionalLight {
426+
fn create_directional_light(app_status: &AppStatus, illuminance: f32) -> DirectionalLight {
378427
DirectionalLight {
428+
illuminance,
379429
shadow_maps_enabled: true,
380430
soft_shadow_size: if app_status.soft_shadows {
381431
Some(LIGHT_RADIUS)
@@ -388,9 +438,9 @@ fn create_directional_light(app_status: &AppStatus) -> DirectionalLight {
388438
}
389439

390440
/// Creates the [`PointLight`] component with the appropriate settings.
391-
fn create_point_light(app_status: &AppStatus) -> PointLight {
441+
fn create_point_light(app_status: &AppStatus, intensity: f32) -> PointLight {
392442
PointLight {
393-
intensity: POINT_LIGHT_INTENSITY,
443+
intensity,
394444
range: POINT_LIGHT_RANGE,
395445
shadow_maps_enabled: true,
396446
radius: LIGHT_RADIUS,
@@ -402,9 +452,9 @@ fn create_point_light(app_status: &AppStatus) -> PointLight {
402452
}
403453

404454
/// Creates the [`SpotLight`] component with the appropriate settings.
405-
fn create_spot_light(app_status: &AppStatus) -> SpotLight {
455+
fn create_spot_light(app_status: &AppStatus, intensity: f32) -> SpotLight {
406456
SpotLight {
407-
intensity: POINT_LIGHT_INTENSITY,
457+
intensity,
408458
range: POINT_LIGHT_RANGE,
409459
radius: LIGHT_RADIUS,
410460
shadow_maps_enabled: true,

0 commit comments

Comments
 (0)