maplibre/render/
translucent_pass.rs

1use std::ops::Deref;
2
3use wgpu::StoreOp;
4
5use crate::{
6    render::{
7        draw_graph,
8        graph::{Node, NodeRunError, RenderContext, RenderGraphContext, SlotInfo},
9        render_phase::{RenderPhase, TranslucentItem},
10        resource::TrackedRenderPass,
11        Eventually::Initialized,
12        RenderResources,
13    },
14    tcs::world::World,
15};
16
17pub struct TranslucentPassNode {}
18
19impl TranslucentPassNode {
20    pub fn new() -> Self {
21        Self {}
22    }
23}
24
25impl Node for TranslucentPassNode {
26    fn input(&self) -> Vec<SlotInfo> {
27        vec![]
28    }
29
30    fn update(&mut self, _state: &mut RenderResources) {}
31
32    fn run(
33        &self,
34        _graph: &mut RenderGraphContext,
35        render_context: &mut RenderContext,
36        state: &RenderResources,
37        world: &World,
38    ) -> Result<(), NodeRunError> {
39        let Initialized(render_target) = &state.render_target else {
40            return Ok(());
41        };
42        let Initialized(multisampling_texture) = &state.multisampling_texture else {
43            return Ok(());
44        };
45
46        let color_attachment = if let Some(texture) = multisampling_texture {
47            wgpu::RenderPassColorAttachment {
48                view: &texture.view,
49                ops: wgpu::Operations {
50                    load: wgpu::LoadOp::Load,
51                    store: StoreOp::Store,
52                },
53                resolve_target: Some(render_target.deref()),
54            }
55        } else {
56            wgpu::RenderPassColorAttachment {
57                view: render_target.deref(),
58                ops: wgpu::Operations {
59                    load: wgpu::LoadOp::Load,
60                    store: StoreOp::Store,
61                },
62                resolve_target: None,
63            }
64        };
65
66        let render_pass =
67            render_context
68                .command_encoder
69                .begin_render_pass(&wgpu::RenderPassDescriptor {
70                    label: Some("translucent_pass"),
71                    color_attachments: &[Some(color_attachment)],
72                    depth_stencil_attachment: None,
73                    timestamp_writes: None,
74                    occlusion_query_set: None,
75                });
76
77        let mut tracked_pass = TrackedRenderPass::new(render_pass);
78
79        // TODO: Automatically raise error when items get linearly too many (+1k)
80
81        if let Some(mask_items) = world.resources.get::<RenderPhase<TranslucentItem>>() {
82            log::trace!(
83                "RenderPhase<TranslucentItem>::size() = {}",
84                mask_items.size()
85            );
86            for item in mask_items {
87                item.draw_function.draw(&mut tracked_pass, world, item);
88            }
89        }
90
91        Ok(())
92    }
93}
94
95pub struct MainPassDriverNode;
96
97impl Node for MainPassDriverNode {
98    fn run(
99        &self,
100        graph: &mut RenderGraphContext,
101        _render_context: &mut RenderContext,
102        _resources: &RenderResources,
103        _world: &World,
104    ) -> Result<(), NodeRunError> {
105        graph.run_sub_graph(draw_graph::NAME, vec![])?;
106
107        Ok(())
108    }
109}