Make setup of Opaque3dPrepass and AlphaMask3dPrepass phase items consistent with others (#8408)
# Objective When browsing the bevy source code to try and learn about `bevy_core_pipeline`, I noticed that the `DrawFunctions` resources, `sort_phase_system`s and texture preparation for the `Opaque3d` and `AlphaMask3d` phase items are all set up in `bevy_core_pipeline`, while the `Opaque3dPrepass` and `AlphaMask3dPrepass` phase items are only *declared* in `bevy_core_pipeline`, and actually registered properly with the renderer in `bevy_pbr`. This means that, if I am trying to make crate that replaces `bevy_pbr`, I need to make sure I manually fix this unfinished setup the same way that `bevy_pbr` does. Worse, it means that if I try to use the `PrepassNode` `bevy_core_pipeline` adds *without* fixing this, the engine will simply crash because the `DrawFunctions<T>` resources cannot be accessed. The only advantage I can think of for bevy doing it this way is an ambiguous performance save due to the prepass render phases not being present unless you are using prepass materials with PBR. ## Solution I have moved the registration of `DrawFunctions<T>`, `sort_phase_system::<T>`, camera `RenderPhase` extraction, and texture preparation for prepass's phase items into `bevy_core_pipeline` alongside the equivalent code that sets up the `Opaque3d`, `AlphaMask3d` and `Transparent3d` phase items. Am open to tweaking this to improve the performance impact of prepass things being around if the app doesn't use them if needed. I've tested that the `shader_prepass` example still works with this change.
This commit is contained in:
		
							parent
							
								
									584e7d00ff
								
							
						
					
					
						commit
						a78c4d78d5
					
				@ -53,7 +53,11 @@ use bevy_render::{
 | 
				
			|||||||
use bevy_utils::{FloatOrd, HashMap};
 | 
					use bevy_utils::{FloatOrd, HashMap};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    prepass::{node::PrepassNode, DepthPrepass},
 | 
					    prepass::{
 | 
				
			||||||
 | 
					        node::PrepassNode, AlphaMask3dPrepass, DepthPrepass, MotionVectorPrepass, NormalPrepass,
 | 
				
			||||||
 | 
					        Opaque3dPrepass, ViewPrepassTextures, DEPTH_PREPASS_FORMAT, MOTION_VECTOR_PREPASS_FORMAT,
 | 
				
			||||||
 | 
					        NORMAL_PREPASS_FORMAT,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    skybox::SkyboxPlugin,
 | 
					    skybox::SkyboxPlugin,
 | 
				
			||||||
    tonemapping::TonemappingNode,
 | 
					    tonemapping::TonemappingNode,
 | 
				
			||||||
    upscaling::UpscalingNode,
 | 
					    upscaling::UpscalingNode,
 | 
				
			||||||
@ -77,16 +81,24 @@ impl Plugin for Core3dPlugin {
 | 
				
			|||||||
            .init_resource::<DrawFunctions<Opaque3d>>()
 | 
					            .init_resource::<DrawFunctions<Opaque3d>>()
 | 
				
			||||||
            .init_resource::<DrawFunctions<AlphaMask3d>>()
 | 
					            .init_resource::<DrawFunctions<AlphaMask3d>>()
 | 
				
			||||||
            .init_resource::<DrawFunctions<Transparent3d>>()
 | 
					            .init_resource::<DrawFunctions<Transparent3d>>()
 | 
				
			||||||
 | 
					            .init_resource::<DrawFunctions<Opaque3dPrepass>>()
 | 
				
			||||||
 | 
					            .init_resource::<DrawFunctions<AlphaMask3dPrepass>>()
 | 
				
			||||||
            .add_systems(ExtractSchedule, extract_core_3d_camera_phases)
 | 
					            .add_systems(ExtractSchedule, extract_core_3d_camera_phases)
 | 
				
			||||||
 | 
					            .add_systems(ExtractSchedule, extract_camera_prepass_phase)
 | 
				
			||||||
            .add_systems(
 | 
					            .add_systems(
 | 
				
			||||||
                Render,
 | 
					                Render,
 | 
				
			||||||
                (
 | 
					                (
 | 
				
			||||||
                    prepare_core_3d_depth_textures
 | 
					                    prepare_core_3d_depth_textures
 | 
				
			||||||
                        .in_set(RenderSet::Prepare)
 | 
					                        .in_set(RenderSet::Prepare)
 | 
				
			||||||
                        .after(bevy_render::view::prepare_windows),
 | 
					                        .after(bevy_render::view::prepare_windows),
 | 
				
			||||||
 | 
					                    prepare_prepass_textures
 | 
				
			||||||
 | 
					                        .in_set(RenderSet::Prepare)
 | 
				
			||||||
 | 
					                        .after(bevy_render::view::prepare_windows),
 | 
				
			||||||
                    sort_phase_system::<Opaque3d>.in_set(RenderSet::PhaseSort),
 | 
					                    sort_phase_system::<Opaque3d>.in_set(RenderSet::PhaseSort),
 | 
				
			||||||
                    sort_phase_system::<AlphaMask3d>.in_set(RenderSet::PhaseSort),
 | 
					                    sort_phase_system::<AlphaMask3d>.in_set(RenderSet::PhaseSort),
 | 
				
			||||||
                    sort_phase_system::<Transparent3d>.in_set(RenderSet::PhaseSort),
 | 
					                    sort_phase_system::<Transparent3d>.in_set(RenderSet::PhaseSort),
 | 
				
			||||||
 | 
					                    sort_phase_system::<Opaque3dPrepass>.in_set(RenderSet::PhaseSort),
 | 
				
			||||||
 | 
					                    sort_phase_system::<AlphaMask3dPrepass>.in_set(RenderSet::PhaseSort),
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -257,6 +269,50 @@ pub fn extract_core_3d_camera_phases(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Extract the render phases for the prepass
 | 
				
			||||||
 | 
					pub fn extract_camera_prepass_phase(
 | 
				
			||||||
 | 
					    mut commands: Commands,
 | 
				
			||||||
 | 
					    cameras_3d: Extract<
 | 
				
			||||||
 | 
					        Query<
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                Entity,
 | 
				
			||||||
 | 
					                &Camera,
 | 
				
			||||||
 | 
					                Option<&DepthPrepass>,
 | 
				
			||||||
 | 
					                Option<&NormalPrepass>,
 | 
				
			||||||
 | 
					                Option<&MotionVectorPrepass>,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            With<Camera3d>,
 | 
				
			||||||
 | 
					        >,
 | 
				
			||||||
 | 
					    >,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    for (entity, camera, depth_prepass, normal_prepass, motion_vector_prepass) in cameras_3d.iter()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if camera.is_active {
 | 
				
			||||||
 | 
					            let mut entity = commands.get_or_spawn(entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if depth_prepass.is_some()
 | 
				
			||||||
 | 
					                || normal_prepass.is_some()
 | 
				
			||||||
 | 
					                || motion_vector_prepass.is_some()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                entity.insert((
 | 
				
			||||||
 | 
					                    RenderPhase::<Opaque3dPrepass>::default(),
 | 
				
			||||||
 | 
					                    RenderPhase::<AlphaMask3dPrepass>::default(),
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if depth_prepass.is_some() {
 | 
				
			||||||
 | 
					                entity.insert(DepthPrepass);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if normal_prepass.is_some() {
 | 
				
			||||||
 | 
					                entity.insert(NormalPrepass);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if motion_vector_prepass.is_some() {
 | 
				
			||||||
 | 
					                entity.insert(MotionVectorPrepass);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn prepare_core_3d_depth_textures(
 | 
					pub fn prepare_core_3d_depth_textures(
 | 
				
			||||||
    mut commands: Commands,
 | 
					    mut commands: Commands,
 | 
				
			||||||
    mut texture_cache: ResMut<TextureCache>,
 | 
					    mut texture_cache: ResMut<TextureCache>,
 | 
				
			||||||
@ -316,3 +372,111 @@ pub fn prepare_core_3d_depth_textures(
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Prepares the textures used by the prepass
 | 
				
			||||||
 | 
					pub fn prepare_prepass_textures(
 | 
				
			||||||
 | 
					    mut commands: Commands,
 | 
				
			||||||
 | 
					    mut texture_cache: ResMut<TextureCache>,
 | 
				
			||||||
 | 
					    msaa: Res<Msaa>,
 | 
				
			||||||
 | 
					    render_device: Res<RenderDevice>,
 | 
				
			||||||
 | 
					    views_3d: Query<
 | 
				
			||||||
 | 
					        (
 | 
				
			||||||
 | 
					            Entity,
 | 
				
			||||||
 | 
					            &ExtractedCamera,
 | 
				
			||||||
 | 
					            Option<&DepthPrepass>,
 | 
				
			||||||
 | 
					            Option<&NormalPrepass>,
 | 
				
			||||||
 | 
					            Option<&MotionVectorPrepass>,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        (
 | 
				
			||||||
 | 
					            With<RenderPhase<Opaque3dPrepass>>,
 | 
				
			||||||
 | 
					            With<RenderPhase<AlphaMask3dPrepass>>,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    >,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    let mut depth_textures = HashMap::default();
 | 
				
			||||||
 | 
					    let mut normal_textures = HashMap::default();
 | 
				
			||||||
 | 
					    let mut motion_vectors_textures = HashMap::default();
 | 
				
			||||||
 | 
					    for (entity, camera, depth_prepass, normal_prepass, motion_vector_prepass) in &views_3d {
 | 
				
			||||||
 | 
					        let Some(physical_target_size) = camera.physical_target_size else {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let size = Extent3d {
 | 
				
			||||||
 | 
					            depth_or_array_layers: 1,
 | 
				
			||||||
 | 
					            width: physical_target_size.x,
 | 
				
			||||||
 | 
					            height: physical_target_size.y,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let cached_depth_texture = depth_prepass.is_some().then(|| {
 | 
				
			||||||
 | 
					            depth_textures
 | 
				
			||||||
 | 
					                .entry(camera.target.clone())
 | 
				
			||||||
 | 
					                .or_insert_with(|| {
 | 
				
			||||||
 | 
					                    let descriptor = TextureDescriptor {
 | 
				
			||||||
 | 
					                        label: Some("prepass_depth_texture"),
 | 
				
			||||||
 | 
					                        size,
 | 
				
			||||||
 | 
					                        mip_level_count: 1,
 | 
				
			||||||
 | 
					                        sample_count: msaa.samples(),
 | 
				
			||||||
 | 
					                        dimension: TextureDimension::D2,
 | 
				
			||||||
 | 
					                        format: DEPTH_PREPASS_FORMAT,
 | 
				
			||||||
 | 
					                        usage: TextureUsages::COPY_DST
 | 
				
			||||||
 | 
					                            | TextureUsages::RENDER_ATTACHMENT
 | 
				
			||||||
 | 
					                            | TextureUsages::TEXTURE_BINDING,
 | 
				
			||||||
 | 
					                        view_formats: &[],
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                    texture_cache.get(&render_device, descriptor)
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .clone()
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let cached_normals_texture = normal_prepass.is_some().then(|| {
 | 
				
			||||||
 | 
					            normal_textures
 | 
				
			||||||
 | 
					                .entry(camera.target.clone())
 | 
				
			||||||
 | 
					                .or_insert_with(|| {
 | 
				
			||||||
 | 
					                    texture_cache.get(
 | 
				
			||||||
 | 
					                        &render_device,
 | 
				
			||||||
 | 
					                        TextureDescriptor {
 | 
				
			||||||
 | 
					                            label: Some("prepass_normal_texture"),
 | 
				
			||||||
 | 
					                            size,
 | 
				
			||||||
 | 
					                            mip_level_count: 1,
 | 
				
			||||||
 | 
					                            sample_count: msaa.samples(),
 | 
				
			||||||
 | 
					                            dimension: TextureDimension::D2,
 | 
				
			||||||
 | 
					                            format: NORMAL_PREPASS_FORMAT,
 | 
				
			||||||
 | 
					                            usage: TextureUsages::RENDER_ATTACHMENT
 | 
				
			||||||
 | 
					                                | TextureUsages::TEXTURE_BINDING,
 | 
				
			||||||
 | 
					                            view_formats: &[],
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .clone()
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let cached_motion_vectors_texture = motion_vector_prepass.is_some().then(|| {
 | 
				
			||||||
 | 
					            motion_vectors_textures
 | 
				
			||||||
 | 
					                .entry(camera.target.clone())
 | 
				
			||||||
 | 
					                .or_insert_with(|| {
 | 
				
			||||||
 | 
					                    texture_cache.get(
 | 
				
			||||||
 | 
					                        &render_device,
 | 
				
			||||||
 | 
					                        TextureDescriptor {
 | 
				
			||||||
 | 
					                            label: Some("prepass_motion_vectors_textures"),
 | 
				
			||||||
 | 
					                            size,
 | 
				
			||||||
 | 
					                            mip_level_count: 1,
 | 
				
			||||||
 | 
					                            sample_count: msaa.samples(),
 | 
				
			||||||
 | 
					                            dimension: TextureDimension::D2,
 | 
				
			||||||
 | 
					                            format: MOTION_VECTOR_PREPASS_FORMAT,
 | 
				
			||||||
 | 
					                            usage: TextureUsages::RENDER_ATTACHMENT
 | 
				
			||||||
 | 
					                                | TextureUsages::TEXTURE_BINDING,
 | 
				
			||||||
 | 
					                            view_formats: &[],
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .clone()
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        commands.entity(entity).insert(ViewPrepassTextures {
 | 
				
			||||||
 | 
					            depth: cached_depth_texture,
 | 
				
			||||||
 | 
					            normal: cached_normals_texture,
 | 
				
			||||||
 | 
					            motion_vectors: cached_motion_vectors_texture,
 | 
				
			||||||
 | 
					            size,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,32 +18,31 @@ use bevy_ecs::{
 | 
				
			|||||||
use bevy_math::Mat4;
 | 
					use bevy_math::Mat4;
 | 
				
			||||||
use bevy_reflect::TypeUuid;
 | 
					use bevy_reflect::TypeUuid;
 | 
				
			||||||
use bevy_render::{
 | 
					use bevy_render::{
 | 
				
			||||||
    camera::ExtractedCamera,
 | 
					 | 
				
			||||||
    globals::{GlobalsBuffer, GlobalsUniform},
 | 
					    globals::{GlobalsBuffer, GlobalsUniform},
 | 
				
			||||||
    mesh::MeshVertexBufferLayout,
 | 
					    mesh::MeshVertexBufferLayout,
 | 
				
			||||||
    prelude::{Camera, Mesh},
 | 
					    prelude::{Camera, Mesh},
 | 
				
			||||||
    render_asset::RenderAssets,
 | 
					    render_asset::RenderAssets,
 | 
				
			||||||
    render_phase::{
 | 
					    render_phase::{
 | 
				
			||||||
        sort_phase_system, AddRenderCommand, DrawFunctions, PhaseItem, RenderCommand,
 | 
					        AddRenderCommand, DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult,
 | 
				
			||||||
        RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass,
 | 
					        RenderPhase, SetItemPipeline, TrackedRenderPass,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    render_resource::{
 | 
					    render_resource::{
 | 
				
			||||||
        BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
 | 
					        BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
 | 
				
			||||||
        BindGroupLayoutEntry, BindingResource, BindingType, BlendState, BufferBindingType,
 | 
					        BindGroupLayoutEntry, BindingResource, BindingType, BlendState, BufferBindingType,
 | 
				
			||||||
        ColorTargetState, ColorWrites, CompareFunction, DepthBiasState, DepthStencilState,
 | 
					        ColorTargetState, ColorWrites, CompareFunction, DepthBiasState, DepthStencilState,
 | 
				
			||||||
        DynamicUniformBuffer, Extent3d, FragmentState, FrontFace, MultisampleState, PipelineCache,
 | 
					        DynamicUniformBuffer, FragmentState, FrontFace, MultisampleState, PipelineCache,
 | 
				
			||||||
        PolygonMode, PrimitiveState, RenderPipelineDescriptor, Shader, ShaderDefVal, ShaderRef,
 | 
					        PolygonMode, PrimitiveState, RenderPipelineDescriptor, Shader, ShaderDefVal, ShaderRef,
 | 
				
			||||||
        ShaderStages, ShaderType, SpecializedMeshPipeline, SpecializedMeshPipelineError,
 | 
					        ShaderStages, ShaderType, SpecializedMeshPipeline, SpecializedMeshPipelineError,
 | 
				
			||||||
        SpecializedMeshPipelines, StencilFaceState, StencilState, TextureDescriptor,
 | 
					        SpecializedMeshPipelines, StencilFaceState, StencilState, TextureSampleType,
 | 
				
			||||||
        TextureDimension, TextureSampleType, TextureUsages, TextureViewDimension, VertexState,
 | 
					        TextureViewDimension, VertexState,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    renderer::{RenderDevice, RenderQueue},
 | 
					    renderer::{RenderDevice, RenderQueue},
 | 
				
			||||||
    texture::{FallbackImagesDepth, FallbackImagesMsaa, TextureCache},
 | 
					    texture::{FallbackImagesDepth, FallbackImagesMsaa},
 | 
				
			||||||
    view::{ExtractedView, Msaa, ViewUniform, ViewUniformOffset, ViewUniforms, VisibleEntities},
 | 
					    view::{ExtractedView, Msaa, ViewUniform, ViewUniformOffset, ViewUniforms, VisibleEntities},
 | 
				
			||||||
    Extract, ExtractSchedule, Render, RenderApp, RenderSet,
 | 
					    Extract, ExtractSchedule, Render, RenderApp, RenderSet,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_transform::prelude::GlobalTransform;
 | 
					use bevy_transform::prelude::GlobalTransform;
 | 
				
			||||||
use bevy_utils::{tracing::error, HashMap};
 | 
					use bevy_utils::tracing::error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    prepare_lights, AlphaMode, DrawMesh, Material, MaterialPipeline, MaterialPipelineKey,
 | 
					    prepare_lights, AlphaMode, DrawMesh, Material, MaterialPipeline, MaterialPipelineKey,
 | 
				
			||||||
@ -153,15 +152,10 @@ where
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if no_prepass_plugin_loaded {
 | 
					        if no_prepass_plugin_loaded {
 | 
				
			||||||
            render_app
 | 
					            render_app
 | 
				
			||||||
                .init_resource::<DrawFunctions<Opaque3dPrepass>>()
 | 
					                .add_systems(ExtractSchedule, extract_camera_previous_view_projection)
 | 
				
			||||||
                .init_resource::<DrawFunctions<AlphaMask3dPrepass>>()
 | 
					 | 
				
			||||||
                .add_systems(ExtractSchedule, extract_camera_prepass_phase)
 | 
					 | 
				
			||||||
                .add_systems(
 | 
					                .add_systems(
 | 
				
			||||||
                    Render,
 | 
					                    Render,
 | 
				
			||||||
                    (
 | 
					                    (
 | 
				
			||||||
                        prepare_prepass_textures
 | 
					 | 
				
			||||||
                            .in_set(RenderSet::Prepare)
 | 
					 | 
				
			||||||
                            .after(bevy_render::view::prepare_windows),
 | 
					 | 
				
			||||||
                        prepare_previous_view_projection_uniforms
 | 
					                        prepare_previous_view_projection_uniforms
 | 
				
			||||||
                            .in_set(RenderSet::Prepare)
 | 
					                            .in_set(RenderSet::Prepare)
 | 
				
			||||||
                            .after(PrepassLightsViewFlush),
 | 
					                            .after(PrepassLightsViewFlush),
 | 
				
			||||||
@ -169,8 +163,6 @@ where
 | 
				
			|||||||
                            .in_set(RenderSet::Prepare)
 | 
					                            .in_set(RenderSet::Prepare)
 | 
				
			||||||
                            .in_set(PrepassLightsViewFlush)
 | 
					                            .in_set(PrepassLightsViewFlush)
 | 
				
			||||||
                            .after(prepare_lights),
 | 
					                            .after(prepare_lights),
 | 
				
			||||||
                        sort_phase_system::<Opaque3dPrepass>.in_set(RenderSet::PhaseSort),
 | 
					 | 
				
			||||||
                        sort_phase_system::<AlphaMask3dPrepass>.in_set(RenderSet::PhaseSort),
 | 
					 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -632,54 +624,14 @@ pub fn get_bindings<'a>(
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Extract the render phases for the prepass
 | 
					// Extract the render phases for the prepass
 | 
				
			||||||
pub fn extract_camera_prepass_phase(
 | 
					pub fn extract_camera_previous_view_projection(
 | 
				
			||||||
    mut commands: Commands,
 | 
					    mut commands: Commands,
 | 
				
			||||||
    cameras_3d: Extract<
 | 
					    cameras_3d: Extract<Query<(Entity, &Camera, Option<&PreviousViewProjection>), With<Camera3d>>>,
 | 
				
			||||||
        Query<
 | 
					 | 
				
			||||||
            (
 | 
					 | 
				
			||||||
                Entity,
 | 
					 | 
				
			||||||
                &Camera,
 | 
					 | 
				
			||||||
                Option<&DepthPrepass>,
 | 
					 | 
				
			||||||
                Option<&NormalPrepass>,
 | 
					 | 
				
			||||||
                Option<&MotionVectorPrepass>,
 | 
					 | 
				
			||||||
                Option<&PreviousViewProjection>,
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            With<Camera3d>,
 | 
					 | 
				
			||||||
        >,
 | 
					 | 
				
			||||||
    >,
 | 
					 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    for (
 | 
					    for (entity, camera, maybe_previous_view_proj) in cameras_3d.iter() {
 | 
				
			||||||
        entity,
 | 
					 | 
				
			||||||
        camera,
 | 
					 | 
				
			||||||
        depth_prepass,
 | 
					 | 
				
			||||||
        normal_prepass,
 | 
					 | 
				
			||||||
        motion_vector_prepass,
 | 
					 | 
				
			||||||
        maybe_previous_view_proj,
 | 
					 | 
				
			||||||
    ) in cameras_3d.iter()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if camera.is_active {
 | 
					        if camera.is_active {
 | 
				
			||||||
            let mut entity = commands.get_or_spawn(entity);
 | 
					            let mut entity = commands.get_or_spawn(entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if depth_prepass.is_some()
 | 
					 | 
				
			||||||
                || normal_prepass.is_some()
 | 
					 | 
				
			||||||
                || motion_vector_prepass.is_some()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                entity.insert((
 | 
					 | 
				
			||||||
                    RenderPhase::<Opaque3dPrepass>::default(),
 | 
					 | 
				
			||||||
                    RenderPhase::<AlphaMask3dPrepass>::default(),
 | 
					 | 
				
			||||||
                ));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if depth_prepass.is_some() {
 | 
					 | 
				
			||||||
                entity.insert(DepthPrepass);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if normal_prepass.is_some() {
 | 
					 | 
				
			||||||
                entity.insert(NormalPrepass);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if motion_vector_prepass.is_some() {
 | 
					 | 
				
			||||||
                entity.insert(MotionVectorPrepass);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if let Some(previous_view) = maybe_previous_view_proj {
 | 
					            if let Some(previous_view) = maybe_previous_view_proj {
 | 
				
			||||||
                entity.insert(previous_view.clone());
 | 
					                entity.insert(previous_view.clone());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -728,114 +680,6 @@ pub fn prepare_previous_view_projection_uniforms(
 | 
				
			|||||||
        .write_buffer(&render_device, &render_queue);
 | 
					        .write_buffer(&render_device, &render_queue);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Prepares the textures used by the prepass
 | 
					 | 
				
			||||||
pub fn prepare_prepass_textures(
 | 
					 | 
				
			||||||
    mut commands: Commands,
 | 
					 | 
				
			||||||
    mut texture_cache: ResMut<TextureCache>,
 | 
					 | 
				
			||||||
    msaa: Res<Msaa>,
 | 
					 | 
				
			||||||
    render_device: Res<RenderDevice>,
 | 
					 | 
				
			||||||
    views_3d: Query<
 | 
					 | 
				
			||||||
        (
 | 
					 | 
				
			||||||
            Entity,
 | 
					 | 
				
			||||||
            &ExtractedCamera,
 | 
					 | 
				
			||||||
            Option<&DepthPrepass>,
 | 
					 | 
				
			||||||
            Option<&NormalPrepass>,
 | 
					 | 
				
			||||||
            Option<&MotionVectorPrepass>,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        (
 | 
					 | 
				
			||||||
            With<RenderPhase<Opaque3dPrepass>>,
 | 
					 | 
				
			||||||
            With<RenderPhase<AlphaMask3dPrepass>>,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
    >,
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
    let mut depth_textures = HashMap::default();
 | 
					 | 
				
			||||||
    let mut normal_textures = HashMap::default();
 | 
					 | 
				
			||||||
    let mut motion_vectors_textures = HashMap::default();
 | 
					 | 
				
			||||||
    for (entity, camera, depth_prepass, normal_prepass, motion_vector_prepass) in &views_3d {
 | 
					 | 
				
			||||||
        let Some(physical_target_size) = camera.physical_target_size else {
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let size = Extent3d {
 | 
					 | 
				
			||||||
            depth_or_array_layers: 1,
 | 
					 | 
				
			||||||
            width: physical_target_size.x,
 | 
					 | 
				
			||||||
            height: physical_target_size.y,
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let cached_depth_texture = depth_prepass.is_some().then(|| {
 | 
					 | 
				
			||||||
            depth_textures
 | 
					 | 
				
			||||||
                .entry(camera.target.clone())
 | 
					 | 
				
			||||||
                .or_insert_with(|| {
 | 
					 | 
				
			||||||
                    let descriptor = TextureDescriptor {
 | 
					 | 
				
			||||||
                        label: Some("prepass_depth_texture"),
 | 
					 | 
				
			||||||
                        size,
 | 
					 | 
				
			||||||
                        mip_level_count: 1,
 | 
					 | 
				
			||||||
                        sample_count: msaa.samples(),
 | 
					 | 
				
			||||||
                        dimension: TextureDimension::D2,
 | 
					 | 
				
			||||||
                        format: DEPTH_PREPASS_FORMAT,
 | 
					 | 
				
			||||||
                        usage: TextureUsages::COPY_DST
 | 
					 | 
				
			||||||
                            | TextureUsages::RENDER_ATTACHMENT
 | 
					 | 
				
			||||||
                            | TextureUsages::TEXTURE_BINDING,
 | 
					 | 
				
			||||||
                        view_formats: &[],
 | 
					 | 
				
			||||||
                    };
 | 
					 | 
				
			||||||
                    texture_cache.get(&render_device, descriptor)
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                .clone()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let cached_normals_texture = normal_prepass.is_some().then(|| {
 | 
					 | 
				
			||||||
            normal_textures
 | 
					 | 
				
			||||||
                .entry(camera.target.clone())
 | 
					 | 
				
			||||||
                .or_insert_with(|| {
 | 
					 | 
				
			||||||
                    texture_cache.get(
 | 
					 | 
				
			||||||
                        &render_device,
 | 
					 | 
				
			||||||
                        TextureDescriptor {
 | 
					 | 
				
			||||||
                            label: Some("prepass_normal_texture"),
 | 
					 | 
				
			||||||
                            size,
 | 
					 | 
				
			||||||
                            mip_level_count: 1,
 | 
					 | 
				
			||||||
                            sample_count: msaa.samples(),
 | 
					 | 
				
			||||||
                            dimension: TextureDimension::D2,
 | 
					 | 
				
			||||||
                            format: NORMAL_PREPASS_FORMAT,
 | 
					 | 
				
			||||||
                            usage: TextureUsages::RENDER_ATTACHMENT
 | 
					 | 
				
			||||||
                                | TextureUsages::TEXTURE_BINDING,
 | 
					 | 
				
			||||||
                            view_formats: &[],
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                .clone()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let cached_motion_vectors_texture = motion_vector_prepass.is_some().then(|| {
 | 
					 | 
				
			||||||
            motion_vectors_textures
 | 
					 | 
				
			||||||
                .entry(camera.target.clone())
 | 
					 | 
				
			||||||
                .or_insert_with(|| {
 | 
					 | 
				
			||||||
                    texture_cache.get(
 | 
					 | 
				
			||||||
                        &render_device,
 | 
					 | 
				
			||||||
                        TextureDescriptor {
 | 
					 | 
				
			||||||
                            label: Some("prepass_motion_vectors_textures"),
 | 
					 | 
				
			||||||
                            size,
 | 
					 | 
				
			||||||
                            mip_level_count: 1,
 | 
					 | 
				
			||||||
                            sample_count: msaa.samples(),
 | 
					 | 
				
			||||||
                            dimension: TextureDimension::D2,
 | 
					 | 
				
			||||||
                            format: MOTION_VECTOR_PREPASS_FORMAT,
 | 
					 | 
				
			||||||
                            usage: TextureUsages::RENDER_ATTACHMENT
 | 
					 | 
				
			||||||
                                | TextureUsages::TEXTURE_BINDING,
 | 
					 | 
				
			||||||
                            view_formats: &[],
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                .clone()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        commands.entity(entity).insert(ViewPrepassTextures {
 | 
					 | 
				
			||||||
            depth: cached_depth_texture,
 | 
					 | 
				
			||||||
            normal: cached_normals_texture,
 | 
					 | 
				
			||||||
            motion_vectors: cached_motion_vectors_texture,
 | 
					 | 
				
			||||||
            size,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Default, Resource)]
 | 
					#[derive(Default, Resource)]
 | 
				
			||||||
pub struct PrepassViewBindGroup {
 | 
					pub struct PrepassViewBindGroup {
 | 
				
			||||||
    motion_vectors: Option<BindGroup>,
 | 
					    motion_vectors: Option<BindGroup>,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user