fyrox_graphics/gpu_program.rs
1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21use crate::{
22 core::{
23 algebra::{Matrix2, Matrix3, Matrix4, Vector2, Vector3, Vector4},
24 reflect::prelude::*,
25 sstorage::ImmutableString,
26 type_traits::prelude::*,
27 visitor::prelude::*,
28 Downcast,
29 },
30 define_shared_wrapper,
31};
32use serde::{Deserialize, Serialize};
33use strum_macros::{AsRefStr, EnumString, VariantNames};
34
35pub trait GpuProgramTrait: Downcast {}
36
37/// A fallback value for the sampler.
38///
39/// # Notes
40///
41/// Sometimes you don't want to set a value to a sampler, or you even don't have the appropriate
42/// one. There is fallback value that helps you with such situations, it defines a values that
43/// will be fetched from a sampler when there is no texture.
44///
45/// For example, standard shader has a lot of samplers defined: diffuse, normal, height, emission,
46/// mask, metallic, roughness, etc. In some situations you may not have all the textures, you have
47/// only diffuse texture, to keep rendering correct, each other property has appropriate fallback
48/// value. Normal sampler - a normal vector pointing up (+Y), height - zero, emission - zero, etc.
49///
50/// Fallback value is also helpful to catch missing textures, you'll definitely know the texture is
51/// missing by very specific value in the fallback texture.
52#[derive(
53 Serialize,
54 Deserialize,
55 Default,
56 Debug,
57 PartialEq,
58 Clone,
59 Copy,
60 Visit,
61 Eq,
62 Reflect,
63 AsRefStr,
64 EnumString,
65 VariantNames,
66 TypeUuidProvider,
67)]
68#[type_uuid(id = "791b333c-eb3f-4279-97fe-cf2ba45c6d78")]
69pub enum SamplerFallback {
70 /// A 1x1px white texture.
71 #[default]
72 White,
73 /// A 1x1px texture with (0, 1, 0) vector.
74 Normal,
75 /// A 1x1px black texture.
76 Black,
77 /// A 1x1x1 volume texture with 1 black pixel.
78 Volume,
79}
80
81#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Clone, Copy, Visit, Eq, Reflect)]
82pub enum SamplerKind {
83 Sampler1D,
84 #[default]
85 Sampler2D,
86 Sampler3D,
87 SamplerCube,
88 USampler1D,
89 USampler2D,
90 USampler3D,
91 USamplerCube,
92}
93
94/// Shader property with default value.
95#[derive(Serialize, Deserialize, Debug, PartialEq, Reflect, Visit, Clone)]
96pub enum ShaderResourceKind {
97 /// A texture.
98 Texture {
99 /// Kind of the texture.
100 kind: SamplerKind,
101
102 /// Fallback value.
103 ///
104 /// Sometimes you don't want to set a value to a texture binding, or you even don't have the appropriate
105 /// one. There is fallback value that helps you with such situations, it defines a set of values that
106 /// will be fetched from a texture binding point when there is no actual texture.
107 ///
108 /// For example, standard shader has a lot of samplers defined: diffuse, normal, height, emission,
109 /// mask, metallic, roughness, etc. In some situations you may not have all the textures, you have
110 /// only diffuse texture, to keep rendering correct, each other property has appropriate fallback
111 /// value. Normal sampler - a normal vector pointing up (+Y), height - zero, emission - zero, etc.
112 ///
113 /// Fallback value is also helpful to catch missing textures, you'll definitely know the texture is
114 /// missing by very specific value in the fallback texture.
115 fallback: SamplerFallback,
116 },
117 PropertyGroup(Vec<ShaderProperty>),
118}
119
120#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Reflect, Visit)]
121pub enum ShaderPropertyKind {
122 /// Real number.
123 Float {
124 #[serde(default)]
125 value: f32,
126 },
127
128 /// Real number array.
129 FloatArray {
130 value: Vec<f32>,
131 /// `max_len` defines the maximum number of elements in the shader.
132 max_len: usize,
133 },
134
135 /// Integer number.
136 Int {
137 #[serde(default)]
138 value: i32,
139 },
140
141 /// Integer number array.
142 IntArray {
143 value: Vec<i32>,
144 /// `max_len` defines the maximum number of elements in the shader.
145 max_len: usize,
146 },
147
148 /// Natural number.
149 UInt {
150 #[serde(default)]
151 value: u32,
152 },
153
154 /// Natural number array.
155 UIntArray {
156 value: Vec<u32>,
157 /// `max_len` defines the maximum number of elements in the shader.
158 max_len: usize,
159 },
160
161 /// Boolean value.
162 Bool {
163 #[serde(default)]
164 value: bool,
165 },
166
167 /// Two-dimensional vector.
168 Vector2 {
169 #[serde(default)]
170 value: Vector2<f32>,
171 },
172
173 /// Two-dimensional vector array.
174 Vector2Array {
175 value: Vec<Vector2<f32>>,
176 /// `max_len` defines the maximum number of elements in the shader.
177 max_len: usize,
178 },
179
180 /// Three-dimensional vector.
181 Vector3 {
182 #[serde(default)]
183 value: Vector3<f32>,
184 },
185
186 /// Three-dimensional vector array.
187 Vector3Array {
188 value: Vec<Vector3<f32>>,
189 /// `max_len` defines the maximum number of elements in the shader.
190 max_len: usize,
191 },
192
193 /// Four-dimensional vector.
194 Vector4 {
195 #[serde(default)]
196 value: Vector4<f32>,
197 },
198
199 /// Four-dimensional vector array.
200 Vector4Array {
201 value: Vec<Vector4<f32>>,
202 /// `max_len` defines the maximum number of elements in the shader.
203 max_len: usize,
204 },
205
206 /// 2x2 Matrix.
207 Matrix2 {
208 #[serde(default)]
209 value: Matrix2<f32>,
210 },
211
212 /// 2x2 Matrix array.
213 Matrix2Array {
214 value: Vec<Matrix2<f32>>,
215 /// `max_len` defines the maximum number of elements in the shader.
216 max_len: usize,
217 },
218
219 /// 3x3 Matrix.
220 Matrix3 {
221 #[serde(default)]
222 value: Matrix3<f32>,
223 },
224
225 /// 3x3 Matrix array.
226 Matrix3Array {
227 value: Vec<Matrix3<f32>>,
228 /// `max_len` defines the maximum number of elements in the shader.
229 max_len: usize,
230 },
231
232 /// 4x4 Matrix.
233 Matrix4 {
234 #[serde(default)]
235 value: Matrix4<f32>,
236 },
237
238 /// 4x4 Matrix array.
239 Matrix4Array {
240 value: Vec<Matrix4<f32>>,
241 /// `max_len` defines the maximum number of elements in the shader.
242 max_len: usize,
243 },
244
245 /// An sRGB color.
246 Color {
247 /// Default Red.
248 #[serde(default = "default_color_component")]
249 r: u8,
250
251 /// Default Green.
252 #[serde(default = "default_color_component")]
253 g: u8,
254
255 /// Default Blue.
256 #[serde(default = "default_color_component")]
257 b: u8,
258
259 /// Default Alpha.
260 #[serde(default = "default_color_component")]
261 a: u8,
262 },
263}
264
265fn default_color_component() -> u8 {
266 255
267}
268
269#[derive(Serialize, Deserialize, Debug, PartialEq, Reflect, Visit, Clone, Default)]
270pub struct ShaderProperty {
271 pub name: ImmutableString,
272 pub kind: ShaderPropertyKind,
273}
274
275impl ShaderProperty {
276 pub fn new(name: impl Into<ImmutableString>, kind: ShaderPropertyKind) -> Self {
277 Self {
278 name: name.into(),
279 kind,
280 }
281 }
282}
283
284impl Default for ShaderPropertyKind {
285 fn default() -> Self {
286 Self::Float { value: 0.0 }
287 }
288}
289
290impl Default for ShaderResourceKind {
291 fn default() -> Self {
292 Self::PropertyGroup(Default::default())
293 }
294}
295
296/// Shader resource definition.
297#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq, Reflect, Visit)]
298pub struct ShaderResourceDefinition {
299 /// A name of the resource.
300 pub name: ImmutableString,
301 /// A kind of resource.
302 pub kind: ShaderResourceKind,
303 pub binding: usize,
304}
305
306impl ShaderResourceDefinition {
307 pub fn is_built_in(&self) -> bool {
308 self.name.starts_with("fyrox_")
309 }
310}
311
312define_shared_wrapper!(GpuProgram<dyn GpuProgramTrait>);