Skip to main content

three_d/core/
render_states.rs

1//!
2//! Definitions of the input state needed for any draw call.
3//!
4
5///
6/// A set of render specific states that has to be specified at each render call.
7///
8#[derive(Debug, Copy, Clone, Default)]
9pub struct RenderStates {
10    ///
11    /// Defines which channels (red, green, blue, alpha and depth) to write to in a render call.
12    ///
13    pub write_mask: WriteMask,
14
15    ///
16    /// Defines the depth test in a render call.
17    /// The depth test determines whether or not a fragment from the current render call should be discarded
18    /// when comparing its depth with the depth of the current fragment.
19    ///
20    pub depth_test: DepthTest,
21
22    ///
23    /// Defines which type of blending to use for a render call.
24    /// Blending allows combining each color channel of a render call with the color already in the
25    /// color channels of the render target.
26    /// This is usually used to simulate transparency.
27    ///
28    pub blend: Blend,
29
30    ///
31    /// Defines whether the triangles that are backfacing, frontfacing or both should be skipped in a render call.
32    ///
33    pub cull: Cull,
34}
35
36///
37/// Defines whether the triangles that are backfacing, frontfacing, both or none should be rendered in a render call.
38///
39#[derive(Debug, Copy, Clone, PartialEq, Default)]
40pub enum Cull {
41    /// Render both front- and backfacing triangles.
42    #[default]
43    None,
44    /// Render only frontfacing triangles.
45    Back,
46    /// Render only backfacing triangles.
47    Front,
48    /// Render nothing.
49    FrontAndBack,
50}
51
52///
53/// Determines whether or not a fragment/pixel from the current render call should be discarded
54/// when comparing its depth with the depth of the current fragment/pixel.
55///
56/// **Note:** Depth test is disabled if the render call is not writing to a depth texture.
57///
58#[allow(missing_docs)]
59#[derive(Debug, Copy, Clone, PartialEq, Default)]
60pub enum DepthTest {
61    Never,
62    #[default]
63    Less,
64    Equal,
65    LessOrEqual,
66    Greater,
67    NotEqual,
68    GreaterOrEqual,
69    Always,
70}
71
72///
73/// Defines which channels (red, green, blue, alpha and depth) to write to in a render call.
74///
75#[allow(missing_docs)]
76#[derive(Debug, Copy, Clone, PartialEq)]
77pub struct WriteMask {
78    pub red: bool,
79    pub green: bool,
80    pub blue: bool,
81    pub alpha: bool,
82    pub depth: bool,
83}
84
85impl WriteMask {
86    ///
87    /// Writes to all channels (red, green, blue, alpha and depth).
88    ///
89    pub const COLOR_AND_DEPTH: Self = Self {
90        red: true,
91        green: true,
92        blue: true,
93        alpha: true,
94        depth: true,
95    };
96
97    ///
98    /// Writes to all color channels (red, green, blue and alpha).
99    ///
100    pub const COLOR: Self = Self {
101        red: true,
102        green: true,
103        blue: true,
104        alpha: true,
105        depth: false,
106    };
107
108    ///
109    /// Writes to the depth channel only.
110    ///
111    pub const DEPTH: Self = Self {
112        red: false,
113        green: false,
114        blue: false,
115        alpha: false,
116        depth: true,
117    };
118
119    ///
120    /// Do not write to any channels.
121    ///
122    pub const NONE: Self = Self {
123        red: false,
124        green: false,
125        blue: false,
126        alpha: false,
127        depth: false,
128    };
129}
130
131impl Default for WriteMask {
132    fn default() -> Self {
133        Self::COLOR_AND_DEPTH
134    }
135}
136
137///
138/// Defines which type of blending to use for a render call.
139/// Blending allows combining each color channel of a render call with the color already in the
140/// color channels of the render target.
141/// This is usually used to simulate transparency.
142///
143#[allow(missing_docs)]
144#[derive(Debug, Copy, Clone, PartialEq, Default)]
145pub enum Blend {
146    Enabled {
147        source_rgb_multiplier: BlendMultiplierType,
148        source_alpha_multiplier: BlendMultiplierType,
149        destination_rgb_multiplier: BlendMultiplierType,
150        destination_alpha_multiplier: BlendMultiplierType,
151        rgb_equation: BlendEquationType,
152        alpha_equation: BlendEquationType,
153    },
154    #[default]
155    Disabled,
156}
157
158impl Blend {
159    ///
160    /// Standard OpenGL transparency blending parameters which, for the usual case of being able to see through objects, does not work on web.
161    /// In that case, use [Blend::TRANSPARENCY] instead which works the same way on desktop and web.
162    ///
163    pub const STANDARD_TRANSPARENCY: Self = Self::Enabled {
164        source_rgb_multiplier: BlendMultiplierType::SrcAlpha,
165        source_alpha_multiplier: BlendMultiplierType::One,
166        destination_rgb_multiplier: BlendMultiplierType::OneMinusSrcAlpha,
167        destination_alpha_multiplier: BlendMultiplierType::Zero,
168        rgb_equation: BlendEquationType::Add,
169        alpha_equation: BlendEquationType::Add,
170    };
171
172    ///
173    /// Transparency blending parameters that works on both desktop and web. For the standard OpenGL parameters, see [Blend::STANDARD_TRANSPARENCY].
174    ///
175    pub const TRANSPARENCY: Self = Self::Enabled {
176        source_rgb_multiplier: BlendMultiplierType::SrcAlpha,
177        source_alpha_multiplier: BlendMultiplierType::Zero,
178        destination_rgb_multiplier: BlendMultiplierType::OneMinusSrcAlpha,
179        destination_alpha_multiplier: BlendMultiplierType::One,
180        rgb_equation: BlendEquationType::Add,
181        alpha_equation: BlendEquationType::Add,
182    };
183
184    ///
185    /// Adds the color of the render target with the output color of the render call.
186    ///
187    pub const ADD: Self = Self::Enabled {
188        source_rgb_multiplier: BlendMultiplierType::One,
189        source_alpha_multiplier: BlendMultiplierType::One,
190        destination_rgb_multiplier: BlendMultiplierType::One,
191        destination_alpha_multiplier: BlendMultiplierType::One,
192        rgb_equation: BlendEquationType::Add,
193        alpha_equation: BlendEquationType::Add,
194    };
195}
196
197///
198/// Value multiplied with the source or target color or alpha value in [Blend].
199///
200#[allow(missing_docs)]
201#[derive(Debug, Copy, Clone, PartialEq)]
202pub enum BlendMultiplierType {
203    Zero,
204    One,
205    SrcColor,
206    OneMinusSrcColor,
207    DstColor,
208    OneMinusDstColor,
209    SrcAlpha,
210    OneMinusSrcAlpha,
211    DstAlpha,
212    OneMinusDstAlpha,
213    SrcAlphaSaturate,
214}
215
216///
217/// How the source and target color or alpha value are combined in [Blend].
218///
219#[allow(missing_docs)]
220#[derive(Debug, Copy, Clone, PartialEq)]
221pub enum BlendEquationType {
222    Add,
223    Subtract,
224    ReverseSubtract,
225    Max,
226    Min,
227}