Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_pbr/src/meshlet/material_shade_nodes.rs
9294 views
1
use super::{
2
material_pipeline_prepare::{
3
MeshletViewMaterialsDeferredGBufferPrepass, MeshletViewMaterialsMainOpaquePass,
4
MeshletViewMaterialsPrepass,
5
},
6
resource_manager::{MeshletViewBindGroups, MeshletViewResources},
7
InstanceManager,
8
};
9
use crate::{
10
MeshViewBindGroup, PrepassViewBindGroup, ViewContactShadowsUniformOffset,
11
ViewEnvironmentMapUniformOffset, ViewFogUniformOffset, ViewLightProbesUniformOffset,
12
ViewLightsUniformOffset, ViewScreenSpaceReflectionsUniformOffset,
13
};
14
use bevy_camera::MainPassResolutionOverride;
15
use bevy_camera::Viewport;
16
use bevy_core_pipeline::prepass::{
17
MotionVectorPrepass, PreviousViewUniformOffset, ViewPrepassTextures,
18
};
19
use bevy_ecs::{prelude::*, query::Has};
20
use bevy_render::{
21
camera::ExtractedCamera,
22
render_resource::{
23
LoadOp, Operations, PipelineCache, RenderPassDepthStencilAttachment, RenderPassDescriptor,
24
StoreOp,
25
},
26
renderer::{RenderContext, ViewQuery},
27
view::{ViewTarget, ViewUniformOffset},
28
};
29
30
///
31
/// Fullscreen shading pass based on the visibility buffer generated from rasterizing meshlets.
32
pub fn meshlet_main_opaque_pass(
33
view: ViewQuery<(
34
&ExtractedCamera,
35
&ViewTarget,
36
&MeshViewBindGroup,
37
&ViewUniformOffset,
38
&ViewLightsUniformOffset,
39
&ViewFogUniformOffset,
40
&ViewLightProbesUniformOffset,
41
&ViewScreenSpaceReflectionsUniformOffset,
42
&ViewContactShadowsUniformOffset,
43
&ViewEnvironmentMapUniformOffset,
44
Option<&MainPassResolutionOverride>,
45
&MeshletViewMaterialsMainOpaquePass,
46
&MeshletViewBindGroups,
47
&MeshletViewResources,
48
)>,
49
instance_manager: Res<InstanceManager>,
50
pipeline_cache: Res<PipelineCache>,
51
mut ctx: RenderContext,
52
) {
53
let (
54
camera,
55
target,
56
mesh_view_bind_group,
57
view_uniform_offset,
58
view_lights_offset,
59
view_fog_offset,
60
view_light_probes_offset,
61
view_ssr_offset,
62
view_contact_shadows_offset,
63
view_environment_map_offset,
64
resolution_override,
65
meshlet_view_materials,
66
meshlet_view_bind_groups,
67
meshlet_view_resources,
68
) = view.into_inner();
69
70
if meshlet_view_materials.is_empty() {
71
return;
72
}
73
74
let (Some(meshlet_material_depth), Some(meshlet_material_shade_bind_group)) = (
75
meshlet_view_resources.material_depth.as_ref(),
76
meshlet_view_bind_groups.material_shade.as_ref(),
77
) else {
78
return;
79
};
80
81
let mut render_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {
82
label: Some("meshlet_material_opaque_3d_pass"),
83
color_attachments: &[Some(target.get_color_attachment())],
84
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
85
view: &meshlet_material_depth.default_view,
86
depth_ops: Some(Operations {
87
load: LoadOp::Load,
88
store: StoreOp::Store,
89
}),
90
stencil_ops: None,
91
}),
92
timestamp_writes: None,
93
occlusion_query_set: None,
94
multiview_mask: None,
95
});
96
97
if let Some(viewport) =
98
Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override)
99
{
100
render_pass.set_camera_viewport(&viewport);
101
}
102
103
render_pass.set_bind_group(
104
0,
105
&mesh_view_bind_group.main,
106
&[
107
view_uniform_offset.offset,
108
view_lights_offset.offset,
109
view_fog_offset.offset,
110
**view_light_probes_offset,
111
**view_ssr_offset,
112
**view_contact_shadows_offset,
113
**view_environment_map_offset,
114
],
115
);
116
render_pass.set_bind_group(1, &mesh_view_bind_group.binding_array, &[]);
117
render_pass.set_bind_group(2, meshlet_material_shade_bind_group, &[]);
118
119
// 1 fullscreen triangle draw per material
120
for (material_id, material_pipeline_id, material_bind_group) in meshlet_view_materials.iter() {
121
if instance_manager.material_present_in_scene(material_id)
122
&& let Some(material_pipeline) =
123
pipeline_cache.get_render_pipeline(*material_pipeline_id)
124
{
125
let x = *material_id * 3;
126
render_pass.set_render_pipeline(material_pipeline);
127
render_pass.set_bind_group(3, material_bind_group, &[]);
128
render_pass.draw(x..(x + 3), 0..1);
129
}
130
}
131
}
132
133
///
134
/// Fullscreen pass to generate prepass textures based on the visibility buffer generated from rasterizing meshlets.
135
pub fn meshlet_prepass(
136
view: ViewQuery<(
137
&ExtractedCamera,
138
&ViewPrepassTextures,
139
&ViewUniformOffset,
140
&PreviousViewUniformOffset,
141
Option<&MainPassResolutionOverride>,
142
Has<MotionVectorPrepass>,
143
&MeshletViewMaterialsPrepass,
144
&MeshletViewBindGroups,
145
&MeshletViewResources,
146
)>,
147
prepass_view_bind_group: Res<PrepassViewBindGroup>,
148
instance_manager: Res<InstanceManager>,
149
pipeline_cache: Res<PipelineCache>,
150
mut ctx: RenderContext,
151
) {
152
let (
153
camera,
154
view_prepass_textures,
155
view_uniform_offset,
156
previous_view_uniform_offset,
157
resolution_override,
158
view_has_motion_vector_prepass,
159
meshlet_view_materials,
160
meshlet_view_bind_groups,
161
meshlet_view_resources,
162
) = view.into_inner();
163
164
if meshlet_view_materials.is_empty() {
165
return;
166
}
167
168
let (Some(meshlet_material_depth), Some(meshlet_material_shade_bind_group)) = (
169
meshlet_view_resources.material_depth.as_ref(),
170
meshlet_view_bind_groups.material_shade.as_ref(),
171
) else {
172
return;
173
};
174
175
let color_attachments = vec![
176
view_prepass_textures
177
.normal
178
.as_ref()
179
.map(|normals_texture| normals_texture.get_attachment()),
180
view_prepass_textures
181
.motion_vectors
182
.as_ref()
183
.map(|motion_vectors_texture| motion_vectors_texture.get_attachment()),
184
// Use None in place of Deferred attachments
185
None,
186
None,
187
];
188
189
let mut render_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {
190
label: Some("meshlet_material_prepass"),
191
color_attachments: &color_attachments,
192
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
193
view: &meshlet_material_depth.default_view,
194
depth_ops: Some(Operations {
195
load: LoadOp::Load,
196
store: StoreOp::Store,
197
}),
198
stencil_ops: None,
199
}),
200
timestamp_writes: None,
201
occlusion_query_set: None,
202
multiview_mask: None,
203
});
204
205
if let Some(viewport) =
206
Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override)
207
{
208
render_pass.set_camera_viewport(&viewport);
209
}
210
211
if view_has_motion_vector_prepass {
212
render_pass.set_bind_group(
213
0,
214
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
215
&[
216
view_uniform_offset.offset,
217
previous_view_uniform_offset.offset,
218
],
219
);
220
} else {
221
render_pass.set_bind_group(
222
0,
223
prepass_view_bind_group.no_motion_vectors.as_ref().unwrap(),
224
&[view_uniform_offset.offset],
225
);
226
}
227
228
render_pass.set_bind_group(1, &prepass_view_bind_group.empty_bind_group, &[]);
229
render_pass.set_bind_group(2, meshlet_material_shade_bind_group, &[]);
230
231
// 1 fullscreen triangle draw per material
232
for (material_id, material_pipeline_id, material_bind_group) in meshlet_view_materials.iter() {
233
if instance_manager.material_present_in_scene(material_id)
234
&& let Some(material_pipeline) =
235
pipeline_cache.get_render_pipeline(*material_pipeline_id)
236
{
237
let x = *material_id * 3;
238
render_pass.set_render_pipeline(material_pipeline);
239
render_pass.set_bind_group(2, material_bind_group, &[]);
240
render_pass.draw(x..(x + 3), 0..1);
241
}
242
}
243
}
244
245
/// Fullscreen pass to generate a gbuffer based on the visibility buffer generated from rasterizing meshlets.
246
pub fn meshlet_deferred_gbuffer_prepass(
247
view: ViewQuery<(
248
&ExtractedCamera,
249
&ViewPrepassTextures,
250
&ViewUniformOffset,
251
&PreviousViewUniformOffset,
252
Option<&MainPassResolutionOverride>,
253
Has<MotionVectorPrepass>,
254
&MeshletViewMaterialsDeferredGBufferPrepass,
255
&MeshletViewBindGroups,
256
&MeshletViewResources,
257
)>,
258
prepass_view_bind_group: Res<PrepassViewBindGroup>,
259
instance_manager: Res<InstanceManager>,
260
pipeline_cache: Res<PipelineCache>,
261
mut ctx: RenderContext,
262
) {
263
let (
264
camera,
265
view_prepass_textures,
266
view_uniform_offset,
267
previous_view_uniform_offset,
268
resolution_override,
269
view_has_motion_vector_prepass,
270
meshlet_view_materials,
271
meshlet_view_bind_groups,
272
meshlet_view_resources,
273
) = view.into_inner();
274
275
if meshlet_view_materials.is_empty() {
276
return;
277
}
278
279
let (Some(meshlet_material_depth), Some(meshlet_material_shade_bind_group)) = (
280
meshlet_view_resources.material_depth.as_ref(),
281
meshlet_view_bind_groups.material_shade.as_ref(),
282
) else {
283
return;
284
};
285
286
let color_attachments = vec![
287
view_prepass_textures
288
.normal
289
.as_ref()
290
.map(|normals_texture| normals_texture.get_attachment()),
291
view_prepass_textures
292
.motion_vectors
293
.as_ref()
294
.map(|motion_vectors_texture| motion_vectors_texture.get_attachment()),
295
view_prepass_textures
296
.deferred
297
.as_ref()
298
.map(|deferred_texture| deferred_texture.get_attachment()),
299
view_prepass_textures
300
.deferred_lighting_pass_id
301
.as_ref()
302
.map(|deferred_lighting_pass_id| deferred_lighting_pass_id.get_attachment()),
303
];
304
305
let mut render_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {
306
label: Some("meshlet_material_deferred_prepass"),
307
color_attachments: &color_attachments,
308
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
309
view: &meshlet_material_depth.default_view,
310
depth_ops: Some(Operations {
311
load: LoadOp::Load,
312
store: StoreOp::Store,
313
}),
314
stencil_ops: None,
315
}),
316
timestamp_writes: None,
317
occlusion_query_set: None,
318
multiview_mask: None,
319
});
320
321
if let Some(viewport) =
322
Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override)
323
{
324
render_pass.set_camera_viewport(&viewport);
325
}
326
327
if view_has_motion_vector_prepass {
328
render_pass.set_bind_group(
329
0,
330
prepass_view_bind_group.motion_vectors.as_ref().unwrap(),
331
&[
332
view_uniform_offset.offset,
333
previous_view_uniform_offset.offset,
334
],
335
);
336
} else {
337
render_pass.set_bind_group(
338
0,
339
prepass_view_bind_group.no_motion_vectors.as_ref().unwrap(),
340
&[view_uniform_offset.offset],
341
);
342
}
343
344
render_pass.set_bind_group(1, &prepass_view_bind_group.empty_bind_group, &[]);
345
render_pass.set_bind_group(2, meshlet_material_shade_bind_group, &[]);
346
347
// 1 fullscreen triangle draw per material
348
for (material_id, material_pipeline_id, material_bind_group) in meshlet_view_materials.iter() {
349
if instance_manager.material_present_in_scene(material_id)
350
&& let Some(material_pipeline) =
351
pipeline_cache.get_render_pipeline(*material_pipeline_id)
352
{
353
let x = *material_id * 3;
354
render_pass.set_render_pipeline(material_pipeline);
355
render_pass.set_bind_group(2, material_bind_group, &[]);
356
render_pass.draw(x..(x + 3), 0..1);
357
}
358
}
359
}
360
361