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}