From b5c0d57eb0724036ebf7b0b1438a67a113d9c680 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 22 Oct 2024 22:42:28 -0700 Subject: [PATCH 1/2] Place percentage-closer soft shadows behind a feature gate to save on samplers. 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 #15345. Closes #15525. Closes #15821. --- Cargo.toml | 4 ++++ crates/bevy_internal/Cargo.toml | 5 +++++ crates/bevy_pbr/Cargo.toml | 1 + crates/bevy_pbr/src/render/light.rs | 4 ++++ crates/bevy_pbr/src/render/mesh.rs | 3 +++ crates/bevy_pbr/src/render/mesh_view_bindings.rs | 4 ++++ crates/bevy_pbr/src/render/mesh_view_bindings.wgsl | 4 ++++ crates/bevy_pbr/src/render/shadow_sampling.wgsl | 12 ++++++++++++ docs/cargo_features.md | 1 + examples/shader/extended_material.rs | 2 +- 10 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 97c0d265da3ab..aacd2292b70ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -402,6 +402,9 @@ pbr_multi_layer_material_textures = [ # 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 pbr_anisotropy_texture = ["bevy_internal/pbr_anisotropy_texture"] +# Enable support for PCSS, at the risk of blowing past the global, per-shader sampler limit on older/lower-end GPUs +pbr_pcss = ["bevy_internal/pbr_pcss"] + # 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. webgl2 = ["bevy_internal/webgl"] @@ -3786,6 +3789,7 @@ wasm = true name = "pcss" path = "examples/3d/pcss.rs" doc-scrape-examples = true +required-features = ["pbr_pcss"] [package.metadata.example.pcss] name = "Percentage-closer soft shadows" diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 1a1930acc2095..95437fbe6a2b1 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -134,6 +134,11 @@ pbr_anisotropy_texture = [ "bevy_gltf?/pbr_anisotropy_texture", ] +# Percentage-closer soft shadows +pbr_pcss = [ + "bevy_pbr?/pbr_pcss", +] + # Optimise for WebGL2 webgl = [ "bevy_core_pipeline?/webgl", diff --git a/crates/bevy_pbr/Cargo.toml b/crates/bevy_pbr/Cargo.toml index 67552945fc87e..6f1d913c651fb 100644 --- a/crates/bevy_pbr/Cargo.toml +++ b/crates/bevy_pbr/Cargo.toml @@ -14,6 +14,7 @@ webgpu = [] pbr_transmission_textures = [] pbr_multi_layer_material_textures = [] pbr_anisotropy_texture = [] +pbr_pcss = [] shader_format_glsl = ["bevy_render/shader_format_glsl"] trace = ["bevy_render/trace"] ios_simulator = ["bevy_render/ios_simulator"] diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 4d64a6a306cfc..bd0248789d5b3 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -147,8 +147,10 @@ pub const MAX_CASCADES_PER_LIGHT: usize = 1; #[derive(Resource, Clone)] pub struct ShadowSamplers { pub point_light_comparison_sampler: Sampler, + #[cfg(feature = "pbr_pcss")] pub point_light_linear_sampler: Sampler, pub directional_light_comparison_sampler: Sampler, + #[cfg(feature = "pbr_pcss")] pub directional_light_linear_sampler: Sampler, } @@ -172,6 +174,7 @@ impl FromWorld for ShadowSamplers { compare: Some(CompareFunction::GreaterEqual), ..base_sampler_descriptor }), + #[cfg(feature = "pbr_pcss")] point_light_linear_sampler: render_device.create_sampler(&base_sampler_descriptor), directional_light_comparison_sampler: render_device.create_sampler( &SamplerDescriptor { @@ -179,6 +182,7 @@ impl FromWorld for ShadowSamplers { ..base_sampler_descriptor }, ), + #[cfg(feature = "pbr_pcss")] directional_light_linear_sampler: render_device .create_sampler(&base_sampler_descriptor), } diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index af6621eb259e6..e996dbb8f0436 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -1858,6 +1858,9 @@ impl SpecializedMeshPipeline for MeshPipeline { #[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))] shader_defs.push("WEBGL2".into()); + #[cfg(feature = "pbr_pcss")] + shader_defs.push("PCSS_SAMPLERS_AVAILABLE".into()); + if key.contains(MeshPipelineKey::TONEMAP_IN_SHADER) { shader_defs.push("TONEMAP_IN_SHADER".into()); shader_defs.push(ShaderDefVal::UInt( diff --git a/crates/bevy_pbr/src/render/mesh_view_bindings.rs b/crates/bevy_pbr/src/render/mesh_view_bindings.rs index 8a55aecacc545..9596eec7299d7 100644 --- a/crates/bevy_pbr/src/render/mesh_view_bindings.rs +++ b/crates/bevy_pbr/src/render/mesh_view_bindings.rs @@ -227,6 +227,7 @@ fn layout_entries( // Point Shadow Texture Array Comparison Sampler (3, sampler(SamplerBindingType::Comparison)), // Point Shadow Texture Array Linear Sampler + #[cfg(feature = "pbr_pcss")] (4, sampler(SamplerBindingType::Filtering)), // Directional Shadow Texture Array ( @@ -243,6 +244,7 @@ fn layout_entries( // Directional Shadow Texture Array Comparison Sampler (6, sampler(SamplerBindingType::Comparison)), // Directional Shadow Texture Array Linear Sampler + #[cfg(feature = "pbr_pcss")] (7, sampler(SamplerBindingType::Filtering)), // PointLights ( @@ -574,9 +576,11 @@ pub fn prepare_mesh_view_bind_groups( (1, light_binding.clone()), (2, &shadow_bindings.point_light_depth_texture_view), (3, &shadow_samplers.point_light_comparison_sampler), + #[cfg(feature = "pbr_pcss")] (4, &shadow_samplers.point_light_linear_sampler), (5, &shadow_bindings.directional_light_depth_texture_view), (6, &shadow_samplers.directional_light_comparison_sampler), + #[cfg(feature = "pbr_pcss")] (7, &shadow_samplers.directional_light_linear_sampler), (8, clusterable_objects_binding.clone()), ( diff --git a/crates/bevy_pbr/src/render/mesh_view_bindings.wgsl b/crates/bevy_pbr/src/render/mesh_view_bindings.wgsl index e777b20358330..e4f7f6ece0758 100644 --- a/crates/bevy_pbr/src/render/mesh_view_bindings.wgsl +++ b/crates/bevy_pbr/src/render/mesh_view_bindings.wgsl @@ -14,14 +14,18 @@ @group(0) @binding(2) var point_shadow_textures: texture_depth_cube_array; #endif @group(0) @binding(3) var point_shadow_textures_comparison_sampler: sampler_comparison; +#ifdef PCSS_SAMPLERS_AVAILABLE @group(0) @binding(4) var point_shadow_textures_linear_sampler: sampler; +#endif // PCSS_SAMPLERS_AVAILABLE #ifdef NO_ARRAY_TEXTURES_SUPPORT @group(0) @binding(5) var directional_shadow_textures: texture_depth_2d; #else @group(0) @binding(5) var directional_shadow_textures: texture_depth_2d_array; #endif @group(0) @binding(6) var directional_shadow_textures_comparison_sampler: sampler_comparison; +#ifdef PCSS_SAMPLERS_AVAILABLE @group(0) @binding(7) var directional_shadow_textures_linear_sampler: sampler; +#endif // PCSS_SAMPLERS_AVAILABLE #if AVAILABLE_STORAGE_BUFFER_BINDINGS >= 3 @group(0) @binding(8) var clusterable_objects: types::ClusterableObjects; diff --git a/crates/bevy_pbr/src/render/shadow_sampling.wgsl b/crates/bevy_pbr/src/render/shadow_sampling.wgsl index 0c546a37c6d3e..22f2e28310bd0 100644 --- a/crates/bevy_pbr/src/render/shadow_sampling.wgsl +++ b/crates/bevy_pbr/src/render/shadow_sampling.wgsl @@ -40,6 +40,8 @@ fn search_for_blockers_in_shadow_map_hardware( return vec2(0.0); #else // WEBGL2 +#ifdef PCSS_SAMPLERS_AVAILABLE + #ifdef NO_ARRAY_TEXTURES_SUPPORT let sampled_depth = textureSampleLevel( view_bindings::directional_shadow_textures, @@ -58,6 +60,10 @@ fn search_for_blockers_in_shadow_map_hardware( #endif // NO_ARRAY_TEXTURES_SUPPORT return select(vec2(0.0), vec2(sampled_depth, 1.0), sampled_depth >= depth); +#else // PCSS_SAMPLERS_AVAILABLE + return vec2(0.0); +#endif // PCSS_SAMPLERS_AVAILABLE + #endif // WEBGL2 } @@ -340,6 +346,8 @@ fn search_for_blockers_in_shadow_cubemap_hardware( return vec2(0.0); #else // WEBGL2 +#ifdef PCSS_SAMPLERS_AVAILABLE + #ifdef NO_CUBE_ARRAY_TEXTURES_SUPPORT let sampled_depth = textureSample( view_bindings::point_shadow_textures, @@ -357,6 +365,10 @@ fn search_for_blockers_in_shadow_cubemap_hardware( return select(vec2(0.0), vec2(sampled_depth, 1.0), sampled_depth >= depth); +#else // PCSS_SAMPLERS_AVAILABLE + return vec2(0.0); +#endif // PCSS_SAMPLERS_AVAILABLE + #endif // WEBGL2 } diff --git a/docs/cargo_features.md b/docs/cargo_features.md index b0434e72bdebb..bb9d8d47aeff9 100644 --- a/docs/cargo_features.md +++ b/docs/cargo_features.md @@ -83,6 +83,7 @@ The default feature set enables most of the expected features of a game engine, |mp3|MP3 audio format support| |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| |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| +|pbr_pcss|Enable support for PCSS, at the risk of blowing past the global, per-shader sampler limit on older/lower-end GPUs| |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| |pnm|PNM image format support, includes pam, pbm, pgm and ppm| |qoi|QOI image format support| diff --git a/examples/shader/extended_material.rs b/examples/shader/extended_material.rs index c35f168e4c421..3c5102db8ae58 100644 --- a/examples/shader/extended_material.rs +++ b/examples/shader/extended_material.rs @@ -32,7 +32,7 @@ fn setup( MeshMaterial3d(materials.add(ExtendedMaterial { base: StandardMaterial { base_color: RED.into(), - // can be used in forward or deferred mode. + // can be used in forward or deferred mode opaque_render_method: OpaqueRendererMethod::Auto, // in deferred mode, only the PbrInput can be modified (uvs, color and other material properties), // in forward mode, the output can also be modified after lighting is applied. From 1ea1cd786f8b62bf9a2aef1a88203aa6c496358a Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Thu, 24 Oct 2024 14:02:14 -0700 Subject: [PATCH 2/2] Update crates/bevy_internal/Cargo.toml Co-authored-by: IceSentry --- crates/bevy_internal/Cargo.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 95437fbe6a2b1..74267a4797356 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -135,9 +135,7 @@ pbr_anisotropy_texture = [ ] # Percentage-closer soft shadows -pbr_pcss = [ - "bevy_pbr?/pbr_pcss", -] +pbr_pcss = ["bevy_pbr?/pbr_pcss"] # Optimise for WebGL2 webgl = [