Skip to content

Commit c6a66a7

Browse files
pcwaltoncartIceSentry
authored
Place percentage-closer soft shadows behind a feature gate to save on samplers. (bevyengine#16068)
The two additional linear texture samplers that PCSS added caused us to blow past the limit on Apple Silicon macOS and WebGL. To fix the issue, this commit adds a `--feature pbr_pcss` feature gate that disables PCSS if not present. Closes bevyengine#15345. Closes bevyengine#15525. Closes bevyengine#15821. --------- Co-authored-by: Carter Anderson <[email protected]> Co-authored-by: IceSentry <[email protected]>
1 parent 897404e commit c6a66a7

File tree

10 files changed

+37
-1
lines changed

10 files changed

+37
-1
lines changed

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,9 @@ pbr_multi_layer_material_textures = [
402402
# 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
403403
pbr_anisotropy_texture = ["bevy_internal/pbr_anisotropy_texture"]
404404

405+
# Enable support for PCSS, at the risk of blowing past the global, per-shader sampler limit on older/lower-end GPUs
406+
pbr_pcss = ["bevy_internal/pbr_pcss"]
407+
405408
# 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.
406409
webgl2 = ["bevy_internal/webgl"]
407410

@@ -3786,6 +3789,7 @@ wasm = true
37863789
name = "pcss"
37873790
path = "examples/3d/pcss.rs"
37883791
doc-scrape-examples = true
3792+
required-features = ["pbr_pcss"]
37893793

37903794
[package.metadata.example.pcss]
37913795
name = "Percentage-closer soft shadows"

crates/bevy_internal/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ pbr_anisotropy_texture = [
134134
"bevy_gltf?/pbr_anisotropy_texture",
135135
]
136136

137+
# Percentage-closer soft shadows
138+
pbr_pcss = ["bevy_pbr?/pbr_pcss"]
139+
137140
# Optimise for WebGL2
138141
webgl = [
139142
"bevy_core_pipeline?/webgl",

crates/bevy_pbr/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ webgpu = []
1414
pbr_transmission_textures = []
1515
pbr_multi_layer_material_textures = []
1616
pbr_anisotropy_texture = []
17+
pbr_pcss = []
1718
shader_format_glsl = ["bevy_render/shader_format_glsl"]
1819
trace = ["bevy_render/trace"]
1920
ios_simulator = ["bevy_render/ios_simulator"]

crates/bevy_pbr/src/render/light.rs

+4
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ pub const MAX_CASCADES_PER_LIGHT: usize = 1;
147147
#[derive(Resource, Clone)]
148148
pub struct ShadowSamplers {
149149
pub point_light_comparison_sampler: Sampler,
150+
#[cfg(feature = "pbr_pcss")]
150151
pub point_light_linear_sampler: Sampler,
151152
pub directional_light_comparison_sampler: Sampler,
153+
#[cfg(feature = "pbr_pcss")]
152154
pub directional_light_linear_sampler: Sampler,
153155
}
154156

@@ -172,13 +174,15 @@ impl FromWorld for ShadowSamplers {
172174
compare: Some(CompareFunction::GreaterEqual),
173175
..base_sampler_descriptor
174176
}),
177+
#[cfg(feature = "pbr_pcss")]
175178
point_light_linear_sampler: render_device.create_sampler(&base_sampler_descriptor),
176179
directional_light_comparison_sampler: render_device.create_sampler(
177180
&SamplerDescriptor {
178181
compare: Some(CompareFunction::GreaterEqual),
179182
..base_sampler_descriptor
180183
},
181184
),
185+
#[cfg(feature = "pbr_pcss")]
182186
directional_light_linear_sampler: render_device
183187
.create_sampler(&base_sampler_descriptor),
184188
}

crates/bevy_pbr/src/render/mesh.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1858,6 +1858,9 @@ impl SpecializedMeshPipeline for MeshPipeline {
18581858
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
18591859
shader_defs.push("WEBGL2".into());
18601860

1861+
#[cfg(feature = "pbr_pcss")]
1862+
shader_defs.push("PCSS_SAMPLERS_AVAILABLE".into());
1863+
18611864
if key.contains(MeshPipelineKey::TONEMAP_IN_SHADER) {
18621865
shader_defs.push("TONEMAP_IN_SHADER".into());
18631866
shader_defs.push(ShaderDefVal::UInt(

crates/bevy_pbr/src/render/mesh_view_bindings.rs

+4
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ fn layout_entries(
227227
// Point Shadow Texture Array Comparison Sampler
228228
(3, sampler(SamplerBindingType::Comparison)),
229229
// Point Shadow Texture Array Linear Sampler
230+
#[cfg(feature = "pbr_pcss")]
230231
(4, sampler(SamplerBindingType::Filtering)),
231232
// Directional Shadow Texture Array
232233
(
@@ -243,6 +244,7 @@ fn layout_entries(
243244
// Directional Shadow Texture Array Comparison Sampler
244245
(6, sampler(SamplerBindingType::Comparison)),
245246
// Directional Shadow Texture Array Linear Sampler
247+
#[cfg(feature = "pbr_pcss")]
246248
(7, sampler(SamplerBindingType::Filtering)),
247249
// PointLights
248250
(
@@ -574,9 +576,11 @@ pub fn prepare_mesh_view_bind_groups(
574576
(1, light_binding.clone()),
575577
(2, &shadow_bindings.point_light_depth_texture_view),
576578
(3, &shadow_samplers.point_light_comparison_sampler),
579+
#[cfg(feature = "pbr_pcss")]
577580
(4, &shadow_samplers.point_light_linear_sampler),
578581
(5, &shadow_bindings.directional_light_depth_texture_view),
579582
(6, &shadow_samplers.directional_light_comparison_sampler),
583+
#[cfg(feature = "pbr_pcss")]
580584
(7, &shadow_samplers.directional_light_linear_sampler),
581585
(8, clusterable_objects_binding.clone()),
582586
(

crates/bevy_pbr/src/render/mesh_view_bindings.wgsl

+4
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@
1414
@group(0) @binding(2) var point_shadow_textures: texture_depth_cube_array;
1515
#endif
1616
@group(0) @binding(3) var point_shadow_textures_comparison_sampler: sampler_comparison;
17+
#ifdef PCSS_SAMPLERS_AVAILABLE
1718
@group(0) @binding(4) var point_shadow_textures_linear_sampler: sampler;
19+
#endif // PCSS_SAMPLERS_AVAILABLE
1820
#ifdef NO_ARRAY_TEXTURES_SUPPORT
1921
@group(0) @binding(5) var directional_shadow_textures: texture_depth_2d;
2022
#else
2123
@group(0) @binding(5) var directional_shadow_textures: texture_depth_2d_array;
2224
#endif
2325
@group(0) @binding(6) var directional_shadow_textures_comparison_sampler: sampler_comparison;
26+
#ifdef PCSS_SAMPLERS_AVAILABLE
2427
@group(0) @binding(7) var directional_shadow_textures_linear_sampler: sampler;
28+
#endif // PCSS_SAMPLERS_AVAILABLE
2529

2630
#if AVAILABLE_STORAGE_BUFFER_BINDINGS >= 3
2731
@group(0) @binding(8) var<storage> clusterable_objects: types::ClusterableObjects;

crates/bevy_pbr/src/render/shadow_sampling.wgsl

+12
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ fn search_for_blockers_in_shadow_map_hardware(
4040
return vec2(0.0);
4141
#else // WEBGL2
4242

43+
#ifdef PCSS_SAMPLERS_AVAILABLE
44+
4345
#ifdef NO_ARRAY_TEXTURES_SUPPORT
4446
let sampled_depth = textureSampleLevel(
4547
view_bindings::directional_shadow_textures,
@@ -58,6 +60,10 @@ fn search_for_blockers_in_shadow_map_hardware(
5860
#endif // NO_ARRAY_TEXTURES_SUPPORT
5961
return select(vec2(0.0), vec2(sampled_depth, 1.0), sampled_depth >= depth);
6062

63+
#else // PCSS_SAMPLERS_AVAILABLE
64+
return vec2(0.0);
65+
#endif // PCSS_SAMPLERS_AVAILABLE
66+
6167
#endif // WEBGL2
6268
}
6369

@@ -340,6 +346,8 @@ fn search_for_blockers_in_shadow_cubemap_hardware(
340346
return vec2(0.0);
341347
#else // WEBGL2
342348

349+
#ifdef PCSS_SAMPLERS_AVAILABLE
350+
343351
#ifdef NO_CUBE_ARRAY_TEXTURES_SUPPORT
344352
let sampled_depth = textureSample(
345353
view_bindings::point_shadow_textures,
@@ -357,6 +365,10 @@ fn search_for_blockers_in_shadow_cubemap_hardware(
357365

358366
return select(vec2(0.0), vec2(sampled_depth, 1.0), sampled_depth >= depth);
359367

368+
#else // PCSS_SAMPLERS_AVAILABLE
369+
return vec2(0.0);
370+
#endif // PCSS_SAMPLERS_AVAILABLE
371+
360372
#endif // WEBGL2
361373
}
362374

docs/cargo_features.md

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ The default feature set enables most of the expected features of a game engine,
8383
|mp3|MP3 audio format support|
8484
|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|
8585
|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|
8687
|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|
8788
|pnm|PNM image format support, includes pam, pbm, pgm and ppm|
8889
|qoi|QOI image format support|

examples/shader/extended_material.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn setup(
3232
MeshMaterial3d(materials.add(ExtendedMaterial {
3333
base: StandardMaterial {
3434
base_color: RED.into(),
35-
// can be used in forward or deferred mode.
35+
// can be used in forward or deferred mode
3636
opaque_render_method: OpaqueRendererMethod::Auto,
3737
// in deferred mode, only the PbrInput can be modified (uvs, color and other material properties),
3838
// in forward mode, the output can also be modified after lighting is applied.

0 commit comments

Comments
 (0)