Skip to main content

cvkg_render_gpu/passes/
ssao.rs

1//! Screen Space Ambient Occlusion (SSAO) pass.
2//! Computes ambient occlusion based on depth and normal G-buffer inputs.
3
4use crate::kvasir::nodes::PassId;
5use crate::kvasir::{ExecutionContext, KvasirNode, ResourceId};
6
7/// Resource ID for the output SSAO texture.
8pub const RES_SSAO_OUT: ResourceId = ResourceId(403);
9
10/// SSAO pass node.
11pub struct SsaoNode {
12    /// Depth buffer texture resource to sample from.
13    pub depth_buffer: ResourceId,
14    /// Normal G-buffer texture resource.
15    pub normal_buffer: ResourceId,
16    /// Cached inputs slice container to satisfy lifetime requirements.
17    pub inputs: [ResourceId; 2],
18}
19
20impl KvasirNode for SsaoNode {
21    fn label(&self) -> &'static str {
22        "SsaoPass"
23    }
24
25    fn inputs(&self) -> &[ResourceId] {
26        &self.inputs
27    }
28
29    fn outputs(&self) -> &[ResourceId] {
30        std::slice::from_ref(&RES_SSAO_OUT)
31    }
32
33    fn pass_id(&self) -> PassId {
34        PassId::Geometry
35    }
36
37    fn execute(&self, ctx: &mut ExecutionContext) {
38        tracing::debug!("SsaoNode::execute - Computing SSAO texture");
39
40        let ssao_view = match ctx.registry.get_texture_view(RES_SSAO_OUT) {
41            Some(v) => v,
42            None => return,
43        };
44
45        // Standard post-processing full-screen pass to evaluate occlusion factors
46        let mut _pass = ctx.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
47            label: Some("SSAO Render Pass"),
48            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
49                view: &ssao_view,
50                resolve_target: None,
51                ops: wgpu::Operations {
52                    load: wgpu::LoadOp::Clear(wgpu::Color::WHITE),
53                    store: wgpu::StoreOp::Store,
54                },
55                depth_slice: None,
56            })],
57            depth_stencil_attachment: None,
58            timestamp_writes: None,
59            occlusion_query_set: None,
60            multiview_mask: None,
61        });
62
63        // Run full-screen triangle shader sampling normal and depth with randomized hemisphere kernel
64    }
65}