Skip to main content

fyrox_impl/renderer/
settings.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21use crate::core::{reflect::prelude::*, type_traits::prelude::*};
22use serde::{Deserialize, Serialize};
23use strum_macros::{AsRefStr, EnumString, VariantNames};
24
25/// Bloom effect settings.
26#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, Reflect)]
27pub struct BloomSettings {
28    /// Whether to use bloom effect.
29    pub use_bloom: bool,
30
31    /// A threshold value for luminance of a pixel to be considered "very bright". Only pixels
32    /// that passed this check (>=) will be included in the bloom render target and will have the glow
33    /// effect.
34    pub threshold: f32,
35}
36
37impl Default for BloomSettings {
38    fn default() -> Self {
39        Self {
40            use_bloom: true,
41            threshold: 1.01,
42        }
43    }
44}
45
46/// Calculation method of a frame luminance for HDR rendering pipeline.
47#[derive(
48    Debug,
49    Copy,
50    Clone,
51    PartialEq,
52    Default,
53    Serialize,
54    Deserialize,
55    Reflect,
56    AsRefStr,
57    EnumString,
58    VariantNames,
59    TypeUuidProvider,
60)]
61#[type_uuid(id = "b1994c1c-bc2f-497c-a05d-062a02b69ff1")]
62pub enum LuminanceCalculationMethod {
63    /// Simplest and fastest luminance calculation method based on average of luminance of all
64    /// pixels of the frame.
65    #[default]
66    DownSampling,
67
68    /// More flexible, yet slower, luminance calculation method.
69    Histogram,
70}
71
72/// Settings of high dynamic range rendering pipeline.
73#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, Reflect)]
74pub struct HdrSettings {
75    /// Whether the HDR pipeline enabled or not.
76    pub use_hdr: bool,
77
78    /// Calculation method of a frame luminance for HDR rendering pipeline.
79    pub luminance_calculation_method: LuminanceCalculationMethod,
80
81    /// Bloom effect settings.
82    #[serde(default)]
83    pub bloom_settings: BloomSettings,
84}
85
86impl Default for HdrSettings {
87    fn default() -> Self {
88        Self {
89            use_hdr: true,
90            luminance_calculation_method: LuminanceCalculationMethod::DownSampling,
91            bloom_settings: BloomSettings::default(),
92        }
93    }
94}
95
96/// Quality settings allows you to find optimal balance between performance and
97/// graphics quality.
98#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, Reflect)]
99pub struct QualitySettings {
100    /// Point shadows
101    /// Size of cube map face of shadow map texture in pixels.
102    pub point_shadow_map_size: usize,
103    /// Use or not percentage close filtering (smoothing) for point shadows.
104    pub point_soft_shadows: bool,
105    /// Point shadows enabled or not.
106    pub point_shadows_enabled: bool,
107    /// Maximum distance from camera to draw shadows.
108    pub point_shadows_distance: f32,
109    /// Point shadow map precision. Allows you to select compromise between
110    /// quality and performance.
111    pub point_shadow_map_precision: ShadowMapPrecision,
112    /// Point shadows fade out range.
113    /// Specifies the distance from the camera at which point shadows start to fade out.
114    /// Shadows beyond this distance will gradually become less visible.
115    pub point_shadows_fade_out_range: f32,
116
117    /// Spot shadows
118    /// Size of square shadow map texture in pixels
119    pub spot_shadow_map_size: usize,
120    /// Use or not percentage close filtering (smoothing) for spot shadows.
121    pub spot_soft_shadows: bool,
122    /// Spot shadows enabled or not.
123    pub spot_shadows_enabled: bool,
124    /// Maximum distance from camera to draw shadows.
125    pub spot_shadows_distance: f32,
126    /// Spot shadow map precision. Allows you to select compromise between
127    /// quality and performance.
128    pub spot_shadow_map_precision: ShadowMapPrecision,
129    /// Specifies the distance from the camera at which spot shadows start to fade out.
130    /// Shadows beyond this distance will gradually become less visible.
131    pub spot_shadows_fade_out_range: f32,
132
133    /// Cascaded-shadow maps settings.
134    pub csm_settings: CsmSettings,
135
136    /// Whether to use screen space ambient occlusion or not.
137    pub use_ssao: bool,
138    /// Radius of sampling hemisphere used in SSAO, it defines much ambient
139    /// occlusion will be in your scene.
140    pub ssao_radius: f32,
141
142    /// Global switch to enable or disable light scattering. Each light can have
143    /// its own scatter switch, but this one is able to globally disable scatter.
144    pub light_scatter_enabled: bool,
145
146    /// Whether to use Fast Approximate AntiAliasing or not.
147    pub fxaa: bool,
148
149    /// Whether to use Parallax Mapping or not.
150    pub use_parallax_mapping: bool,
151
152    /// Whether to use occlusion culling for geometry or not. Warning: this is experimental feature
153    /// that may have bugs and unstable behavior. Disabled by default.
154    #[serde(default)]
155    pub use_occlusion_culling: bool,
156
157    /// Whether to use occlusion culling for light sources or not. Warning: this is experimental
158    /// feature that may have bugs and unstable behavior. Disabled by default.
159    #[serde(default)]
160    pub use_light_occlusion_culling: bool,
161
162    /// HDR pipeline settings.
163    #[serde(default)]
164    pub hdr_settings: HdrSettings,
165}
166
167impl Default for QualitySettings {
168    fn default() -> Self {
169        Self::high()
170    }
171}
172
173impl QualitySettings {
174    /// Highest possible graphics quality. Requires very powerful GPU.
175    pub fn ultra() -> Self {
176        Self {
177            point_shadow_map_size: 2048,
178            point_shadows_distance: 20.0,
179            point_shadows_enabled: true,
180            point_soft_shadows: true,
181            point_shadows_fade_out_range: 1.0,
182
183            spot_shadow_map_size: 2048,
184            spot_shadows_distance: 20.0,
185            spot_shadows_enabled: true,
186            spot_soft_shadows: true,
187            spot_shadows_fade_out_range: 1.0,
188
189            use_ssao: true,
190            ssao_radius: 0.5,
191
192            light_scatter_enabled: true,
193
194            point_shadow_map_precision: ShadowMapPrecision::Full,
195            spot_shadow_map_precision: ShadowMapPrecision::Full,
196
197            fxaa: true,
198
199            hdr_settings: Default::default(),
200
201            use_parallax_mapping: true,
202
203            csm_settings: Default::default(),
204
205            use_occlusion_culling: false,
206            use_light_occlusion_culling: false,
207        }
208    }
209
210    /// High graphics quality, includes all graphical effects. Requires powerful GPU.
211    pub fn high() -> Self {
212        Self {
213            point_shadow_map_size: 1024,
214            point_shadows_distance: 15.0,
215            point_shadows_enabled: true,
216            point_soft_shadows: true,
217            point_shadows_fade_out_range: 1.0,
218
219            spot_shadow_map_size: 1024,
220            spot_shadows_distance: 15.0,
221            spot_shadows_enabled: true,
222            spot_soft_shadows: true,
223            spot_shadows_fade_out_range: 1.0,
224
225            use_ssao: true,
226            ssao_radius: 0.5,
227
228            light_scatter_enabled: true,
229
230            point_shadow_map_precision: ShadowMapPrecision::Full,
231            spot_shadow_map_precision: ShadowMapPrecision::Full,
232
233            fxaa: true,
234
235            hdr_settings: Default::default(),
236
237            use_parallax_mapping: true,
238
239            csm_settings: CsmSettings {
240                enabled: true,
241                size: 2048,
242                precision: ShadowMapPrecision::Full,
243                pcf: true,
244            },
245
246            use_occlusion_culling: false,
247            use_light_occlusion_culling: false,
248        }
249    }
250
251    /// Medium graphics quality, some of effects are disabled, shadows will have sharp edges.
252    pub fn medium() -> Self {
253        Self {
254            point_shadow_map_size: 512,
255            point_shadows_distance: 5.0,
256            point_shadows_enabled: true,
257            point_soft_shadows: false,
258            point_shadows_fade_out_range: 1.0,
259
260            spot_shadow_map_size: 512,
261            spot_shadows_distance: 5.0,
262            spot_shadows_enabled: true,
263            spot_soft_shadows: false,
264            spot_shadows_fade_out_range: 1.0,
265
266            use_ssao: true,
267            ssao_radius: 0.5,
268
269            light_scatter_enabled: false,
270
271            point_shadow_map_precision: ShadowMapPrecision::Half,
272            spot_shadow_map_precision: ShadowMapPrecision::Half,
273
274            fxaa: true,
275
276            hdr_settings: Default::default(),
277
278            use_parallax_mapping: false,
279
280            csm_settings: CsmSettings {
281                enabled: true,
282                size: 512,
283                precision: ShadowMapPrecision::Full,
284                pcf: false,
285            },
286
287            use_occlusion_culling: false,
288            use_light_occlusion_culling: false,
289        }
290    }
291
292    /// Lowest graphics quality, all effects are disabled.
293    pub fn low() -> Self {
294        Self {
295            point_shadow_map_size: 1, // Zero is unsupported.
296            point_shadows_distance: 0.0,
297            point_shadows_enabled: false,
298            point_soft_shadows: false,
299            point_shadows_fade_out_range: 1.0,
300
301            spot_shadow_map_size: 1,
302            spot_shadows_distance: 0.0,
303            spot_shadows_enabled: false,
304            spot_soft_shadows: false,
305            spot_shadows_fade_out_range: 1.0,
306
307            use_ssao: false,
308            ssao_radius: 0.5,
309
310            light_scatter_enabled: false,
311
312            point_shadow_map_precision: ShadowMapPrecision::Half,
313            spot_shadow_map_precision: ShadowMapPrecision::Half,
314
315            fxaa: false,
316
317            hdr_settings: HdrSettings {
318                bloom_settings: BloomSettings {
319                    use_bloom: false,
320                    ..Default::default()
321                },
322                ..Default::default()
323            },
324
325            use_parallax_mapping: false,
326
327            csm_settings: CsmSettings {
328                enabled: true,
329                size: 512,
330                precision: ShadowMapPrecision::Half,
331                pcf: false,
332            },
333
334            use_occlusion_culling: false,
335            use_light_occlusion_culling: false,
336        }
337    }
338}
339
340/// Cascaded-shadow maps settings.
341#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, Reflect, Eq)]
342pub struct CsmSettings {
343    /// Whether cascaded shadow maps enabled or not.
344    pub enabled: bool,
345
346    /// Size of texture for each cascade.
347    pub size: usize,
348
349    /// Bit-wise precision for each cascade, the lower precision the better performance is,
350    /// but the more artifacts may occur.
351    pub precision: ShadowMapPrecision,
352
353    /// Whether to use Percentage-Closer Filtering or not.
354    pub pcf: bool,
355}
356
357impl Default for CsmSettings {
358    fn default() -> Self {
359        Self {
360            enabled: true,
361            size: 2048,
362            precision: ShadowMapPrecision::Full,
363            pcf: true,
364        }
365    }
366}
367
368/// Shadow map precision allows you to select compromise between quality and performance.
369#[derive(
370    Copy,
371    Clone,
372    Hash,
373    PartialOrd,
374    PartialEq,
375    Eq,
376    Ord,
377    Debug,
378    Serialize,
379    Deserialize,
380    Reflect,
381    AsRefStr,
382    EnumString,
383    VariantNames,
384    TypeUuidProvider,
385)]
386#[type_uuid(id = "f9b2755b-248e-46ba-bcab-473eac1acdb8")]
387pub enum ShadowMapPrecision {
388    /// Shadow map will use 2 times less memory by switching to 16bit pixel format,
389    /// but "shadow acne" may occur.
390    Half,
391    /// Shadow map will use 32bit pixel format. This option gives highest quality,
392    /// but could be less performant than `Half`.
393    Full,
394}