Skip to content

Commit 6ad93ed

Browse files
authored
Correctly disable prepass/shadows when configured on MaterialPlugin<M> (#19890)
Previously, the specialize/queue systems were added per-material and the plugin prepass/shadow enable flags controlled whether we added those systems. Now, we make this a property of the material instance and check for it when specializing. Fixes #19850.
1 parent e072625 commit 6ad93ed

File tree

4 files changed

+68
-15
lines changed

4 files changed

+68
-15
lines changed

crates/bevy_pbr/src/light/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use core::ops::DerefMut;
2-
31
use bevy_ecs::{
42
entity::{EntityHashMap, EntityHashSet},
53
prelude::*,
@@ -19,6 +17,7 @@ use bevy_render::{
1917
};
2018
use bevy_transform::components::{GlobalTransform, Transform};
2119
use bevy_utils::Parallel;
20+
use core::{marker::PhantomData, ops::DerefMut};
2221

2322
use crate::*;
2423

@@ -91,6 +90,16 @@ pub mod light_consts {
9190
}
9291
}
9392

93+
/// Marker resource for whether shadows are enabled for this material type
94+
#[derive(Resource, Debug)]
95+
pub struct ShadowsEnabled<M: Material>(PhantomData<M>);
96+
97+
impl<M: Material> Default for ShadowsEnabled<M> {
98+
fn default() -> Self {
99+
Self(PhantomData)
100+
}
101+
}
102+
94103
/// Controls the resolution of [`PointLight`] shadow maps.
95104
///
96105
/// ```

crates/bevy_pbr/src/material.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,13 @@ where
372372
}
373373

374374
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
375+
if self.prepass_enabled {
376+
render_app.init_resource::<PrepassEnabled<M>>();
377+
}
378+
if self.shadows_enabled {
379+
render_app.init_resource::<ShadowsEnabled<M>>();
380+
}
381+
375382
render_app
376383
.add_systems(RenderStartup, setup_render_app::<M>)
377384
.add_systems(
@@ -1316,6 +1323,10 @@ pub struct MaterialProperties {
13161323
/// The key for this material, typically a bitfield of flags that are used to modify
13171324
/// the pipeline descriptor used for this material.
13181325
pub material_key: SmallVec<[u8; 8]>,
1326+
/// Whether shadows are enabled for this material
1327+
pub shadows_enabled: bool,
1328+
/// Whether prepass is enabled for this material
1329+
pub prepass_enabled: bool,
13191330
}
13201331

13211332
impl MaterialProperties {
@@ -1394,7 +1405,11 @@ where
13941405
SRes<DrawFunctions<AlphaMask3dDeferred>>,
13951406
SRes<DrawFunctions<Shadow>>,
13961407
SRes<AssetServer>,
1397-
M::Param,
1408+
(
1409+
Option<SRes<ShadowsEnabled<M>>>,
1410+
Option<SRes<PrepassEnabled<M>>>,
1411+
M::Param,
1412+
),
13981413
);
13991414

14001415
fn prepare_asset(
@@ -1415,10 +1430,14 @@ where
14151430
alpha_mask_deferred_draw_functions,
14161431
shadow_draw_functions,
14171432
asset_server,
1418-
material_param,
1433+
(shadows_enabled, prepass_enabled, material_param),
14191434
): &mut SystemParamItem<Self::Param>,
14201435
) -> Result<Self::ErasedAsset, PrepareAssetError<Self::SourceAsset>> {
14211436
let material_layout = M::bind_group_layout(render_device);
1437+
1438+
let shadows_enabled = shadows_enabled.is_some();
1439+
let prepass_enabled = prepass_enabled.is_some();
1440+
14221441
let draw_opaque_pbr = opaque_draw_functions.read().id::<DrawMaterial>();
14231442
let draw_alpha_mask_pbr = alpha_mask_draw_functions.read().id::<DrawMaterial>();
14241443
let draw_transmissive_pbr = transmissive_draw_functions.read().id::<DrawMaterial>();
@@ -1584,6 +1603,8 @@ where
15841603
bindless,
15851604
specialize: Some(specialize::<M>),
15861605
material_key,
1606+
shadows_enabled,
1607+
prepass_enabled,
15871608
}),
15881609
})
15891610
}
@@ -1621,6 +1642,8 @@ where
16211642
bindless,
16221643
specialize: Some(specialize::<M>),
16231644
material_key,
1645+
shadows_enabled,
1646+
prepass_enabled,
16241647
}),
16251648
})
16261649
}

crates/bevy_pbr/src/prepass/mod.rs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ use crate::{
44
alpha_mode_pipeline_key, binding_arrays_are_usable, buffer_layout,
55
collect_meshes_for_gpu_building, set_mesh_motion_vector_flags, setup_morph_and_skinning_defs,
66
skin, DeferredDrawFunction, DeferredFragmentShader, DeferredVertexShader, DrawMesh,
7-
EntitySpecializationTicks, ErasedMaterialPipelineKey, MaterialPipeline, MaterialProperties,
8-
MeshLayouts, MeshPipeline, MeshPipelineKey, OpaqueRendererMethod, PreparedMaterial,
9-
PrepassDrawFunction, PrepassFragmentShader, PrepassVertexShader, RenderLightmaps,
10-
RenderMaterialInstances, RenderMeshInstanceFlags, RenderMeshInstances, RenderPhaseType,
11-
SetMaterialBindGroup, SetMeshBindGroup, ShadowView,
7+
EntitySpecializationTicks, ErasedMaterialPipelineKey, Material, MaterialPipeline,
8+
MaterialProperties, MeshLayouts, MeshPipeline, MeshPipelineKey, OpaqueRendererMethod,
9+
PreparedMaterial, PrepassDrawFunction, PrepassFragmentShader, PrepassVertexShader,
10+
RenderLightmaps, RenderMaterialInstances, RenderMeshInstanceFlags, RenderMeshInstances,
11+
RenderPhaseType, SetMaterialBindGroup, SetMeshBindGroup, ShadowView,
1212
};
1313
use bevy_app::{App, Plugin, PreUpdate};
1414
use bevy_render::{
@@ -58,13 +58,15 @@ use crate::meshlet::{
5858

5959
use alloc::sync::Arc;
6060
use bevy_derive::{Deref, DerefMut};
61-
use bevy_ecs::component::Tick;
62-
use bevy_ecs::system::SystemChangeTick;
61+
use bevy_ecs::{component::Tick, system::SystemChangeTick};
6362
use bevy_platform::collections::HashMap;
64-
use bevy_render::erased_render_asset::ErasedRenderAssets;
65-
use bevy_render::sync_world::MainEntityHashMap;
66-
use bevy_render::view::RenderVisibleEntities;
67-
use bevy_render::RenderSystems::{PrepareAssets, PrepareResources};
63+
use bevy_render::{
64+
erased_render_asset::ErasedRenderAssets,
65+
sync_world::MainEntityHashMap,
66+
view::RenderVisibleEntities,
67+
RenderSystems::{PrepareAssets, PrepareResources},
68+
};
69+
use core::marker::PhantomData;
6870

6971
/// Sets up everything required to use the prepass pipeline.
7072
///
@@ -188,6 +190,16 @@ impl Plugin for PrepassPlugin {
188190
}
189191
}
190192

193+
/// Marker resource for whether prepass is enabled globally for this material type
194+
#[derive(Resource, Debug)]
195+
pub struct PrepassEnabled<M: Material>(PhantomData<M>);
196+
197+
impl<M: Material> Default for PrepassEnabled<M> {
198+
fn default() -> Self {
199+
PrepassEnabled(PhantomData)
200+
}
201+
}
202+
191203
#[derive(Resource)]
192204
struct AnyPrepassPluginLoaded;
193205

@@ -911,6 +923,11 @@ pub fn specialize_prepass_material_meshes(
911923
let Some(material) = render_materials.get(material_instance.asset_id) else {
912924
continue;
913925
};
926+
if !material.properties.prepass_enabled && !material.properties.shadows_enabled {
927+
// If the material was previously specialized for prepass, remove it
928+
view_specialized_material_pipeline_cache.remove(visible_entity);
929+
continue;
930+
}
914931
let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id) else {
915932
continue;
916933
};

crates/bevy_pbr/src/render/light.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,6 +1891,10 @@ pub fn specialize_shadows(
18911891
let Some(material) = render_materials.get(material_instance.asset_id) else {
18921892
continue;
18931893
};
1894+
if !material.properties.shadows_enabled {
1895+
// If the material is not a shadow caster, we don't need to specialize it.
1896+
continue;
1897+
}
18941898
if !mesh_instance
18951899
.flags
18961900
.contains(RenderMeshInstanceFlags::SHADOW_CASTER)

0 commit comments

Comments
 (0)