bevy_core_pipeline/prepass/
mod.rs1pub mod background_motion_vectors;
29pub mod node;
30
31pub use background_motion_vectors::{
32 BackgroundMotionVectorsBindGroup, BackgroundMotionVectorsPipelineId,
33 BackgroundMotionVectorsPlugin, NoBackgroundMotionVectors,
34};
35use bevy_render::texture::DepthStencilAttachment;
36
37use core::ops::Range;
38
39use crate::deferred::{DEFERRED_LIGHTING_PASS_ID_FORMAT, DEFERRED_PREPASS_FORMAT};
40use bevy_asset::UntypedAssetId;
41use bevy_ecs::prelude::*;
42use bevy_math::Mat4;
43use bevy_reflect::{std_traits::ReflectDefault, Reflect};
44use bevy_render::mesh::allocator::MeshSlabs;
45use bevy_render::render_phase::PhaseItemBatchSetKey;
46use bevy_render::sync_world::MainEntity;
47use bevy_render::{
48 render_phase::{
49 BinnedPhaseItem, CachedRenderPipelinePhaseItem, DrawFunctionId, PhaseItem,
50 PhaseItemExtraIndex,
51 },
52 render_resource::{
53 CachedRenderPipelineId, ColorTargetState, ColorWrites, DynamicUniformBuffer, Extent3d,
54 ShaderType, TextureFormat, TextureView,
55 },
56 texture::ColorAttachment,
57};
58
59pub const NORMAL_PREPASS_FORMAT: TextureFormat = TextureFormat::Rgb10a2Unorm;
60pub const MOTION_VECTOR_PREPASS_FORMAT: TextureFormat = TextureFormat::Rg16Float;
61
62#[derive(Component, Default, Reflect, Clone)]
64#[reflect(Component, Default, Clone)]
65pub struct DepthPrepass;
66
67#[derive(Component, Default, Reflect, Clone)]
70#[reflect(Component, Default, Clone)]
71pub struct NormalPrepass;
72
73#[derive(Component, Default, Reflect, Clone)]
78#[reflect(Component, Default, Clone)]
79pub struct MotionVectorPrepass;
80
81#[derive(Component, Default, Reflect, Clone)]
84#[reflect(Component, Default, Clone)]
85pub struct DeferredPrepass;
86
87#[derive(Component, Default, Reflect, Clone)]
89#[reflect(Component, Default, Clone)]
90#[require(DepthPrepass)]
91pub struct DepthPrepassDoubleBuffer;
92
93#[derive(Component, Default, Reflect, Clone)]
95#[reflect(Component, Default, Clone)]
96#[require(DeferredPrepass)]
97pub struct DeferredPrepassDoubleBuffer;
98
99#[derive(Component, ShaderType, Clone)]
103pub struct PreviousViewData {
104 pub view_from_world: Mat4,
105 pub clip_from_world: Mat4,
106 pub unjittered_clip_from_world: Mat4,
107 pub clip_from_view: Mat4,
108 pub world_from_clip: Mat4,
109 pub view_from_clip: Mat4,
110}
111
112#[derive(Resource, Default)]
113pub struct PreviousViewUniforms {
114 pub uniforms: DynamicUniformBuffer<PreviousViewData>,
115}
116
117#[derive(Component)]
118pub struct PreviousViewUniformOffset {
119 pub offset: u32,
120}
121
122#[derive(Component)]
126pub struct ViewPrepassTextures {
127 pub depth: Option<DepthStencilAttachment>,
130 pub normal: Option<ColorAttachment>,
133 pub motion_vectors: Option<ColorAttachment>,
136 pub deferred: Option<ColorAttachment>,
139 pub deferred_lighting_pass_id: Option<ColorAttachment>,
142 pub size: Extent3d,
144}
145
146impl ViewPrepassTextures {
147 pub fn depth_only_view(&self) -> Option<&TextureView> {
148 self.depth
149 .as_ref()
150 .and_then(|t| t.depth_stencil_views().depth_only_view())
151 }
152
153 pub fn previous_depth_only_view(&self) -> Option<&TextureView> {
154 self.depth.as_ref().and_then(|t| {
155 t.previous_frame_depth_stencil_views
156 .as_ref()
157 .and_then(|views| views.depth_only_view())
158 })
159 }
160
161 pub fn normal_view(&self) -> Option<&TextureView> {
162 self.normal.as_ref().map(|t| &t.texture.default_view)
163 }
164
165 pub fn motion_vectors_view(&self) -> Option<&TextureView> {
166 self.motion_vectors
167 .as_ref()
168 .map(|t| &t.texture.default_view)
169 }
170
171 pub fn deferred_view(&self) -> Option<&TextureView> {
172 self.deferred.as_ref().map(|t| &t.texture.default_view)
173 }
174
175 pub fn previous_deferred_view(&self) -> Option<&TextureView> {
176 self.deferred
177 .as_ref()
178 .and_then(|t| t.previous_frame_texture.as_ref().map(|t| &t.default_view))
179 }
180}
181
182pub struct Opaque3dPrepass {
188 pub batch_set_key: OpaqueNoLightmap3dBatchSetKey,
193 pub bin_key: OpaqueNoLightmap3dBinKey,
195
196 pub representative_entity: (Entity, MainEntity),
199 pub batch_range: Range<u32>,
200 pub extra_index: PhaseItemExtraIndex,
201}
202
203#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
209pub struct OpaqueNoLightmap3dBatchSetKey {
210 pub pipeline: CachedRenderPipelineId,
212
213 pub draw_function: DrawFunctionId,
215
216 pub material_bind_group_index: Option<u32>,
220
221 pub slabs: MeshSlabs,
228}
229
230impl PhaseItemBatchSetKey for OpaqueNoLightmap3dBatchSetKey {
231 fn indexed(&self) -> bool {
232 self.slabs.index_slab_id.is_some()
233 }
234}
235
236#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
239pub struct OpaqueNoLightmap3dBinKey {
240 pub asset_id: UntypedAssetId,
242}
243
244impl PhaseItem for Opaque3dPrepass {
245 #[inline]
246 fn entity(&self) -> Entity {
247 self.representative_entity.0
248 }
249
250 fn main_entity(&self) -> MainEntity {
251 self.representative_entity.1
252 }
253
254 #[inline]
255 fn draw_function(&self) -> DrawFunctionId {
256 self.batch_set_key.draw_function
257 }
258
259 #[inline]
260 fn batch_range(&self) -> &Range<u32> {
261 &self.batch_range
262 }
263
264 #[inline]
265 fn batch_range_mut(&mut self) -> &mut Range<u32> {
266 &mut self.batch_range
267 }
268
269 #[inline]
270 fn extra_index(&self) -> PhaseItemExtraIndex {
271 self.extra_index.clone()
272 }
273
274 #[inline]
275 fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
276 (&mut self.batch_range, &mut self.extra_index)
277 }
278}
279
280impl BinnedPhaseItem for Opaque3dPrepass {
281 type BatchSetKey = OpaqueNoLightmap3dBatchSetKey;
282 type BinKey = OpaqueNoLightmap3dBinKey;
283
284 #[inline]
285 fn new(
286 batch_set_key: Self::BatchSetKey,
287 bin_key: Self::BinKey,
288 representative_entity: (Entity, MainEntity),
289 batch_range: Range<u32>,
290 extra_index: PhaseItemExtraIndex,
291 ) -> Self {
292 Opaque3dPrepass {
293 batch_set_key,
294 bin_key,
295 representative_entity,
296 batch_range,
297 extra_index,
298 }
299 }
300}
301
302impl CachedRenderPipelinePhaseItem for Opaque3dPrepass {
303 #[inline]
304 fn cached_pipeline(&self) -> CachedRenderPipelineId {
305 self.batch_set_key.pipeline
306 }
307}
308
309pub struct AlphaMask3dPrepass {
315 pub batch_set_key: OpaqueNoLightmap3dBatchSetKey,
320 pub bin_key: OpaqueNoLightmap3dBinKey,
322 pub representative_entity: (Entity, MainEntity),
323 pub batch_range: Range<u32>,
324 pub extra_index: PhaseItemExtraIndex,
325}
326
327impl PhaseItem for AlphaMask3dPrepass {
328 #[inline]
329 fn entity(&self) -> Entity {
330 self.representative_entity.0
331 }
332
333 fn main_entity(&self) -> MainEntity {
334 self.representative_entity.1
335 }
336
337 #[inline]
338 fn draw_function(&self) -> DrawFunctionId {
339 self.batch_set_key.draw_function
340 }
341
342 #[inline]
343 fn batch_range(&self) -> &Range<u32> {
344 &self.batch_range
345 }
346
347 #[inline]
348 fn batch_range_mut(&mut self) -> &mut Range<u32> {
349 &mut self.batch_range
350 }
351
352 #[inline]
353 fn extra_index(&self) -> PhaseItemExtraIndex {
354 self.extra_index.clone()
355 }
356
357 #[inline]
358 fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
359 (&mut self.batch_range, &mut self.extra_index)
360 }
361}
362
363impl BinnedPhaseItem for AlphaMask3dPrepass {
364 type BatchSetKey = OpaqueNoLightmap3dBatchSetKey;
365 type BinKey = OpaqueNoLightmap3dBinKey;
366
367 #[inline]
368 fn new(
369 batch_set_key: Self::BatchSetKey,
370 bin_key: Self::BinKey,
371 representative_entity: (Entity, MainEntity),
372 batch_range: Range<u32>,
373 extra_index: PhaseItemExtraIndex,
374 ) -> Self {
375 Self {
376 batch_set_key,
377 bin_key,
378 representative_entity,
379 batch_range,
380 extra_index,
381 }
382 }
383}
384
385impl CachedRenderPipelinePhaseItem for AlphaMask3dPrepass {
386 #[inline]
387 fn cached_pipeline(&self) -> CachedRenderPipelineId {
388 self.batch_set_key.pipeline
389 }
390}
391
392pub fn prepass_target_descriptors(
393 normal_prepass: bool,
394 motion_vector_prepass: bool,
395 deferred_prepass: bool,
396) -> Vec<Option<ColorTargetState>> {
397 vec![
398 normal_prepass.then_some(ColorTargetState {
399 format: NORMAL_PREPASS_FORMAT,
400 blend: None,
401 write_mask: ColorWrites::ALL,
402 }),
403 motion_vector_prepass.then_some(ColorTargetState {
404 format: MOTION_VECTOR_PREPASS_FORMAT,
405 blend: None,
406 write_mask: ColorWrites::ALL,
407 }),
408 deferred_prepass.then_some(ColorTargetState {
409 format: DEFERRED_PREPASS_FORMAT,
410 blend: None,
411 write_mask: ColorWrites::ALL,
412 }),
413 deferred_prepass.then_some(ColorTargetState {
414 format: DEFERRED_LIGHTING_PASS_ID_FORMAT,
415 blend: None,
416 write_mask: ColorWrites::ALL,
417 }),
418 ]
419}