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)]
78pub struct PreviousViewData {
79 pub view_from_world: Mat4,
80 pub clip_from_world: Mat4,
81 pub clip_from_view: Mat4,
82}
83
84#[derive(Resource, Default)]
85pub struct PreviousViewUniforms {
86 pub uniforms: DynamicUniformBuffer<PreviousViewData>,
87}
88
89#[derive(Component)]
90pub struct PreviousViewUniformOffset {
91 pub offset: u32,
92}
93
94#[derive(Component)]
98pub struct ViewPrepassTextures {
99 pub depth: Option<ColorAttachment>,
102 pub normal: Option<ColorAttachment>,
105 pub motion_vectors: Option<ColorAttachment>,
108 pub deferred: Option<ColorAttachment>,
111 pub deferred_lighting_pass_id: Option<ColorAttachment>,
114 pub size: Extent3d,
116}
117
118impl ViewPrepassTextures {
119 pub fn depth_view(&self) -> Option<&TextureView> {
120 self.depth.as_ref().map(|t| &t.texture.default_view)
121 }
122
123 pub fn normal_view(&self) -> Option<&TextureView> {
124 self.normal.as_ref().map(|t| &t.texture.default_view)
125 }
126
127 pub fn motion_vectors_view(&self) -> Option<&TextureView> {
128 self.motion_vectors
129 .as_ref()
130 .map(|t| &t.texture.default_view)
131 }
132
133 pub fn deferred_view(&self) -> Option<&TextureView> {
134 self.deferred.as_ref().map(|t| &t.texture.default_view)
135 }
136}
137
138pub struct Opaque3dPrepass {
144 pub batch_set_key: OpaqueNoLightmap3dBatchSetKey,
149 pub bin_key: OpaqueNoLightmap3dBinKey,
151
152 pub representative_entity: (Entity, MainEntity),
155 pub batch_range: Range<u32>,
156 pub extra_index: PhaseItemExtraIndex,
157}
158
159#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
165pub struct OpaqueNoLightmap3dBatchSetKey {
166 pub pipeline: CachedRenderPipelineId,
168
169 pub draw_function: DrawFunctionId,
171
172 pub material_bind_group_index: Option<u32>,
176
177 pub vertex_slab: SlabId,
182
183 pub index_slab: Option<SlabId>,
187}
188
189impl PhaseItemBatchSetKey for OpaqueNoLightmap3dBatchSetKey {
190 fn indexed(&self) -> bool {
191 self.index_slab.is_some()
192 }
193}
194
195#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
198pub struct OpaqueNoLightmap3dBinKey {
199 pub asset_id: UntypedAssetId,
201}
202
203impl PhaseItem for Opaque3dPrepass {
204 #[inline]
205 fn entity(&self) -> Entity {
206 self.representative_entity.0
207 }
208
209 fn main_entity(&self) -> MainEntity {
210 self.representative_entity.1
211 }
212
213 #[inline]
214 fn draw_function(&self) -> DrawFunctionId {
215 self.batch_set_key.draw_function
216 }
217
218 #[inline]
219 fn batch_range(&self) -> &Range<u32> {
220 &self.batch_range
221 }
222
223 #[inline]
224 fn batch_range_mut(&mut self) -> &mut Range<u32> {
225 &mut self.batch_range
226 }
227
228 #[inline]
229 fn extra_index(&self) -> PhaseItemExtraIndex {
230 self.extra_index.clone()
231 }
232
233 #[inline]
234 fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
235 (&mut self.batch_range, &mut self.extra_index)
236 }
237}
238
239impl BinnedPhaseItem for Opaque3dPrepass {
240 type BatchSetKey = OpaqueNoLightmap3dBatchSetKey;
241 type BinKey = OpaqueNoLightmap3dBinKey;
242
243 #[inline]
244 fn new(
245 batch_set_key: Self::BatchSetKey,
246 bin_key: Self::BinKey,
247 representative_entity: (Entity, MainEntity),
248 batch_range: Range<u32>,
249 extra_index: PhaseItemExtraIndex,
250 ) -> Self {
251 Opaque3dPrepass {
252 batch_set_key,
253 bin_key,
254 representative_entity,
255 batch_range,
256 extra_index,
257 }
258 }
259}
260
261impl CachedRenderPipelinePhaseItem for Opaque3dPrepass {
262 #[inline]
263 fn cached_pipeline(&self) -> CachedRenderPipelineId {
264 self.batch_set_key.pipeline
265 }
266}
267
268pub struct AlphaMask3dPrepass {
274 pub batch_set_key: OpaqueNoLightmap3dBatchSetKey,
279 pub bin_key: OpaqueNoLightmap3dBinKey,
281 pub representative_entity: (Entity, MainEntity),
282 pub batch_range: Range<u32>,
283 pub extra_index: PhaseItemExtraIndex,
284}
285
286impl PhaseItem for AlphaMask3dPrepass {
287 #[inline]
288 fn entity(&self) -> Entity {
289 self.representative_entity.0
290 }
291
292 fn main_entity(&self) -> MainEntity {
293 self.representative_entity.1
294 }
295
296 #[inline]
297 fn draw_function(&self) -> DrawFunctionId {
298 self.batch_set_key.draw_function
299 }
300
301 #[inline]
302 fn batch_range(&self) -> &Range<u32> {
303 &self.batch_range
304 }
305
306 #[inline]
307 fn batch_range_mut(&mut self) -> &mut Range<u32> {
308 &mut self.batch_range
309 }
310
311 #[inline]
312 fn extra_index(&self) -> PhaseItemExtraIndex {
313 self.extra_index.clone()
314 }
315
316 #[inline]
317 fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
318 (&mut self.batch_range, &mut self.extra_index)
319 }
320}
321
322impl BinnedPhaseItem for AlphaMask3dPrepass {
323 type BatchSetKey = OpaqueNoLightmap3dBatchSetKey;
324 type BinKey = OpaqueNoLightmap3dBinKey;
325
326 #[inline]
327 fn new(
328 batch_set_key: Self::BatchSetKey,
329 bin_key: Self::BinKey,
330 representative_entity: (Entity, MainEntity),
331 batch_range: Range<u32>,
332 extra_index: PhaseItemExtraIndex,
333 ) -> Self {
334 Self {
335 batch_set_key,
336 bin_key,
337 representative_entity,
338 batch_range,
339 extra_index,
340 }
341 }
342}
343
344impl CachedRenderPipelinePhaseItem for AlphaMask3dPrepass {
345 #[inline]
346 fn cached_pipeline(&self) -> CachedRenderPipelineId {
347 self.batch_set_key.pipeline
348 }
349}
350
351pub fn prepass_target_descriptors(
352 normal_prepass: bool,
353 motion_vector_prepass: bool,
354 deferred_prepass: bool,
355) -> Vec<Option<ColorTargetState>> {
356 vec![
357 normal_prepass.then_some(ColorTargetState {
358 format: NORMAL_PREPASS_FORMAT,
359 blend: None,
360 write_mask: ColorWrites::ALL,
361 }),
362 motion_vector_prepass.then_some(ColorTargetState {
363 format: MOTION_VECTOR_PREPASS_FORMAT,
364 blend: None,
365 write_mask: ColorWrites::ALL,
366 }),
367 deferred_prepass.then_some(ColorTargetState {
368 format: DEFERRED_PREPASS_FORMAT,
369 blend: None,
370 write_mask: ColorWrites::ALL,
371 }),
372 deferred_prepass.then_some(ColorTargetState {
373 format: DEFERRED_LIGHTING_PASS_ID_FORMAT,
374 blend: None,
375 write_mask: ColorWrites::ALL,
376 }),
377 ]
378}