three_d/renderer/effect/
fog.rs

1use crate::renderer::*;
2
3///
4/// An effect that simulates fog, ie. the area where it is applied gets hazy when objects are far away.
5///
6#[derive(Clone, Debug)]
7pub struct FogEffect {
8    /// The color of the fog.
9    pub color: Srgba,
10    /// The density of the fog.
11    pub density: f32,
12    /// Determines the variation on the density as a function of time.
13    pub animation: f32,
14    /// The time used for the animation.
15    pub time: f32,
16}
17
18impl Default for FogEffect {
19    fn default() -> Self {
20        Self {
21            color: Srgba::WHITE,
22            density: 0.2,
23            animation: 1.0,
24            time: 0.0,
25        }
26    }
27}
28
29impl Effect for FogEffect {
30    fn fragment_shader_source(
31        &self,
32        _lights: &[&dyn Light],
33        color_texture: Option<ColorTexture>,
34        depth_texture: Option<DepthTexture>,
35    ) -> String {
36        format!(
37            "{}\n{}\n{}\n{}\n{}\n{}",
38            include_str!("../../core/shared.frag"),
39            color_texture
40                .expect("Must supply a depth texture to apply a fog effect")
41                .fragment_shader_source(),
42            depth_texture
43                .expect("Must supply a depth texture to apply a fog effect")
44                .fragment_shader_source(),
45            ToneMapping::fragment_shader_source(),
46            ColorMapping::fragment_shader_source(),
47            include_str!("shaders/fog_effect.frag")
48        )
49    }
50
51    fn id(
52        &self,
53        color_texture: Option<ColorTexture>,
54        depth_texture: Option<DepthTexture>,
55    ) -> EffectMaterialId {
56        EffectMaterialId::FogEffect(
57            color_texture.expect("Must supply a color texture to apply a fog effect"),
58            depth_texture.expect("Must supply a depth texture to apply a fog effect"),
59        )
60    }
61
62    fn use_uniforms(
63        &self,
64        program: &Program,
65        viewer: &dyn Viewer,
66        _lights: &[&dyn Light],
67        color_texture: Option<ColorTexture>,
68        depth_texture: Option<DepthTexture>,
69    ) {
70        viewer.tone_mapping().use_uniforms(program);
71        viewer.color_mapping().use_uniforms(program);
72        color_texture
73            .expect("Must supply a color texture to apply a fog effect")
74            .use_uniforms(program);
75        depth_texture
76            .expect("Must supply a depth texture to apply a fog effect")
77            .use_uniforms(program);
78        program.use_uniform(
79            "viewProjectionInverse",
80            (viewer.projection() * viewer.view()).invert().unwrap(),
81        );
82        program.use_uniform("fogColor", Vec4::from(self.color));
83        program.use_uniform("fogDensity", self.density);
84        program.use_uniform("animation", self.animation);
85        program.use_uniform("time", 0.001 * self.time);
86        program.use_uniform("eyePosition", viewer.position());
87    }
88
89    fn render_states(&self) -> RenderStates {
90        RenderStates {
91            depth_test: DepthTest::Always,
92            cull: Cull::Back,
93            ..Default::default()
94        }
95    }
96}