Skip to content

Commit

Permalink
Place percentage-closer soft shadows behind a feature gate to save on…
Browse files Browse the repository at this point in the history
… samplers. (#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 #15345.
Closes #15525.
Closes #15821.

---------

Co-authored-by: Carter Anderson <[email protected]>
Co-authored-by: IceSentry <[email protected]>
  • Loading branch information
3 people authored Oct 24, 2024
1 parent 897404e commit c6a66a7
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ 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",
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_pbr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_pbr/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand All @@ -172,13 +174,15 @@ 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 {
compare: Some(CompareFunction::GreaterEqual),
..base_sampler_descriptor
},
),
#[cfg(feature = "pbr_pcss")]
directional_light_linear_sampler: render_device
.create_sampler(&base_sampler_descriptor),
}
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_pbr/src/render/mesh_view_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
(
Expand All @@ -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
(
Expand Down Expand Up @@ -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()),
(
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_pbr/src/render/mesh_view_bindings.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -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<storage> clusterable_objects: types::ClusterableObjects;
Expand Down
12 changes: 12 additions & 0 deletions crates/bevy_pbr/src/render/shadow_sampling.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
}

Expand Down Expand Up @@ -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,
Expand All @@ -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
}

Expand Down
1 change: 1 addition & 0 deletions docs/cargo_features.md
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down
2 changes: 1 addition & 1 deletion examples/shader/extended_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit c6a66a7

Please sign in to comment.