Skip to main content

molgfx_render/engine/
depth_cue.rs

1//! Explicit view-space depth-cue settings.
2
3use super::profile_numeric::{finite_clamp, lerp, unit};
4use serde::{Deserialize, Serialize};
5
6/// Distance-based atmospheric cue applied in view space after lighting.
7#[derive(Clone, Copy, PartialEq, Debug, Default, Serialize, Deserialize)]
8pub struct DepthCue {
9    /// View-space distance where the cue begins.
10    pub near_distance: f32,
11    /// View-space distance where the cue reaches full strength.
12    pub far_distance: f32,
13    /// Blend toward the resolved backdrop, in `[0, 1]`.
14    pub strength: f32,
15}
16
17impl DepthCue {
18    pub(super) fn sanitize(self) -> Self {
19        let near_distance = finite_clamp(self.near_distance, 0.0, 999_999.0, 0.0);
20        let minimum_far = near_distance + near_distance.mul_add(1.0e-6, 1.0e-3);
21        let far_distance = finite_clamp(
22            self.far_distance,
23            minimum_far,
24            1_000_000.0,
25            minimum_far.max(1.0),
26        );
27        Self {
28            near_distance,
29            far_distance,
30            strength: unit(self.strength),
31        }
32    }
33
34    pub(super) fn blend(self, other: Self, weight: f32) -> Self {
35        let weight = unit(weight);
36        Self {
37            near_distance: lerp(self.near_distance, other.near_distance, weight),
38            far_distance: lerp(self.far_distance, other.far_distance, weight),
39            strength: lerp(self.strength, other.strength, weight),
40        }
41        .sanitize()
42    }
43
44    pub(crate) fn packed(self) -> [f32; 4] {
45        let cue = self.sanitize();
46        [cue.near_distance, cue.far_distance, cue.strength, 0.0]
47    }
48}