bevy_core_pipeline/prepass/
mod.rs1pub mod node;
29
30use core::ops::Range;
31
32use crate::deferred::{DEFERRED_LIGHTING_PASS_ID_FORMAT, DEFERRED_PREPASS_FORMAT};
33use bevy_asset::UntypedAssetId;
34use bevy_ecs::prelude::*;
35use bevy_math::Mat4;
36use bevy_reflect::{std_traits::ReflectDefault, Reflect};
37use bevy_render::mesh::allocator::SlabId;
38use bevy_render::render_phase::PhaseItemBatchSetKey;
39use bevy_render::sync_world::MainEntity;
40use bevy_render::{
41 render_phase::{
42 BinnedPhaseItem, CachedRenderPipelinePhaseItem, DrawFunctionId, PhaseItem,
43 PhaseItemExtraIndex,
44 },
45 render_resource::{
46 CachedRenderPipelineId, ColorTargetState, ColorWrites, DynamicUniformBuffer, Extent3d,
47 ShaderType, TextureFormat, TextureView,
48 },
49 texture::ColorAttachment,
50};
51
52pub const NORMAL_PREPASS_FORMAT: TextureFormat = TextureFormat::Rgb10a2Unorm;
53pub const MOTION_VECTOR_PREPASS_FORMAT: TextureFormat = TextureFormat::Rg16Float;
54
55#[derive(Component, Default, Reflect, Clone)]
57#[reflect(Component, Default, Clone)]
58pub struct DepthPrepass;
59
60#[derive(Component, Default, Reflect, Clone)]
63#[reflect(Component, Default, Clone)]
64pub struct NormalPrepass;
65
66#[derive(Component, Default, Reflect, Clone)]
68#[reflect(Component, Default, Clone)]
69pub struct MotionVectorPrepass;
70
71#[derive(Component, Default, Reflect)]
74#[reflect(Component, Default)]
75pub struct DeferredPrepass;
76
77#[derive(Component, ShaderType, Clone)]
81pub struct PreviousViewData {
82 pub view_from_world: Mat4,
83 pub clip_from_world: Mat4,
84 pub clip_from_view: Mat4,
85 pub world_from_clip: Mat4,
86 pub view_from_clip: Mat4,
87}
88
89#[derive(Resource, Default)]
90pub struct PreviousViewUniforms {
91 pub uniforms: DynamicUniformBuffer<PreviousViewData>,
92}
93
94#[derive(Component)]
95pub struct PreviousViewUniformOffset {
96 pub offset: u32,
97}
98
99#[derive(Component)]
103pub struct ViewPrepassTextures {
104 pub depth: Option<ColorAttachment>,
107 pub normal: Option<ColorAttachment>,
110 pub motion_vectors: Option<ColorAttachment>,
113 pub deferred: Option<ColorAttachment>,
116 pub deferred_lighting_pass_id: Option<ColorAttachment>,
119 pub size: Extent3d,
121}
122
123impl ViewPrepassTextures {
124 pub fn depth_view(&self) -> Option<&TextureView> {
125 self.depth.as_ref().map(|t| &t.texture.default_view)
126 }
127
128 pub fn normal_view(&self) -> Option<&TextureView> {
129 self.normal.as_ref().map(|t| &t.texture.default_view)
130 }
131
132 pub fn motion_vectors_view(&self) -> Option<&TextureView> {
133 self.motion_vectors
134 .as_ref()
135 .map(|t| &t.texture.default_view)
136 }
137
138 pub fn deferred_view(&self) -> Option<&TextureView> {
139 self.deferred.as_ref().map(|t| &t.texture.default_view)
140 }
141}
142
143pub struct Opaque3dPrepass {
149 pub batch_set_key: OpaqueNoLightmap3dBatchSetKey,
154 pub bin_key: OpaqueNoLightmap3dBinKey,
156
157 pub representative_entity: (Entity, MainEntity),
160 pub batch_range: Range<u32>,
161 pub extra_index: PhaseItemExtraIndex,
162}
163
164#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
170pub struct OpaqueNoLightmap3dBatchSetKey {
171 pub pipeline: CachedRenderPipelineId,
173
174 pub draw_function: DrawFunctionId,
176
177 pub material_bind_group_index: Option<u32>,
181
182 pub vertex_slab: SlabId,
187
188 pub index_slab: Option<SlabId>,
192}
193
194impl PhaseItemBatchSetKey for OpaqueNoLightmap3dBatchSetKey {
195 fn indexed(&self) -> bool {
196 self.index_slab.is_some()
197 }
198}
199
200#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
203pub struct OpaqueNoLightmap3dBinKey {
204 pub asset_id: UntypedAssetId,
206}
207
208impl PhaseItem for Opaque3dPrepass {
209 #[inline]
210 fn entity(&self) -> Entity {
211 self.representative_entity.0
212 }
213
214 fn main_entity(&self) -> MainEntity {
215 self.representative_entity.1
216 }
217
218 #[inline]
219 fn draw_function(&self) -> DrawFunctionId {
220 self.batch_set_key.draw_function
221 }
222
223 #[inline]
224 fn batch_range(&self) -> &Range<u32> {
225 &self.batch_range
226 }
227
228 #[inline]
229 fn batch_range_mut(&mut self) -> &mut Range<u32> {
230 &mut self.batch_range
231 }
232
233 #[inline]
234 fn extra_index(&self) -> PhaseItemExtraIndex {
235 self.extra_index.clone()
236 }
237
238 #[inline]
239 fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
240 (&mut self.batch_range, &mut self.extra_index)
241 }
242}
243
244impl BinnedPhaseItem for Opaque3dPrepass {
245 type BatchSetKey = OpaqueNoLightmap3dBatchSetKey;
246 type BinKey = OpaqueNoLightmap3dBinKey;
247
248 #[inline]
249 fn new(
250 batch_set_key: Self::BatchSetKey,
251 bin_key: Self::BinKey,
252 representative_entity: (Entity, MainEntity),
253 batch_range: Range<u32>,
254 extra_index: PhaseItemExtraIndex,
255 ) -> Self {
256 Opaque3dPrepass {
257 batch_set_key,
258 bin_key,
259 representative_entity,
260 batch_range,
261 extra_index,
262 }
263 }
264}
265
266impl CachedRenderPipelinePhaseItem for Opaque3dPrepass {
267 #[inline]
268 fn cached_pipeline(&self) -> CachedRenderPipelineId {
269 self.batch_set_key.pipeline
270 }
271}
272
273pub struct AlphaMask3dPrepass {
279 pub batch_set_key: OpaqueNoLightmap3dBatchSetKey,
284 pub bin_key: OpaqueNoLightmap3dBinKey,
286 pub representative_entity: (Entity, MainEntity),
287 pub batch_range: Range<u32>,
288 pub extra_index: PhaseItemExtraIndex,
289}
290
291impl PhaseItem for AlphaMask3dPrepass {
292 #[inline]
293 fn entity(&self) -> Entity {
294 self.representative_entity.0
295 }
296
297 fn main_entity(&self) -> MainEntity {
298 self.representative_entity.1
299 }
300
301 #[inline]
302 fn draw_function(&self) -> DrawFunctionId {
303 self.batch_set_key.draw_function
304 }
305
306 #[inline]
307 fn batch_range(&self) -> &Range<u32> {
308 &self.batch_range
309 }
310
311 #[inline]
312 fn batch_range_mut(&mut self) -> &mut Range<u32> {
313 &mut self.batch_range
314 }
315
316 #[inline]
317 fn extra_index(&self) -> PhaseItemExtraIndex {
318 self.extra_index.clone()
319 }
320
321 #[inline]
322 fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
323 (&mut self.batch_range, &mut self.extra_index)
324 }
325}
326
327impl BinnedPhaseItem for AlphaMask3dPrepass {
328 type BatchSetKey = OpaqueNoLightmap3dBatchSetKey;
329 type BinKey = OpaqueNoLightmap3dBinKey;
330
331 #[inline]
332 fn new(
333 batch_set_key: Self::BatchSetKey,
334 bin_key: Self::BinKey,
335 representative_entity: (Entity, MainEntity),
336 batch_range: Range<u32>,
337 extra_index: PhaseItemExtraIndex,
338 ) -> Self {
339 Self {
340 batch_set_key,
341 bin_key,
342 representative_entity,
343 batch_range,
344 extra_index,
345 }
346 }
347}
348
349impl CachedRenderPipelinePhaseItem for AlphaMask3dPrepass {
350 #[inline]
351 fn cached_pipeline(&self) -> CachedRenderPipelineId {
352 self.batch_set_key.pipeline
353 }
354}
355
356pub fn prepass_target_descriptors(
357 normal_prepass: bool,
358 motion_vector_prepass: bool,
359 deferred_prepass: bool,
360) -> Vec<Option<ColorTargetState>> {
361 vec![
362 normal_prepass.then_some(ColorTargetState {
363 format: NORMAL_PREPASS_FORMAT,
364 blend: None,
365 write_mask: ColorWrites::ALL,
366 }),
367 motion_vector_prepass.then_some(ColorTargetState {
368 format: MOTION_VECTOR_PREPASS_FORMAT,
369 blend: None,
370 write_mask: ColorWrites::ALL,
371 }),
372 deferred_prepass.then_some(ColorTargetState {
373 format: DEFERRED_PREPASS_FORMAT,
374 blend: None,
375 write_mask: ColorWrites::ALL,
376 }),
377 deferred_prepass.then_some(ColorTargetState {
378 format: DEFERRED_LIGHTING_PASS_ID_FORMAT,
379 blend: None,
380 write_mask: ColorWrites::ALL,
381 }),
382 ]
383}