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.

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.
  • Loading branch information
pcwalton committed Oct 23, 2024
1 parent 50d38f2 commit b5c0d57
Show file tree
Hide file tree
Showing 10 changed files with 39 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
5 changes: 5 additions & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
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 b5c0d57

Please sign in to comment.