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::sync_world::MainEntity;
38use bevy_render::{
39 render_phase::{
40 BinnedPhaseItem, CachedRenderPipelinePhaseItem, DrawFunctionId, PhaseItem,
41 PhaseItemExtraIndex,
42 },
43 render_resource::{
44 BindGroupId, CachedRenderPipelineId, ColorTargetState, ColorWrites, DynamicUniformBuffer,
45 Extent3d, ShaderType, TextureFormat, TextureView,
46 },
47 texture::ColorAttachment,
48};
49
50pub const NORMAL_PREPASS_FORMAT: TextureFormat = TextureFormat::Rgb10a2Unorm;
51pub const MOTION_VECTOR_PREPASS_FORMAT: TextureFormat = TextureFormat::Rg16Float;
52
53#[derive(Component, Default, Reflect, Clone)]
55#[reflect(Component, Default)]
56pub struct DepthPrepass;
57
58#[derive(Component, Default, Reflect, Clone)]
61#[reflect(Component, Default)]
62pub struct NormalPrepass;
63
64#[derive(Component, Default, Reflect, Clone)]
66#[reflect(Component, Default)]
67pub struct MotionVectorPrepass;
68
69#[derive(Component, Default, Reflect)]
72#[reflect(Component, Default)]
73pub struct DeferredPrepass;
74
75#[derive(Component, ShaderType, Clone)]
76pub struct PreviousViewData {
77 pub view_from_world: Mat4,
78 pub clip_from_world: Mat4,
79}
80
81#[derive(Resource, Default)]
82pub struct PreviousViewUniforms {
83 pub uniforms: DynamicUniformBuffer<PreviousViewData>,
84}
85
86#[derive(Component)]
87pub struct PreviousViewUniformOffset {
88 pub offset: u32,
89}
90
91#[derive(Component)]
95pub struct ViewPrepassTextures {
96 pub depth: Option<ColorAttachment>,
99 pub normal: Option<ColorAttachment>,
102 pub motion_vectors: Option<ColorAttachment>,
105 pub deferred: Option<ColorAttachment>,
108 pub deferred_lighting_pass_id: Option<ColorAttachment>,
111 pub size: Extent3d,
113}
114
115impl ViewPrepassTextures {
116 pub fn depth_view(&self) -> Option<&TextureView> {
117 self.depth.as_ref().map(|t| &t.texture.default_view)
118 }
119
120 pub fn normal_view(&self) -> Option<&TextureView> {
121 self.normal.as_ref().map(|t| &t.texture.default_view)
122 }
123
124 pub fn motion_vectors_view(&self) -> Option<&TextureView> {
125 self.motion_vectors
126 .as_ref()
127 .map(|t| &t.texture.default_view)
128 }
129
130 pub fn deferred_view(&self) -> Option<&TextureView> {
131 self.deferred.as_ref().map(|t| &t.texture.default_view)
132 }
133}
134
135pub struct Opaque3dPrepass {
141 pub key: OpaqueNoLightmap3dBinKey,
143
144 pub representative_entity: (Entity, MainEntity),
147 pub batch_range: Range<u32>,
148 pub extra_index: PhaseItemExtraIndex,
149}
150
151#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
154pub struct OpaqueNoLightmap3dBinKey {
155 pub pipeline: CachedRenderPipelineId,
157
158 pub draw_function: DrawFunctionId,
160
161 pub asset_id: UntypedAssetId,
163
164 pub material_bind_group_id: Option<BindGroupId>,
168}
169
170impl PhaseItem for Opaque3dPrepass {
171 #[inline]
172 fn entity(&self) -> Entity {
173 self.representative_entity.0
174 }
175
176 fn main_entity(&self) -> MainEntity {
177 self.representative_entity.1
178 }
179
180 #[inline]
181 fn draw_function(&self) -> DrawFunctionId {
182 self.key.draw_function
183 }
184
185 #[inline]
186 fn batch_range(&self) -> &Range<u32> {
187 &self.batch_range
188 }
189
190 #[inline]
191 fn batch_range_mut(&mut self) -> &mut Range<u32> {
192 &mut self.batch_range
193 }
194
195 #[inline]
196 fn extra_index(&self) -> PhaseItemExtraIndex {
197 self.extra_index
198 }
199
200 #[inline]
201 fn batch_range_and_extra_index_mut(&mut self) -> (&mut Range<u32>, &mut PhaseItemExtraIndex) {
202 (&mut self.batch_range, &mut self.extra_index)
203 }
204}
205
206impl BinnedPhaseItem for Opaque3dPrepass {
207 type BinKey = OpaqueNoLightmap3dBinKey;
208
209 #[inline]
210 fn new(
211 key: Self::BinKey,
212 representative_entity: (Entity, MainEntity),
213 batch_range: Range<u32>,
214 extra_index: PhaseItemExtraIndex,
215 ) -> Self {
216 Opaque3dPrepass {
217 key,
218 representative_entity,
219 batch_range,
220 extra_index,
221 }
222 }
223}
224
225impl CachedRenderPipelinePhaseItem for Opaque3dPrepass {
226 #[inline]
227 fn cached_pipeline(&self) -> CachedRenderPipelineId {
228 self.key.pipeline
229 }
230}
231
232pub struct AlphaMask3dPrepass {
238 pub key: OpaqueNoLightmap3dBinKey,
239 pub representative_entity: (Entity, MainEntity),
240 pub batch_range: Range<u32>,
241 pub extra_index: PhaseItemExtraIndex,
242}
243
244impl PhaseItem for AlphaMask3dPrepass {
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.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
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 AlphaMask3dPrepass {
281 type BinKey = OpaqueNoLightmap3dBinKey;
282
283 #[inline]
284 fn new(
285 key: Self::BinKey,
286 representative_entity: (Entity, MainEntity),
287 batch_range: Range<u32>,
288 extra_index: PhaseItemExtraIndex,
289 ) -> Self {
290 Self {
291 key,
292 representative_entity,
293 batch_range,
294 extra_index,
295 }
296 }
297}
298
299impl CachedRenderPipelinePhaseItem for AlphaMask3dPrepass {
300 #[inline]
301 fn cached_pipeline(&self) -> CachedRenderPipelineId {
302 self.key.pipeline
303 }
304}
305
306pub fn prepass_target_descriptors(
307 normal_prepass: bool,
308 motion_vector_prepass: bool,
309 deferred_prepass: bool,
310) -> Vec<Option<ColorTargetState>> {
311 vec![
312 normal_prepass.then_some(ColorTargetState {
313 format: NORMAL_PREPASS_FORMAT,
314 blend: None,
315 write_mask: ColorWrites::ALL,
316 }),
317 motion_vector_prepass.then_some(ColorTargetState {
318 format: MOTION_VECTOR_PREPASS_FORMAT,
319 blend: None,
320 write_mask: ColorWrites::ALL,
321 }),
322 deferred_prepass.then_some(ColorTargetState {
323 format: DEFERRED_PREPASS_FORMAT,
324 blend: None,
325 write_mask: ColorWrites::ALL,
326 }),
327 deferred_prepass.then_some(ColorTargetState {
328 format: DEFERRED_LIGHTING_PASS_ID_FORMAT,
329 blend: None,
330 write_mask: ColorWrites::ALL,
331 }),
332 ]
333}