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>);