Remove prepasses from the render world when they're removed from the main world. (#17565)

This makes switching rendering modes in `deferred_rendering` work again.

Closes #16679.
This commit is contained in:
Patrick Walton 2025-02-13 22:43:35 -08:00 committed by GitHub
parent 0f1c75796b
commit 6b837dd297
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 56 additions and 27 deletions

View File

@ -718,13 +718,35 @@ pub fn extract_camera_prepass_phase(
}
live_entities.insert(retained_view_entity);
commands
// Add or remove prepasses as appropriate.
let mut camera_commands = commands
.get_entity(entity)
.expect("Camera entity wasn't synced.")
.insert_if(DepthPrepass, || depth_prepass)
.insert_if(NormalPrepass, || normal_prepass)
.insert_if(MotionVectorPrepass, || motion_vector_prepass)
.insert_if(DeferredPrepass, || deferred_prepass);
.expect("Camera entity wasn't synced.");
if depth_prepass {
camera_commands.insert(DepthPrepass);
} else {
camera_commands.remove::<DepthPrepass>();
}
if normal_prepass {
camera_commands.insert(NormalPrepass);
} else {
camera_commands.remove::<NormalPrepass>();
}
if motion_vector_prepass {
camera_commands.insert(MotionVectorPrepass);
} else {
camera_commands.remove::<MotionVectorPrepass>();
}
if deferred_prepass {
camera_commands.insert(DeferredPrepass);
} else {
camera_commands.remove::<DeferredPrepass>();
}
}
opaque_3d_prepass_phases.retain(|view_entity, _| live_entities.contains(view_entity));
@ -986,6 +1008,7 @@ pub fn prepare_prepass_textures(
&& !opaque_3d_deferred_phases.contains_key(&view.retained_view_entity)
&& !alpha_mask_3d_deferred_phases.contains_key(&view.retained_view_entity)
{
commands.entity(entity).remove::<ViewPrepassTextures>();
continue;
};

View File

@ -432,28 +432,26 @@ pub fn prepare_deferred_lighting_pipelines(
pipeline_cache: Res<PipelineCache>,
mut pipelines: ResMut<SpecializedRenderPipelines<DeferredLightingLayout>>,
deferred_lighting_layout: Res<DeferredLightingLayout>,
views: Query<
views: Query<(
Entity,
&ExtractedView,
Option<&Tonemapping>,
Option<&DebandDither>,
Option<&ShadowFilteringMethod>,
(
Entity,
&ExtractedView,
Option<&Tonemapping>,
Option<&DebandDither>,
Option<&ShadowFilteringMethod>,
(
Has<ScreenSpaceAmbientOcclusion>,
Has<ScreenSpaceReflectionsUniform>,
Has<DistanceFog>,
),
(
Has<NormalPrepass>,
Has<DepthPrepass>,
Has<MotionVectorPrepass>,
),
Has<RenderViewLightProbes<EnvironmentMapLight>>,
Has<RenderViewLightProbes<IrradianceVolume>>,
Has<ScreenSpaceAmbientOcclusion>,
Has<ScreenSpaceReflectionsUniform>,
Has<DistanceFog>,
),
With<DeferredPrepass>,
>,
(
Has<NormalPrepass>,
Has<DepthPrepass>,
Has<MotionVectorPrepass>,
Has<DeferredPrepass>,
),
Has<RenderViewLightProbes<EnvironmentMapLight>>,
Has<RenderViewLightProbes<IrradianceVolume>>,
)>,
) {
for (
entity,
@ -462,11 +460,19 @@ pub fn prepare_deferred_lighting_pipelines(
dither,
shadow_filter_method,
(ssao, ssr, distance_fog),
(normal_prepass, depth_prepass, motion_vector_prepass),
(normal_prepass, depth_prepass, motion_vector_prepass, deferred_prepass),
has_environment_maps,
has_irradiance_volumes,
) in &views
{
// If there is no deferred prepass, remove the old pipeline if there was
// one. This handles the case in which a view using deferred stops using
// it.
if !deferred_prepass {
commands.entity(entity).remove::<DeferredLightingPipeline>();
continue;
}
let mut view_key = MeshPipelineKey::from_hdr(view.hdr);
if normal_prepass {