EN-011 — like `dispatch`, but uses a caller-supplied PerView bind group (so the planar-reflection pass can render the same draws against a mirrored camera UBO) and skips any command whose material handle the `accept` predicate rejects (so the reflection pass can drop hardcoded-excluded materials — foliage, particles, grass — without touching the original command list). `accept` is consulted once
(
&'pass self,
pass: &mut wgpu::RenderPass<'pass>,
per_view_bg: &'pass wgpu::BindGroup,
mut accept: A,
use_reflection_pipeline: bool,
mut mesh_fetch: F
| 1582 | /// exists (translucent / cutout materials, where the original |
| 1583 | /// pipeline already cull-mode = None and no flip is needed). |
| 1584 | pub fn dispatch_with_view<'pass, F, A>( |
| 1585 | &'pass self, |
| 1586 | pass: &mut wgpu::RenderPass<'pass>, |
| 1587 | per_view_bg: &'pass wgpu::BindGroup, |
| 1588 | mut accept: A, |
| 1589 | use_reflection_pipeline: bool, |
| 1590 | mut mesh_fetch: F, |
| 1591 | ) |
| 1592 | where |
| 1593 | F: FnMut(u64, usize) -> Option<(&'pass wgpu::Buffer, &'pass wgpu::Buffer, u32)>, |
| 1594 | A: FnMut(MaterialHandle) -> bool, |
| 1595 | { |
| 1596 | if self.commands.is_empty() { return; } |
| 1597 | |
| 1598 | let mut last_material: MaterialHandle = 0; |
| 1599 | for cmd in &self.commands { |
| 1600 | if !accept(cmd.material) { continue; } |
| 1601 | if cmd.material != last_material { |
| 1602 | let mat = match self.pipelines.get(cmd.material as usize - 1) { |
| 1603 | Some(Some(m)) => m, |
| 1604 | _ => continue, |
| 1605 | }; |
| 1606 | let pipeline = if use_reflection_pipeline { |
| 1607 | mat.reflection_pipeline.as_ref().unwrap_or(&mat.pipeline) |
| 1608 | } else { |
| 1609 | &mat.pipeline |
| 1610 | }; |
| 1611 | pass.set_pipeline(pipeline); |
| 1612 | pass.set_bind_group(0, &self.per_frame_bg, &[]); |
| 1613 | pass.set_bind_group(1, per_view_bg, &[]); |
| 1614 | pass.set_bind_group(2, self.per_material_bg_for(cmd.material), &[]); |
| 1615 | last_material = cmd.material; |
| 1616 | } |
| 1617 | if let Some((vb, ib, icount)) = mesh_fetch(cmd.mesh_handle, cmd.mesh_idx) { |
| 1618 | pass.set_bind_group(3, &self.per_draw_bgs[cmd.draw_slot], &[]); |
| 1619 | pass.set_vertex_buffer(0, vb.slice(..)); |
| 1620 | pass.set_index_buffer(ib.slice(..), wgpu::IndexFormat::Uint32); |
| 1621 | let instance_range = self.bind_instance_buffer(pass, &cmd.instance); |
| 1622 | if instance_range.end > instance_range.start { |
| 1623 | pass.draw_indexed(0..icount, 0, instance_range); |
| 1624 | } |
| 1625 | } |
| 1626 | } |
| 1627 | } |
| 1628 | |
| 1629 | /// EN-001 — resolve an instanced draw command's vertex slot 1 binding |
| 1630 | /// and return the instance range. For non-instanced draws (`info` is |
no test coverage detected