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