three_d/renderer/effect/
full_screen.rs

1use crate::renderer::*;
2
3///
4/// Renders a full screen quad with the content of the color and/or depth textures.
5/// The difference from [CopyEffect] is that this effect also applies any tone and color mapping specified in the [Viewer].
6///
7#[derive(Clone, Debug, Default)]
8pub struct ScreenEffect {
9    /// Defines which channels (red, green, blue, alpha and depth) to render into.
10    pub write_mask: WriteMask,
11    /// Defines which type of blending to use when writing the color to the render target.
12    pub blend: Blend,
13}
14
15impl Effect for ScreenEffect {
16    fn fragment_shader_source(
17        &self,
18        _lights: &[&dyn crate::Light],
19        color_texture: Option<ColorTexture>,
20        depth_texture: Option<DepthTexture>,
21    ) -> String {
22        format!(
23            "{}{}{}{}
24
25            in vec2 uvs;
26            layout (location = 0) out vec4 outColor;
27
28            void main()
29            {{
30                {}
31                {}
32            }}
33
34        ",
35            color_texture
36                .map(|t| t.fragment_shader_source())
37                .unwrap_or("".to_string()),
38            depth_texture
39                .map(|t| t.fragment_shader_source())
40                .unwrap_or("".to_string()),
41            ToneMapping::fragment_shader_source(),
42            ColorMapping::fragment_shader_source(),
43            color_texture
44                .map(|_| "
45                    outColor = sample_color(uvs);
46                    outColor.rgb = tone_mapping(outColor.rgb);
47                    outColor.rgb = color_mapping(outColor.rgb);"
48                    .to_string())
49                .unwrap_or("".to_string()),
50            depth_texture
51                .map(|_| "gl_FragDepth = sample_depth(uvs);".to_string())
52                .unwrap_or("".to_string()),
53        )
54    }
55
56    fn id(
57        &self,
58        color_texture: Option<ColorTexture>,
59        depth_texture: Option<DepthTexture>,
60    ) -> EffectMaterialId {
61        EffectMaterialId::ScreenEffect(color_texture, depth_texture)
62    }
63
64    fn use_uniforms(
65        &self,
66        program: &Program,
67        viewer: &dyn Viewer,
68        _lights: &[&dyn crate::Light],
69        color_texture: Option<ColorTexture>,
70        depth_texture: Option<DepthTexture>,
71    ) {
72        if let Some(color_texture) = color_texture {
73            viewer.tone_mapping().use_uniforms(program);
74            viewer.color_mapping().use_uniforms(program);
75            color_texture.use_uniforms(program);
76        }
77        if let Some(depth_texture) = depth_texture {
78            depth_texture.use_uniforms(program);
79        }
80    }
81
82    fn render_states(&self) -> RenderStates {
83        RenderStates {
84            depth_test: DepthTest::Always,
85            cull: Cull::Back,
86            write_mask: self.write_mask,
87            blend: self.blend,
88        }
89    }
90}