concinnity_render/render_graph/
view_mask.rs1use super::frame::FrameGraphInputs;
10use concinnity_core::gfx::view_modes::{ShowFlags, ViewMode};
11
12pub fn apply_view(inputs: &FrameGraphInputs, mode: ViewMode, show: ShowFlags) -> FrameGraphInputs {
17 let mut out = *inputs;
18 out.composite_reads_ao = false;
19 if !show.contains(ShowFlags::SHADOWS) {
20 out.shadow_enabled = false;
21 out.shadowed_spot_count = 0;
22 }
23 if !show.contains(ShowFlags::FOG) {
24 out.fog_enabled = false;
25 }
26 if !show.contains(ShowFlags::BLOOM) {
27 out.bloom_enabled = false;
28 }
29 if !show.contains(ShowFlags::SSGI) {
30 out.ssgi_enabled = false;
31 }
32 if !show.contains(ShowFlags::SSR) {
33 out.ssr_enabled = false;
34 out.rt_reflections_enabled = false;
35 }
36 if !show.contains(ShowFlags::LINES) {
37 out.lines_enabled = false;
38 }
39 if mode.is_flat() {
40 out.ssao_enabled = false;
41 out.ssr_enabled = false;
42 out.rt_reflections_enabled = false;
43 out.ssgi_enabled = false;
44 out.bloom_enabled = false;
45 out.fog_enabled = false;
46 out.decals_enabled = false;
47 out.taa_enabled = false;
48 out.upscale_enabled = false;
49 out.velocity_enabled = false;
50 out.ssr_prepass_enabled = false;
51 }
52 if mode.is_gbuffer_channel() {
53 out.ssr_prepass_enabled = true;
55 out.bloom_enabled = false;
59 out.composite_reads_ao = mode == ViewMode::Occlusion && out.ssao_enabled;
60 }
61 out
62}
63
64#[cfg(test)]
65mod tests {
66 use super::super::frame::build_frame_graph;
67 use super::super::passes::PassId;
68 use super::*;
69
70 fn everything_on() -> FrameGraphInputs {
71 FrameGraphInputs {
72 shadow_enabled: true,
73 auto_exposure_enabled: true,
74 bloom_enabled: true,
75 velocity_enabled: true,
76 taa_enabled: true,
77 ssr_enabled: true,
78 fog_enabled: true,
79 decals_enabled: true,
80 ssr_prepass_enabled: true,
81 ssao_enabled: true,
82 transparent_enabled: true,
83 lines_enabled: true,
84 ssgi_enabled: true,
85 shadowed_spot_count: 2,
86 ..FrameGraphInputs::all_off()
87 }
88 }
89
90 #[test]
91 fn lit_with_all_flags_is_identity() {
92 let inputs = everything_on();
93 assert_eq!(apply_view(&inputs, ViewMode::Lit, ShowFlags::all()), inputs);
94 }
95
96 #[test]
97 fn each_flag_masks_its_passes() {
98 let inputs = everything_on();
99 let m = |f| apply_view(&inputs, ViewMode::Lit, ShowFlags::all().toggled(f));
100 let no_shadows = m(ShowFlags::SHADOWS);
101 assert!(!no_shadows.shadow_enabled);
102 assert_eq!(no_shadows.shadowed_spot_count, 0);
103 assert!(!m(ShowFlags::FOG).fog_enabled);
104 assert!(!m(ShowFlags::BLOOM).bloom_enabled);
105 assert!(!m(ShowFlags::SSGI).ssgi_enabled);
106 let no_ssr = m(ShowFlags::SSR);
107 assert!(!no_ssr.ssr_enabled && !no_ssr.rt_reflections_enabled);
108 assert!(!m(ShowFlags::LINES).lines_enabled);
109 }
110
111 #[test]
112 fn flat_modes_drop_the_surface_effect_stack() {
113 let inputs = everything_on();
114 for mode in [ViewMode::Unlit, ViewMode::Wireframe] {
115 let out = apply_view(&inputs, mode, ShowFlags::all());
116 assert!(!out.ssao_enabled && !out.ssr_enabled && !out.ssgi_enabled);
117 assert!(!out.bloom_enabled && !out.fog_enabled && !out.decals_enabled);
118 assert!(!out.taa_enabled && !out.upscale_enabled && !out.velocity_enabled);
119 assert!(out.shadow_enabled);
121 }
122 }
123
124 #[test]
125 fn occlusion_view_routes_ao_into_the_composite() {
126 let inputs = everything_on();
127 let out = apply_view(&inputs, ViewMode::Occlusion, ShowFlags::all());
128 assert!(out.composite_reads_ao && out.ssao_enabled);
129 assert!(!out.bloom_enabled, "bloom never overlaps the extended AO");
130 let mut no_ssao = everything_on();
132 no_ssao.ssao_enabled = false;
133 let out = apply_view(&no_ssao, ViewMode::Occlusion, ShowFlags::all());
134 assert!(!out.composite_reads_ao);
135 }
136
137 #[test]
138 fn channel_modes_keep_the_prepass_alive() {
139 let mut inputs = everything_on();
140 inputs.ssr_prepass_enabled = false;
141 for mode in [
142 ViewMode::Normals,
143 ViewMode::Roughness,
144 ViewMode::Occlusion,
145 ViewMode::Depth,
146 ] {
147 assert!(apply_view(&inputs, mode, ShowFlags::all()).ssr_prepass_enabled);
148 }
149 }
150
151 #[test]
152 fn masked_inputs_still_compile_and_ao_read_orders_composite_last() {
153 let inputs = everything_on();
154 for mode in ViewMode::ALL {
155 let out = apply_view(&inputs, mode, ShowFlags::all());
156 let graph = build_frame_graph(&out).expect("masked graph compiles");
157 assert_eq!(
158 graph.passes.last().map(|p| p.id),
159 Some(PassId::Composite),
160 "{mode:?}"
161 );
162 }
163 let out = apply_view(&inputs, ViewMode::Occlusion, ShowFlags::all());
166 let graph = build_frame_graph(&out).unwrap();
167 let composite_idx = graph.passes.len() - 1;
168 let ao = graph
169 .resources
170 .iter()
171 .find(|r| r.label == "ao_output")
172 .expect("ao_output present");
173 assert_eq!(ao.lifetime.last, composite_idx);
174 }
175}