Dispatch translucent-bucket draws (Transparent, Refractive, Additive). Caller owns a render pass set up with a single HDR attachment (LoadOp::Load) + depth read-only. Refractive materials additionally receive the SceneInputs bind group at group 4 — `update_scene_inputs` must have been called this frame for that to be non-None.
(
&'pass self,
pass: &mut wgpu::RenderPass<'pass>,
mut mesh_fetch: F,
)
| 1706 | /// group 4 — `update_scene_inputs` must have been called this |
| 1707 | /// frame for that to be non-None. |
| 1708 | pub fn dispatch_translucent<'pass, F>( |
| 1709 | &'pass self, |
| 1710 | pass: &mut wgpu::RenderPass<'pass>, |
| 1711 | mut mesh_fetch: F, |
| 1712 | ) |
| 1713 | where F: FnMut(u64, usize) -> Option<(&'pass wgpu::Buffer, &'pass wgpu::Buffer, u32)> |
| 1714 | { |
| 1715 | if self.translucent_commands.is_empty() { return; } |
| 1716 | |
| 1717 | let mut last_material: MaterialHandle = 0; |
| 1718 | let mut last_reads_scene: bool = false; |
| 1719 | for cmd in &self.translucent_commands { |
| 1720 | if cmd.material != last_material { |
| 1721 | let mat = match self.pipelines.get(cmd.material as usize - 1) { |
| 1722 | Some(Some(m)) => m, |
| 1723 | _ => continue, |
| 1724 | }; |
| 1725 | pass.set_pipeline(&mat.pipeline); |
| 1726 | pass.set_bind_group(0, &self.per_frame_bg, &[]); |
| 1727 | pass.set_bind_group(1, &self.per_view_bg, &[]); |
| 1728 | pass.set_bind_group(2, self.per_material_bg_for(cmd.material), &[]); |
| 1729 | if mat.reads_scene { |
| 1730 | if let Some(bg) = self.scene_inputs_bg.as_ref() { |
| 1731 | pass.set_bind_group(4, bg, &[]); |
| 1732 | } |
| 1733 | } |
| 1734 | last_material = cmd.material; |
| 1735 | last_reads_scene = mat.reads_scene; |
| 1736 | } |
| 1737 | // Re-bind group 4 if the material switches its reads_scene |
| 1738 | // between subsequent draws — rarely happens with a |
| 1739 | // stable bucket but keeps the state machine honest. |
| 1740 | let _ = last_reads_scene; |
| 1741 | |
| 1742 | if let Some((vb, ib, icount)) = mesh_fetch(cmd.mesh_handle, cmd.mesh_idx) { |
| 1743 | pass.set_bind_group(3, &self.per_draw_bgs[cmd.draw_slot], &[]); |
| 1744 | pass.set_vertex_buffer(0, vb.slice(..)); |
| 1745 | pass.set_index_buffer(ib.slice(..), wgpu::IndexFormat::Uint32); |
| 1746 | let instance_range = self.bind_instance_buffer(pass, &cmd.instance); |
| 1747 | if instance_range.end > instance_range.start { |
| 1748 | pass.draw_indexed(0..icount, 0, instance_range); |
| 1749 | } |
| 1750 | } |
| 1751 | } |
| 1752 | } |
| 1753 | } |
| 1754 | |
| 1755 | // ===================================================================== |