Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs
9374 views
1
use super::{
2
pipelines::MeshletPipelines,
3
resource_manager::{MeshletViewBindGroups, MeshletViewResources, ResourceManager},
4
};
5
use crate::{LightEntity, ShadowView, ViewLightEntities};
6
use bevy_color::LinearRgba;
7
use bevy_core_pipeline::prepass::PreviousViewUniformOffset;
8
use bevy_ecs::prelude::*;
9
use bevy_math::UVec2;
10
use bevy_render::{
11
camera::ExtractedCamera,
12
diagnostic::RecordDiagnostics,
13
render_resource::*,
14
renderer::{RenderContext, ViewQuery},
15
view::{ViewDepthTexture, ViewUniformOffset},
16
};
17
18
///
19
/// Rasterize meshlets into a depth buffer, and optional visibility buffer + material depth buffer for shading passes.
20
// TODO: Reuse compute/render passes between logical passes where possible, as they're expensive
21
pub fn meshlet_visibility_buffer_raster(
22
world: &World,
23
view: ViewQuery<(
24
&ExtractedCamera,
25
&ViewDepthTexture,
26
&ViewUniformOffset,
27
&PreviousViewUniformOffset,
28
&MeshletViewBindGroups,
29
&MeshletViewResources,
30
&ViewLightEntities,
31
)>,
32
view_light_query: Query<(
33
&ShadowView,
34
&LightEntity,
35
&ViewUniformOffset,
36
&PreviousViewUniformOffset,
37
&MeshletViewBindGroups,
38
&MeshletViewResources,
39
)>,
40
resource_manager: Res<ResourceManager>,
41
mut ctx: RenderContext,
42
) {
43
let (
44
camera,
45
view_depth,
46
view_offset,
47
previous_view_offset,
48
meshlet_view_bind_groups,
49
meshlet_view_resources,
50
lights,
51
) = view.into_inner();
52
53
let Some((
54
clear_visibility_buffer_pipeline,
55
clear_visibility_buffer_shadow_view_pipeline,
56
first_instance_cull_pipeline,
57
second_instance_cull_pipeline,
58
first_bvh_cull_pipeline,
59
second_bvh_cull_pipeline,
60
first_meshlet_cull_pipeline,
61
second_meshlet_cull_pipeline,
62
downsample_depth_first_pipeline,
63
downsample_depth_second_pipeline,
64
downsample_depth_first_shadow_view_pipeline,
65
downsample_depth_second_shadow_view_pipeline,
66
visibility_buffer_software_raster_pipeline,
67
visibility_buffer_software_raster_shadow_view_pipeline,
68
visibility_buffer_hardware_raster_pipeline,
69
visibility_buffer_hardware_raster_shadow_view_pipeline,
70
visibility_buffer_hardware_raster_shadow_view_unclipped_pipeline,
71
resolve_depth_pipeline,
72
resolve_depth_shadow_view_pipeline,
73
resolve_material_depth_pipeline,
74
remap_1d_to_2d_dispatch_pipeline,
75
fill_counts_pipeline,
76
)) = MeshletPipelines::get(world)
77
else {
78
return;
79
};
80
81
let diagnostics = ctx.diagnostic_recorder();
82
let diagnostics = diagnostics.as_deref();
83
84
ctx.command_encoder()
85
.push_debug_group("meshlet_visibility_buffer_raster");
86
let time_span =
87
diagnostics.time_span(ctx.command_encoder(), "meshlet_visibility_buffer_raster");
88
89
ctx.command_encoder().clear_buffer(
90
&resource_manager.visibility_buffer_raster_cluster_prev_counts,
91
0,
92
None,
93
);
94
95
clear_visibility_buffer_pass(
96
&mut ctx,
97
&meshlet_view_bind_groups.clear_visibility_buffer,
98
clear_visibility_buffer_pipeline,
99
meshlet_view_resources.view_size,
100
);
101
102
ctx.command_encoder().push_debug_group("meshlet_first_pass");
103
first_cull(
104
&mut ctx,
105
meshlet_view_bind_groups,
106
meshlet_view_resources,
107
view_offset,
108
previous_view_offset,
109
first_instance_cull_pipeline,
110
first_bvh_cull_pipeline,
111
first_meshlet_cull_pipeline,
112
remap_1d_to_2d_dispatch_pipeline,
113
);
114
raster_pass(
115
true,
116
&mut ctx,
117
&meshlet_view_resources.visibility_buffer_software_raster_indirect_args,
118
&meshlet_view_resources.visibility_buffer_hardware_raster_indirect_args,
119
&meshlet_view_resources.dummy_render_target.default_view,
120
meshlet_view_bind_groups,
121
view_offset,
122
visibility_buffer_software_raster_pipeline,
123
visibility_buffer_hardware_raster_pipeline,
124
fill_counts_pipeline,
125
Some(camera),
126
meshlet_view_resources.rightmost_slot,
127
);
128
ctx.command_encoder().pop_debug_group();
129
130
meshlet_view_resources
131
.depth_pyramid
132
.downsample_depth_with_ctx(
133
"downsample_depth",
134
&mut ctx,
135
meshlet_view_resources.view_size,
136
&meshlet_view_bind_groups.downsample_depth,
137
downsample_depth_first_pipeline,
138
downsample_depth_second_pipeline,
139
);
140
141
ctx.command_encoder()
142
.push_debug_group("meshlet_second_pass");
143
second_cull(
144
&mut ctx,
145
meshlet_view_bind_groups,
146
meshlet_view_resources,
147
view_offset,
148
previous_view_offset,
149
second_instance_cull_pipeline,
150
second_bvh_cull_pipeline,
151
second_meshlet_cull_pipeline,
152
remap_1d_to_2d_dispatch_pipeline,
153
);
154
raster_pass(
155
false,
156
&mut ctx,
157
&meshlet_view_resources.visibility_buffer_software_raster_indirect_args,
158
&meshlet_view_resources.visibility_buffer_hardware_raster_indirect_args,
159
&meshlet_view_resources.dummy_render_target.default_view,
160
meshlet_view_bind_groups,
161
view_offset,
162
visibility_buffer_software_raster_pipeline,
163
visibility_buffer_hardware_raster_pipeline,
164
fill_counts_pipeline,
165
Some(camera),
166
meshlet_view_resources.rightmost_slot,
167
);
168
ctx.command_encoder().pop_debug_group();
169
170
resolve_depth(
171
&mut ctx,
172
view_depth.get_attachment(StoreOp::Store),
173
meshlet_view_bind_groups,
174
resolve_depth_pipeline,
175
camera,
176
);
177
resolve_material_depth(
178
&mut ctx,
179
meshlet_view_resources,
180
meshlet_view_bind_groups,
181
resolve_material_depth_pipeline,
182
camera,
183
);
184
meshlet_view_resources
185
.depth_pyramid
186
.downsample_depth_with_ctx(
187
"downsample_depth",
188
&mut ctx,
189
meshlet_view_resources.view_size,
190
&meshlet_view_bind_groups.downsample_depth,
191
downsample_depth_first_pipeline,
192
downsample_depth_second_pipeline,
193
);
194
ctx.command_encoder().pop_debug_group();
195
time_span.end(ctx.command_encoder());
196
197
for light_entity in &lights.lights {
198
let Ok((
199
shadow_view,
200
light_type,
201
view_offset,
202
previous_view_offset,
203
meshlet_view_bind_groups,
204
meshlet_view_resources,
205
)) = view_light_query.get(*light_entity)
206
else {
207
continue;
208
};
209
210
let shadow_visibility_buffer_hardware_raster_pipeline =
211
if let LightEntity::Directional { .. } = light_type {
212
visibility_buffer_hardware_raster_shadow_view_unclipped_pipeline
213
} else {
214
visibility_buffer_hardware_raster_shadow_view_pipeline
215
};
216
217
ctx.command_encoder().push_debug_group(&format!(
218
"meshlet_visibility_buffer_raster: {}",
219
shadow_view.pass_name
220
));
221
let time_span_shadow =
222
diagnostics.time_span(ctx.command_encoder(), shadow_view.pass_name.clone());
223
224
clear_visibility_buffer_pass(
225
&mut ctx,
226
&meshlet_view_bind_groups.clear_visibility_buffer,
227
clear_visibility_buffer_shadow_view_pipeline,
228
meshlet_view_resources.view_size,
229
);
230
231
ctx.command_encoder().push_debug_group("meshlet_first_pass");
232
first_cull(
233
&mut ctx,
234
meshlet_view_bind_groups,
235
meshlet_view_resources,
236
view_offset,
237
previous_view_offset,
238
first_instance_cull_pipeline,
239
first_bvh_cull_pipeline,
240
first_meshlet_cull_pipeline,
241
remap_1d_to_2d_dispatch_pipeline,
242
);
243
raster_pass(
244
true,
245
&mut ctx,
246
&meshlet_view_resources.visibility_buffer_software_raster_indirect_args,
247
&meshlet_view_resources.visibility_buffer_hardware_raster_indirect_args,
248
&meshlet_view_resources.dummy_render_target.default_view,
249
meshlet_view_bind_groups,
250
view_offset,
251
visibility_buffer_software_raster_shadow_view_pipeline,
252
shadow_visibility_buffer_hardware_raster_pipeline,
253
fill_counts_pipeline,
254
None,
255
meshlet_view_resources.rightmost_slot,
256
);
257
ctx.command_encoder().pop_debug_group();
258
259
meshlet_view_resources
260
.depth_pyramid
261
.downsample_depth_with_ctx(
262
"downsample_depth",
263
&mut ctx,
264
meshlet_view_resources.view_size,
265
&meshlet_view_bind_groups.downsample_depth,
266
downsample_depth_first_shadow_view_pipeline,
267
downsample_depth_second_shadow_view_pipeline,
268
);
269
270
ctx.command_encoder()
271
.push_debug_group("meshlet_second_pass");
272
second_cull(
273
&mut ctx,
274
meshlet_view_bind_groups,
275
meshlet_view_resources,
276
view_offset,
277
previous_view_offset,
278
second_instance_cull_pipeline,
279
second_bvh_cull_pipeline,
280
second_meshlet_cull_pipeline,
281
remap_1d_to_2d_dispatch_pipeline,
282
);
283
raster_pass(
284
false,
285
&mut ctx,
286
&meshlet_view_resources.visibility_buffer_software_raster_indirect_args,
287
&meshlet_view_resources.visibility_buffer_hardware_raster_indirect_args,
288
&meshlet_view_resources.dummy_render_target.default_view,
289
meshlet_view_bind_groups,
290
view_offset,
291
visibility_buffer_software_raster_shadow_view_pipeline,
292
shadow_visibility_buffer_hardware_raster_pipeline,
293
fill_counts_pipeline,
294
None,
295
meshlet_view_resources.rightmost_slot,
296
);
297
ctx.command_encoder().pop_debug_group();
298
299
resolve_depth(
300
&mut ctx,
301
shadow_view.depth_attachment.get_attachment(StoreOp::Store),
302
meshlet_view_bind_groups,
303
resolve_depth_shadow_view_pipeline,
304
camera,
305
);
306
meshlet_view_resources
307
.depth_pyramid
308
.downsample_depth_with_ctx(
309
"downsample_depth",
310
&mut ctx,
311
meshlet_view_resources.view_size,
312
&meshlet_view_bind_groups.downsample_depth,
313
downsample_depth_first_shadow_view_pipeline,
314
downsample_depth_second_shadow_view_pipeline,
315
);
316
ctx.command_encoder().pop_debug_group();
317
time_span_shadow.end(ctx.command_encoder());
318
}
319
}
320
321
// TODO: Replace this with vkCmdClearColorImage once wgpu supports it
322
fn clear_visibility_buffer_pass(
323
ctx: &mut RenderContext,
324
clear_visibility_buffer_bind_group: &BindGroup,
325
clear_visibility_buffer_pipeline: &ComputePipeline,
326
view_size: UVec2,
327
) {
328
let command_encoder = ctx.command_encoder();
329
let mut clear_visibility_buffer_pass =
330
command_encoder.begin_compute_pass(&ComputePassDescriptor {
331
label: Some("clear_visibility_buffer"),
332
timestamp_writes: None,
333
});
334
clear_visibility_buffer_pass.set_pipeline(clear_visibility_buffer_pipeline);
335
clear_visibility_buffer_pass.set_immediates(0, bytemuck::bytes_of(&view_size));
336
clear_visibility_buffer_pass.set_bind_group(0, clear_visibility_buffer_bind_group, &[]);
337
clear_visibility_buffer_pass.dispatch_workgroups(
338
view_size.x.div_ceil(16),
339
view_size.y.div_ceil(16),
340
1,
341
);
342
}
343
344
fn first_cull(
345
ctx: &mut RenderContext,
346
meshlet_view_bind_groups: &MeshletViewBindGroups,
347
meshlet_view_resources: &MeshletViewResources,
348
view_offset: &ViewUniformOffset,
349
previous_view_offset: &PreviousViewUniformOffset,
350
first_instance_cull_pipeline: &ComputePipeline,
351
first_bvh_cull_pipeline: &ComputePipeline,
352
first_meshlet_cull_pipeline: &ComputePipeline,
353
remap_1d_to_2d_pipeline: Option<&ComputePipeline>,
354
) {
355
let workgroups = meshlet_view_resources.scene_instance_count.div_ceil(128);
356
cull_pass(
357
"meshlet_first_instance_cull",
358
ctx,
359
&meshlet_view_bind_groups.first_instance_cull,
360
view_offset,
361
previous_view_offset,
362
first_instance_cull_pipeline,
363
&[meshlet_view_resources.scene_instance_count],
364
)
365
.dispatch_workgroups(workgroups, 1, 1);
366
367
ctx.command_encoder()
368
.push_debug_group("meshlet_first_bvh_cull");
369
let mut ping = true;
370
for _ in 0..meshlet_view_resources.max_bvh_depth {
371
cull_pass(
372
"meshlet_first_bvh_cull_dispatch",
373
ctx,
374
if ping {
375
&meshlet_view_bind_groups.first_bvh_cull_ping
376
} else {
377
&meshlet_view_bind_groups.first_bvh_cull_pong
378
},
379
view_offset,
380
previous_view_offset,
381
first_bvh_cull_pipeline,
382
&[ping as u32, meshlet_view_resources.rightmost_slot],
383
)
384
.dispatch_workgroups_indirect(
385
if ping {
386
&meshlet_view_resources.first_bvh_cull_dispatch_front
387
} else {
388
&meshlet_view_resources.first_bvh_cull_dispatch_back
389
},
390
0,
391
);
392
ctx.command_encoder().clear_buffer(
393
if ping {
394
&meshlet_view_resources.first_bvh_cull_count_front
395
} else {
396
&meshlet_view_resources.first_bvh_cull_count_back
397
},
398
0,
399
Some(4),
400
);
401
ctx.command_encoder().clear_buffer(
402
if ping {
403
&meshlet_view_resources.first_bvh_cull_dispatch_front
404
} else {
405
&meshlet_view_resources.first_bvh_cull_dispatch_back
406
},
407
0,
408
Some(4),
409
);
410
ping = !ping;
411
}
412
ctx.command_encoder().pop_debug_group();
413
414
let mut pass = cull_pass(
415
"meshlet_first_meshlet_cull",
416
ctx,
417
&meshlet_view_bind_groups.first_meshlet_cull,
418
view_offset,
419
previous_view_offset,
420
first_meshlet_cull_pipeline,
421
&[meshlet_view_resources.rightmost_slot],
422
);
423
pass.dispatch_workgroups_indirect(&meshlet_view_resources.front_meshlet_cull_dispatch, 0);
424
remap_1d_to_2d(
425
pass,
426
remap_1d_to_2d_pipeline,
427
meshlet_view_bind_groups.remap_1d_to_2d_dispatch.as_ref(),
428
);
429
}
430
431
fn second_cull(
432
ctx: &mut RenderContext,
433
meshlet_view_bind_groups: &MeshletViewBindGroups,
434
meshlet_view_resources: &MeshletViewResources,
435
view_offset: &ViewUniformOffset,
436
previous_view_offset: &PreviousViewUniformOffset,
437
second_instance_cull_pipeline: &ComputePipeline,
438
second_bvh_cull_pipeline: &ComputePipeline,
439
second_meshlet_cull_pipeline: &ComputePipeline,
440
remap_1d_to_2d_pipeline: Option<&ComputePipeline>,
441
) {
442
cull_pass(
443
"meshlet_second_instance_cull",
444
ctx,
445
&meshlet_view_bind_groups.second_instance_cull,
446
view_offset,
447
previous_view_offset,
448
second_instance_cull_pipeline,
449
&[meshlet_view_resources.scene_instance_count],
450
)
451
.dispatch_workgroups_indirect(&meshlet_view_resources.second_pass_dispatch, 0);
452
453
ctx.command_encoder()
454
.push_debug_group("meshlet_second_bvh_cull");
455
let mut ping = true;
456
for _ in 0..meshlet_view_resources.max_bvh_depth {
457
cull_pass(
458
"meshlet_second_bvh_cull_dispatch",
459
ctx,
460
if ping {
461
&meshlet_view_bind_groups.second_bvh_cull_ping
462
} else {
463
&meshlet_view_bind_groups.second_bvh_cull_pong
464
},
465
view_offset,
466
previous_view_offset,
467
second_bvh_cull_pipeline,
468
&[ping as u32, meshlet_view_resources.rightmost_slot],
469
)
470
.dispatch_workgroups_indirect(
471
if ping {
472
&meshlet_view_resources.second_bvh_cull_dispatch_front
473
} else {
474
&meshlet_view_resources.second_bvh_cull_dispatch_back
475
},
476
0,
477
);
478
ping = !ping;
479
}
480
ctx.command_encoder().pop_debug_group();
481
482
let mut pass = cull_pass(
483
"meshlet_second_meshlet_cull",
484
ctx,
485
&meshlet_view_bind_groups.second_meshlet_cull,
486
view_offset,
487
previous_view_offset,
488
second_meshlet_cull_pipeline,
489
&[meshlet_view_resources.rightmost_slot],
490
);
491
pass.dispatch_workgroups_indirect(&meshlet_view_resources.back_meshlet_cull_dispatch, 0);
492
remap_1d_to_2d(
493
pass,
494
remap_1d_to_2d_pipeline,
495
meshlet_view_bind_groups.remap_1d_to_2d_dispatch.as_ref(),
496
);
497
}
498
499
fn cull_pass<'a>(
500
label: &'static str,
501
ctx: &'a mut RenderContext,
502
bind_group: &'a BindGroup,
503
view_offset: &'a ViewUniformOffset,
504
previous_view_offset: &'a PreviousViewUniformOffset,
505
pipeline: &'a ComputePipeline,
506
immediates: &[u32],
507
) -> ComputePass<'a> {
508
let command_encoder = ctx.command_encoder();
509
let mut pass = command_encoder.begin_compute_pass(&ComputePassDescriptor {
510
label: Some(label),
511
timestamp_writes: None,
512
});
513
pass.set_pipeline(pipeline);
514
pass.set_bind_group(
515
0,
516
bind_group,
517
&[view_offset.offset, previous_view_offset.offset],
518
);
519
pass.set_immediates(0, bytemuck::cast_slice(immediates));
520
pass
521
}
522
523
fn remap_1d_to_2d(
524
mut pass: ComputePass,
525
pipeline: Option<&ComputePipeline>,
526
bind_group: Option<&BindGroup>,
527
) {
528
if let (Some(pipeline), Some(bind_group)) = (pipeline, bind_group) {
529
pass.set_pipeline(pipeline);
530
pass.set_bind_group(0, bind_group, &[]);
531
pass.dispatch_workgroups(1, 1, 1);
532
}
533
}
534
535
fn raster_pass(
536
first_pass: bool,
537
ctx: &mut RenderContext,
538
visibility_buffer_software_raster_indirect_args: &Buffer,
539
visibility_buffer_hardware_raster_indirect_args: &Buffer,
540
dummy_render_target: &TextureView,
541
meshlet_view_bind_groups: &MeshletViewBindGroups,
542
view_offset: &ViewUniformOffset,
543
visibility_buffer_software_raster_pipeline: &ComputePipeline,
544
visibility_buffer_hardware_raster_pipeline: &RenderPipeline,
545
fill_counts_pipeline: &ComputePipeline,
546
camera: Option<&ExtractedCamera>,
547
raster_cluster_rightmost_slot: u32,
548
) {
549
let mut software_pass = ctx
550
.command_encoder()
551
.begin_compute_pass(&ComputePassDescriptor {
552
label: Some(if first_pass {
553
"raster_software_first"
554
} else {
555
"raster_software_second"
556
}),
557
timestamp_writes: None,
558
});
559
software_pass.set_pipeline(visibility_buffer_software_raster_pipeline);
560
software_pass.set_bind_group(
561
0,
562
&meshlet_view_bind_groups.visibility_buffer_raster,
563
&[view_offset.offset],
564
);
565
software_pass.dispatch_workgroups_indirect(visibility_buffer_software_raster_indirect_args, 0);
566
drop(software_pass);
567
568
let mut hardware_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {
569
label: Some(if first_pass {
570
"raster_hardware_first"
571
} else {
572
"raster_hardware_second"
573
}),
574
color_attachments: &[Some(RenderPassColorAttachment {
575
view: dummy_render_target,
576
depth_slice: None,
577
resolve_target: None,
578
ops: Operations {
579
load: LoadOp::Clear(LinearRgba::BLACK.into()),
580
store: StoreOp::Discard,
581
},
582
})],
583
depth_stencil_attachment: None,
584
timestamp_writes: None,
585
occlusion_query_set: None,
586
multiview_mask: None,
587
});
588
if let Some(viewport) = camera.and_then(|camera| camera.viewport.as_ref()) {
589
hardware_pass.set_camera_viewport(viewport);
590
}
591
hardware_pass.set_render_pipeline(visibility_buffer_hardware_raster_pipeline);
592
hardware_pass.set_immediates(0, &raster_cluster_rightmost_slot.to_le_bytes());
593
hardware_pass.set_bind_group(
594
0,
595
&meshlet_view_bind_groups.visibility_buffer_raster,
596
&[view_offset.offset],
597
);
598
hardware_pass.draw_indirect(visibility_buffer_hardware_raster_indirect_args, 0);
599
drop(hardware_pass);
600
601
let mut fill_counts_pass = ctx
602
.command_encoder()
603
.begin_compute_pass(&ComputePassDescriptor {
604
label: Some("fill_counts"),
605
timestamp_writes: None,
606
});
607
fill_counts_pass.set_pipeline(fill_counts_pipeline);
608
fill_counts_pass.set_bind_group(0, &meshlet_view_bind_groups.fill_counts, &[]);
609
fill_counts_pass.dispatch_workgroups(1, 1, 1);
610
}
611
612
fn resolve_depth(
613
ctx: &mut RenderContext,
614
depth_stencil_attachment: RenderPassDepthStencilAttachment,
615
meshlet_view_bind_groups: &MeshletViewBindGroups,
616
resolve_depth_pipeline: &RenderPipeline,
617
camera: &ExtractedCamera,
618
) {
619
let mut resolve_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {
620
label: Some("resolve_depth"),
621
color_attachments: &[],
622
depth_stencil_attachment: Some(depth_stencil_attachment),
623
timestamp_writes: None,
624
occlusion_query_set: None,
625
multiview_mask: None,
626
});
627
if let Some(viewport) = &camera.viewport {
628
resolve_pass.set_camera_viewport(viewport);
629
}
630
resolve_pass.set_render_pipeline(resolve_depth_pipeline);
631
resolve_pass.set_bind_group(0, &meshlet_view_bind_groups.resolve_depth, &[]);
632
resolve_pass.draw(0..3, 0..1);
633
}
634
635
fn resolve_material_depth(
636
ctx: &mut RenderContext,
637
meshlet_view_resources: &MeshletViewResources,
638
meshlet_view_bind_groups: &MeshletViewBindGroups,
639
resolve_material_depth_pipeline: &RenderPipeline,
640
camera: &ExtractedCamera,
641
) {
642
if let (Some(material_depth), Some(resolve_material_depth_bind_group)) = (
643
meshlet_view_resources.material_depth.as_ref(),
644
meshlet_view_bind_groups.resolve_material_depth.as_ref(),
645
) {
646
let mut resolve_pass = ctx.begin_tracked_render_pass(RenderPassDescriptor {
647
label: Some("resolve_material_depth"),
648
color_attachments: &[],
649
depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
650
view: &material_depth.default_view,
651
depth_ops: Some(Operations {
652
load: LoadOp::Clear(0.0),
653
store: StoreOp::Store,
654
}),
655
stencil_ops: None,
656
}),
657
timestamp_writes: None,
658
occlusion_query_set: None,
659
multiview_mask: None,
660
});
661
if let Some(viewport) = &camera.viewport {
662
resolve_pass.set_camera_viewport(viewport);
663
}
664
resolve_pass.set_render_pipeline(resolve_material_depth_pipeline);
665
resolve_pass.set_bind_group(0, resolve_material_depth_bind_group, &[]);
666
resolve_pass.draw(0..3, 0..1);
667
}
668
}
669
670