nightshade/ecs/camera/components/
viewport_shading.rs1use crate::ecs::primitives::CameraCullingMask;
29use crate::render::config::{
30 Atmosphere, ColorGrading, DebugDraw, DepthOfField, Fog, RenderSettings,
31};
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
34pub enum ShadingMode {
35 Wireframe,
36 Solid,
37 Flat,
38 #[default]
39 Rendered,
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
43pub struct ViewportShading {
44 pub mode: ShadingMode,
45 pub show_overlays: bool,
46}
47
48impl Default for ViewportShading {
49 fn default() -> Self {
50 Self {
51 mode: ShadingMode::Rendered,
52 show_overlays: true,
53 }
54 }
55}
56
57use crate::render::config::{EffectiveShading, FLAT_SHADING_COLOR, WIREFRAME_SENTINEL_COLOR};
58
59pub fn effective_shading_from_graphics(
60 render: &RenderSettings,
61 debug: &DebugDraw,
62) -> EffectiveShading {
63 EffectiveShading {
64 unlit_mode: render.unlit_mode,
65 bloom_enabled: render.bloom_enabled,
66 ssao_enabled: render.ssao_enabled,
67 ssgi_enabled: render.ssgi_enabled,
68 ssr_enabled: render.ssr_enabled,
69 show_normals: debug.show_normals,
70 show_bounding_volumes: debug.show_bounding_volumes,
71 show_wireframe: false,
72 selection_outline_enabled: debug.selection_outline_enabled,
73 flat_shading_color: None,
74 shadow_depth_enabled: true,
75 lines_enabled: debug.show_normals || debug.show_bounding_volumes,
76 color_grading: render.color_grading,
77 depth_of_field: render.depth_of_field,
78 bloom_intensity: render.bloom_intensity,
79 bloom_threshold: render.bloom_threshold,
80 bloom_knee: render.bloom_knee,
81 bloom_filter_radius: render.bloom_filter_radius,
82 ssao_radius: render.ssao_radius,
83 ssao_bias: render.ssao_bias,
84 ssao_intensity: render.ssao_intensity,
85 ssao_sample_count: render.ssao_sample_count,
86 ssao_visualization: debug.ssao_visualization,
87 ssao_blur_depth_threshold: render.ssao_blur_depth_threshold,
88 ssao_blur_normal_power: render.ssao_blur_normal_power,
89 ssgi_radius: render.ssgi_radius,
90 ssgi_intensity: render.ssgi_intensity,
91 ssgi_max_steps: render.ssgi_max_steps,
92 ssr_max_steps: render.ssr_max_steps,
93 ssr_thickness: render.ssr_thickness,
94 ssr_max_distance: render.ssr_max_distance,
95 ssr_stride: render.ssr_stride,
96 ssr_fade_start: render.ssr_fade_start,
97 ssr_fade_end: render.ssr_fade_end,
98 ssr_intensity: render.ssr_intensity,
99 ambient_light: render.ambient_light,
100 culling_mask: !0,
101 fog: render.fog,
102 atmosphere: render.atmosphere,
103 }
104}
105
106pub fn effective_shading_for_camera(
107 render: &RenderSettings,
108 debug: &DebugDraw,
109 shading: &ViewportShading,
110 post_process: Option<&CameraPostProcess>,
111 culling_mask: Option<&CameraCullingMask>,
112 environment: Option<&CameraEnvironment>,
113) -> EffectiveShading {
114 let mut effective = effective_shading_from_graphics(render, debug);
115 if let Some(mask) = culling_mask {
116 effective.culling_mask = mask.0;
117 }
118 if let Some(env) = environment {
119 if let Some(atmosphere) = env.atmosphere {
120 effective.atmosphere = atmosphere;
121 }
122 effective.fog = match env.fog {
123 FogOverride::Inherit => effective.fog,
124 FogOverride::Disabled => None,
125 FogOverride::Override(fog) => Some(fog),
126 };
127 }
128 if let Some(overrides) = post_process {
129 if let Some(cg) = overrides.color_grading {
130 effective.color_grading = cg;
131 }
132 if let Some(dof) = overrides.depth_of_field {
133 effective.depth_of_field = dof;
134 }
135 if let Some(value) = overrides.bloom_intensity {
136 effective.bloom_intensity = value;
137 }
138 if let Some(value) = overrides.bloom_threshold {
139 effective.bloom_threshold = value;
140 }
141 if let Some(value) = overrides.bloom_knee {
142 effective.bloom_knee = value;
143 }
144 if let Some(value) = overrides.bloom_filter_radius {
145 effective.bloom_filter_radius = value;
146 }
147 if let Some(value) = overrides.ssao_intensity {
148 effective.ssao_intensity = value;
149 }
150 if let Some(value) = overrides.ssao_radius {
151 effective.ssao_radius = value;
152 }
153 if let Some(value) = overrides.ssgi_intensity {
154 effective.ssgi_intensity = value;
155 }
156 if let Some(value) = overrides.ssr_intensity {
157 effective.ssr_intensity = value;
158 }
159 if let Some(value) = overrides.ambient_light {
160 effective.ambient_light = value;
161 }
162 }
163 match shading.mode {
164 ShadingMode::Rendered => {}
165 ShadingMode::Solid => {
166 effective.unlit_mode = true;
167 effective.bloom_enabled = false;
168 effective.ssao_enabled = false;
169 effective.ssgi_enabled = false;
170 effective.ssr_enabled = false;
171 effective.shadow_depth_enabled = false;
172 }
173 ShadingMode::Flat => {
174 effective.bloom_enabled = false;
175 effective.ssao_enabled = false;
176 effective.ssgi_enabled = false;
177 effective.ssr_enabled = false;
178 effective.flat_shading_color = Some(FLAT_SHADING_COLOR);
179 }
180 ShadingMode::Wireframe => {
181 effective.unlit_mode = true;
182 effective.bloom_enabled = false;
183 effective.ssao_enabled = false;
184 effective.ssgi_enabled = false;
185 effective.ssr_enabled = false;
186 effective.shadow_depth_enabled = false;
187 effective.flat_shading_color = Some(WIREFRAME_SENTINEL_COLOR);
188 effective.show_wireframe = true;
189 }
190 }
191 if !shading.show_overlays {
192 effective.show_normals = false;
193 effective.show_bounding_volumes = false;
194 effective.selection_outline_enabled = false;
195 }
196 effective.lines_enabled =
197 effective.show_normals || effective.show_bounding_volumes || effective.show_wireframe;
198 effective
199}
200
201#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
209pub struct ConstrainedAspect(pub f32);
210
211impl Default for ConstrainedAspect {
212 fn default() -> Self {
213 Self(16.0 / 9.0)
214 }
215}
216
217#[derive(Debug, Clone, Copy, Default, PartialEq, serde::Serialize, serde::Deserialize)]
222pub struct CameraEnvironment {
223 pub atmosphere: Option<Atmosphere>,
224 pub fog: FogOverride,
225}
226
227#[derive(Debug, Clone, Copy, Default, PartialEq, serde::Serialize, serde::Deserialize)]
228pub enum FogOverride {
229 #[default]
230 Inherit,
231 Disabled,
232 Override(Fog),
233}
234
235#[derive(Debug, Clone, Copy, Default, PartialEq, serde::Serialize, serde::Deserialize)]
241pub struct CameraPostProcess {
242 pub color_grading: Option<ColorGrading>,
243 pub depth_of_field: Option<DepthOfField>,
244 pub bloom_intensity: Option<f32>,
245 pub bloom_threshold: Option<f32>,
246 pub bloom_knee: Option<f32>,
247 pub bloom_filter_radius: Option<f32>,
248 pub ssao_intensity: Option<f32>,
249 pub ssao_radius: Option<f32>,
250 pub ssgi_intensity: Option<f32>,
251 pub ssr_intensity: Option<f32>,
252 pub ambient_light: Option<[f32; 4]>,
253}