Skip to content

Commit 6beeaa8

Browse files
authored
Make PCSS experimental (#16382)
# Objective PCSS still has some fundamental issues (#16155). We should resolve them before "releasing" the feature. ## Solution 1. Rename the already-optional `pbr_pcss` cargo feature to `experimental_pbr_pcss` to better communicate its state to developers. 2. Adjust the description of the `experimental_pbr_pcss` cargo feature to better communicate its state to developers. 3. Gate PCSS-related light component fields behind that cargo feature, to prevent surfacing them to developers by default.
1 parent aab36f3 commit 6beeaa8

File tree

10 files changed

+41
-26
lines changed

10 files changed

+41
-26
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ pbr_multi_layer_material_textures = [
405405
pbr_anisotropy_texture = ["bevy_internal/pbr_anisotropy_texture"]
406406

407407
# Enable support for PCSS, at the risk of blowing past the global, per-shader sampler limit on older/lower-end GPUs
408-
pbr_pcss = ["bevy_internal/pbr_pcss"]
408+
experimental_pbr_pcss = ["bevy_internal/experimental_pbr_pcss"]
409409

410410
# Enable some limitations to be able to use WebGL2. Please refer to the [WebGL2 and WebGPU](https://github.com/bevyengine/bevy/tree/latest/examples#webgl2-and-webgpu) section of the examples README for more information on how to run Wasm builds with WebGPU.
411411
webgl2 = ["bevy_internal/webgl"]
@@ -3792,7 +3792,7 @@ wasm = true
37923792
name = "pcss"
37933793
path = "examples/3d/pcss.rs"
37943794
doc-scrape-examples = true
3795-
required-features = ["pbr_pcss"]
3795+
required-features = ["experimental_pbr_pcss"]
37963796

37973797
[package.metadata.example.pcss]
37983798
name = "Percentage-closer soft shadows"

crates/bevy_internal/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ pbr_anisotropy_texture = [
135135
]
136136

137137
# Percentage-closer soft shadows
138-
pbr_pcss = ["bevy_pbr?/pbr_pcss"]
138+
experimental_pbr_pcss = ["bevy_pbr?/experimental_pbr_pcss"]
139139

140140
# Optimise for WebGL2
141141
webgl = [

crates/bevy_pbr/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ webgpu = []
1414
pbr_transmission_textures = []
1515
pbr_multi_layer_material_textures = []
1616
pbr_anisotropy_texture = []
17-
pbr_pcss = []
17+
experimental_pbr_pcss = []
1818
shader_format_glsl = ["bevy_render/shader_format_glsl"]
1919
trace = ["bevy_render/trace"]
2020
ios_simulator = ["bevy_render/ios_simulator"]

crates/bevy_pbr/src/light/directional_light.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub struct DirectionalLight {
9595
///
9696
/// Note that soft shadows are significantly more expensive to render than
9797
/// hard shadows.
98+
#[cfg(feature = "experimental_pbr_pcss")]
9899
pub soft_shadow_size: Option<f32>,
99100

100101
/// A value that adjusts the tradeoff between self-shadowing artifacts and
@@ -120,9 +121,10 @@ impl Default for DirectionalLight {
120121
color: Color::WHITE,
121122
illuminance: light_consts::lux::AMBIENT_DAYLIGHT,
122123
shadows_enabled: false,
123-
soft_shadow_size: None,
124124
shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS,
125125
shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS,
126+
#[cfg(feature = "experimental_pbr_pcss")]
127+
soft_shadow_size: None,
126128
}
127129
}
128130
}

crates/bevy_pbr/src/light/point_light.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub struct PointLight {
6161
///
6262
/// Note that soft shadows are significantly more expensive to render than
6363
/// hard shadows.
64+
#[cfg(feature = "experimental_pbr_pcss")]
6465
pub soft_shadows_enabled: bool,
6566

6667
/// A bias used when sampling shadow maps to avoid "shadow-acne", or false shadow occlusions
@@ -95,10 +96,11 @@ impl Default for PointLight {
9596
range: 20.0,
9697
radius: 0.0,
9798
shadows_enabled: false,
98-
soft_shadows_enabled: false,
9999
shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS,
100100
shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS,
101101
shadow_map_near_z: Self::DEFAULT_SHADOW_MAP_NEAR_Z,
102+
#[cfg(feature = "experimental_pbr_pcss")]
103+
soft_shadows_enabled: false,
102104
}
103105
}
104106
}

crates/bevy_pbr/src/light/spot_light.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub struct SpotLight {
5757
///
5858
/// Note that soft shadows are significantly more expensive to render than
5959
/// hard shadows.
60+
#[cfg(feature = "experimental_pbr_pcss")]
6061
pub soft_shadows_enabled: bool,
6162

6263
/// A value that adjusts the tradeoff between self-shadowing artifacts and
@@ -115,12 +116,13 @@ impl Default for SpotLight {
115116
range: 20.0,
116117
radius: 0.0,
117118
shadows_enabled: false,
118-
soft_shadows_enabled: false,
119119
shadow_depth_bias: Self::DEFAULT_SHADOW_DEPTH_BIAS,
120120
shadow_normal_bias: Self::DEFAULT_SHADOW_NORMAL_BIAS,
121121
shadow_map_near_z: Self::DEFAULT_SHADOW_MAP_NEAR_Z,
122122
inner_angle: 0.0,
123123
outer_angle: core::f32::consts::FRAC_PI_4,
124+
#[cfg(feature = "experimental_pbr_pcss")]
125+
soft_shadows_enabled: false,
124126
}
125127
}
126128
}

crates/bevy_pbr/src/render/light.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ pub struct ExtractedPointLight {
4343
pub radius: f32,
4444
pub transform: GlobalTransform,
4545
pub shadows_enabled: bool,
46-
pub soft_shadows_enabled: bool,
4746
pub shadow_depth_bias: f32,
4847
pub shadow_normal_bias: f32,
4948
pub shadow_map_near_z: f32,
5049
pub spot_light_angles: Option<(f32, f32)>,
5150
pub volumetric: bool,
51+
pub soft_shadows_enabled: bool,
5252
}
5353

5454
#[derive(Component, Debug)]
@@ -58,13 +58,13 @@ pub struct ExtractedDirectionalLight {
5858
pub transform: GlobalTransform,
5959
pub shadows_enabled: bool,
6060
pub volumetric: bool,
61-
pub soft_shadow_size: Option<f32>,
6261
pub shadow_depth_bias: f32,
6362
pub shadow_normal_bias: f32,
6463
pub cascade_shadow_config: CascadeShadowConfig,
6564
pub cascades: EntityHashMap<Vec<Cascade>>,
6665
pub frusta: EntityHashMap<Vec<Frustum>>,
6766
pub render_layers: RenderLayers,
67+
pub soft_shadow_size: Option<f32>,
6868
}
6969

7070
// NOTE: These must match the bit flags in bevy_pbr/src/render/mesh_view_types.wgsl!
@@ -149,10 +149,10 @@ pub const MAX_CASCADES_PER_LIGHT: usize = 1;
149149
#[derive(Resource, Clone)]
150150
pub struct ShadowSamplers {
151151
pub point_light_comparison_sampler: Sampler,
152-
#[cfg(feature = "pbr_pcss")]
152+
#[cfg(feature = "experimental_pbr_pcss")]
153153
pub point_light_linear_sampler: Sampler,
154154
pub directional_light_comparison_sampler: Sampler,
155-
#[cfg(feature = "pbr_pcss")]
155+
#[cfg(feature = "experimental_pbr_pcss")]
156156
pub directional_light_linear_sampler: Sampler,
157157
}
158158

@@ -176,15 +176,15 @@ impl FromWorld for ShadowSamplers {
176176
compare: Some(CompareFunction::GreaterEqual),
177177
..base_sampler_descriptor
178178
}),
179-
#[cfg(feature = "pbr_pcss")]
179+
#[cfg(feature = "experimental_pbr_pcss")]
180180
point_light_linear_sampler: render_device.create_sampler(&base_sampler_descriptor),
181181
directional_light_comparison_sampler: render_device.create_sampler(
182182
&SamplerDescriptor {
183183
compare: Some(CompareFunction::GreaterEqual),
184184
..base_sampler_descriptor
185185
},
186186
),
187-
#[cfg(feature = "pbr_pcss")]
187+
#[cfg(feature = "experimental_pbr_pcss")]
188188
directional_light_linear_sampler: render_device
189189
.create_sampler(&base_sampler_descriptor),
190190
}
@@ -293,7 +293,6 @@ pub fn extract_lights(
293293
radius: point_light.radius,
294294
transform: *transform,
295295
shadows_enabled: point_light.shadows_enabled,
296-
soft_shadows_enabled: point_light.soft_shadows_enabled,
297296
shadow_depth_bias: point_light.shadow_depth_bias,
298297
// The factor of SQRT_2 is for the worst-case diagonal offset
299298
shadow_normal_bias: point_light.shadow_normal_bias
@@ -302,6 +301,10 @@ pub fn extract_lights(
302301
shadow_map_near_z: point_light.shadow_map_near_z,
303302
spot_light_angles: None,
304303
volumetric: volumetric_light.is_some(),
304+
#[cfg(feature = "experimental_pbr_pcss")]
305+
soft_shadows_enabled: point_light.soft_shadows_enabled,
306+
#[cfg(not(feature = "experimental_pbr_pcss"))]
307+
soft_shadows_enabled: false,
305308
};
306309
point_lights_values.push((
307310
render_entity,
@@ -352,7 +355,6 @@ pub fn extract_lights(
352355
radius: spot_light.radius,
353356
transform: *transform,
354357
shadows_enabled: spot_light.shadows_enabled,
355-
soft_shadows_enabled: spot_light.soft_shadows_enabled,
356358
shadow_depth_bias: spot_light.shadow_depth_bias,
357359
// The factor of SQRT_2 is for the worst-case diagonal offset
358360
shadow_normal_bias: spot_light.shadow_normal_bias
@@ -361,6 +363,10 @@ pub fn extract_lights(
361363
shadow_map_near_z: spot_light.shadow_map_near_z,
362364
spot_light_angles: Some((spot_light.inner_angle, spot_light.outer_angle)),
363365
volumetric: volumetric_light.is_some(),
366+
#[cfg(feature = "experimental_pbr_pcss")]
367+
soft_shadows_enabled: spot_light.soft_shadows_enabled,
368+
#[cfg(not(feature = "experimental_pbr_pcss"))]
369+
soft_shadows_enabled: false,
364370
},
365371
render_visible_entities,
366372
*frustum,
@@ -432,7 +438,10 @@ pub fn extract_lights(
432438
illuminance: directional_light.illuminance,
433439
transform: *transform,
434440
volumetric: volumetric_light.is_some(),
441+
#[cfg(feature = "experimental_pbr_pcss")]
435442
soft_shadow_size: directional_light.soft_shadow_size,
443+
#[cfg(not(feature = "experimental_pbr_pcss"))]
444+
soft_shadow_size: None,
436445
shadows_enabled: directional_light.shadows_enabled,
437446
shadow_depth_bias: directional_light.shadow_depth_bias,
438447
// The factor of SQRT_2 is for the worst-case diagonal offset
@@ -914,17 +923,17 @@ pub fn prepare_lights(
914923
.extend(1.0 / (light.range * light.range)),
915924
position_radius: light.transform.translation().extend(light.radius),
916925
flags: flags.bits(),
917-
soft_shadow_size: if light.soft_shadows_enabled {
918-
light.radius
919-
} else {
920-
0.0
921-
},
922926
shadow_depth_bias: light.shadow_depth_bias,
923927
shadow_normal_bias: light.shadow_normal_bias,
924928
shadow_map_near_z: light.shadow_map_near_z,
925929
spot_light_tan_angle,
926930
pad_a: 0.0,
927931
pad_b: 0.0,
932+
soft_shadow_size: if light.soft_shadows_enabled {
933+
light.radius
934+
} else {
935+
0.0
936+
},
928937
});
929938
global_light_meta.entity_to_index.insert(entity, index);
930939
}

crates/bevy_pbr/src/render/mesh.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1859,7 +1859,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
18591859
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
18601860
shader_defs.push("WEBGL2".into());
18611861

1862-
#[cfg(feature = "pbr_pcss")]
1862+
#[cfg(feature = "experimental_pbr_pcss")]
18631863
shader_defs.push("PCSS_SAMPLERS_AVAILABLE".into());
18641864

18651865
if key.contains(MeshPipelineKey::TONEMAP_IN_SHADER) {

crates/bevy_pbr/src/render/mesh_view_bindings.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ fn layout_entries(
228228
// Point Shadow Texture Array Comparison Sampler
229229
(3, sampler(SamplerBindingType::Comparison)),
230230
// Point Shadow Texture Array Linear Sampler
231-
#[cfg(feature = "pbr_pcss")]
231+
#[cfg(feature = "experimental_pbr_pcss")]
232232
(4, sampler(SamplerBindingType::Filtering)),
233233
// Directional Shadow Texture Array
234234
(
@@ -245,7 +245,7 @@ fn layout_entries(
245245
// Directional Shadow Texture Array Comparison Sampler
246246
(6, sampler(SamplerBindingType::Comparison)),
247247
// Directional Shadow Texture Array Linear Sampler
248-
#[cfg(feature = "pbr_pcss")]
248+
#[cfg(feature = "experimental_pbr_pcss")]
249249
(7, sampler(SamplerBindingType::Filtering)),
250250
// PointLights
251251
(
@@ -580,11 +580,11 @@ pub fn prepare_mesh_view_bind_groups(
580580
(1, light_binding.clone()),
581581
(2, &shadow_bindings.point_light_depth_texture_view),
582582
(3, &shadow_samplers.point_light_comparison_sampler),
583-
#[cfg(feature = "pbr_pcss")]
583+
#[cfg(feature = "experimental_pbr_pcss")]
584584
(4, &shadow_samplers.point_light_linear_sampler),
585585
(5, &shadow_bindings.directional_light_depth_texture_view),
586586
(6, &shadow_samplers.directional_light_comparison_sampler),
587-
#[cfg(feature = "pbr_pcss")]
587+
#[cfg(feature = "experimental_pbr_pcss")]
588588
(7, &shadow_samplers.directional_light_linear_sampler),
589589
(8, clusterable_objects_binding.clone()),
590590
(

docs/cargo_features.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ The default feature set enables most of the expected features of a game engine,
6767
|detailed_trace|Enable detailed trace event logging. These trace events are expensive even when off, thus they require compile time opt-in|
6868
|dynamic_linking|Force dynamic linking, which improves iterative compile times|
6969
|embedded_watcher|Enables watching in memory asset providers for Bevy Asset hot-reloading|
70+
|experimental_pbr_pcss|Enable support for PCSS, at the risk of blowing past the global, per-shader sampler limit on older/lower-end GPUs|
7071
|exr|EXR image format support|
7172
|ff|Farbfeld image format support|
7273
|file_watcher|Enables watching the filesystem for Bevy Asset hot-reloading|
@@ -83,7 +84,6 @@ The default feature set enables most of the expected features of a game engine,
8384
|mp3|MP3 audio format support|
8485
|pbr_anisotropy_texture|Enable support for anisotropy texture in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs|
8586
|pbr_multi_layer_material_textures|Enable support for multi-layer material textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs|
86-
|pbr_pcss|Enable support for PCSS, at the risk of blowing past the global, per-shader sampler limit on older/lower-end GPUs|
8787
|pbr_transmission_textures|Enable support for transmission-related textures in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs|
8888
|pnm|PNM image format support, includes pam, pbm, pgm and ppm|
8989
|qoi|QOI image format support|

0 commit comments

Comments
 (0)