shine_gltf/extensions/
material.rs

1use serde_derive::{Deserialize, Serialize};
2use shine_gltf_macro::Validate;
3
4#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
5use {
6    material::StrengthFactor,
7    texture, Path, Root, {Error, Validate},
8};
9
10/// The material appearance of a primitive.
11#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
12pub struct Material {
13    #[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
14    #[serde(
15        default,
16        rename = "KHR_materials_pbrSpecularGlossiness",
17        skip_serializing_if = "Option::is_none"
18    )]
19    pub pbr_specular_glossiness: Option<PbrSpecularGlossiness>,
20}
21
22/// A set of parameter values that are used to define the metallic-roughness
23/// material model from Physically-Based Rendering (PBR) methodology.
24#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
25pub struct PbrMetallicRoughness {}
26
27/// A set of parameter values that are used to define the specular-glossiness
28/// material model from Physically-Based Rendering (PBR) methodology.
29///
30/// This model supports more materials than metallic-roughness, at the cost of
31/// increased memory use. When both are available, specular-glossiness should be
32/// preferred.
33#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
34#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
35#[serde(default, rename_all = "camelCase")]
36pub struct PbrSpecularGlossiness {
37    /// The material's diffuse factor.
38    ///
39    /// The RGBA components of the reflected diffuse color of the
40    /// material. Metals have a diffuse value of `[0.0, 0.0, 0.0]`. The fourth
41    /// component (A) is the alpha coverage of the material. The `alphaMode`
42    /// property specifies how alpha is interpreted. The values are linear.
43    pub diffuse_factor: PbrDiffuseFactor,
44
45    /// The diffuse texture.
46    ///
47    /// This texture contains RGB(A) components of the reflected diffuse color
48    /// of the material in sRGB color space. If the fourth component (A) is
49    /// present, it represents the alpha coverage of the material. Otherwise, an
50    /// alpha of 1.0 is assumed. The `alphaMode` property specifies how alpha is
51    /// interpreted. The stored texels must not be premultiplied.
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub diffuse_texture: Option<texture::Info>,
54
55    /// The material's specular factor.
56    pub specular_factor: PbrSpecularFactor,
57
58    /// The glossiness or smoothness of the material.
59    ///
60    /// A value of 1.0 means the material has full glossiness or is perfectly
61    /// smooth. A value of 0.0 means the material has no glossiness or is
62    /// completely rough. This value is linear.
63    pub glossiness_factor: StrengthFactor,
64
65    /// The specular-glossiness texture.
66    ///
67    /// A RGBA texture, containing the specular color of the material (RGB
68    /// components) and its glossiness (A component). The values are in sRGB
69    /// space.
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub specular_glossiness_texture: Option<texture::Info>,
72}
73
74/// Defines the normal texture of a material.
75#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
76pub struct NormalTexture {}
77
78/// Defines the occlusion texture of a material.
79#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
80pub struct OcclusionTexture {}
81
82/// The diffuse factor of a material.
83#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
84#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
85pub struct PbrDiffuseFactor(pub [f32; 4]);
86
87#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
88impl Default for PbrDiffuseFactor {
89    fn default() -> Self {
90        PbrDiffuseFactor([1.0, 1.0, 1.0, 1.0])
91    }
92}
93
94#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
95impl Validate for PbrDiffuseFactor {
96    fn validate_completely<P, R>(&self, _: &Root, path: P, report: &mut R)
97    where
98        P: Fn() -> Path,
99        R: FnMut(&Fn() -> Path, Error),
100    {
101        for x in &self.0 {
102            if *x < 0.0 || *x > 1.0 {
103                report(&path, Error::Invalid);
104                // Only report once
105                break;
106            }
107        }
108    }
109}
110
111/// The specular factor of a material.
112#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
113#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
114pub struct PbrSpecularFactor(pub [f32; 3]);
115
116#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
117impl Default for PbrSpecularFactor {
118    fn default() -> Self {
119        PbrSpecularFactor([1.0, 1.0, 1.0])
120    }
121}
122
123#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
124impl Validate for PbrSpecularFactor {
125    fn validate_completely<P, R>(&self, _: &Root, path: P, report: &mut R)
126    where
127        P: Fn() -> Path,
128        R: FnMut(&Fn() -> Path, Error),
129    {
130        for x in &self.0 {
131            if *x < 0.0 || *x > 1.0 {
132                report(&path, Error::Invalid);
133                // Only report once
134                break;
135            }
136        }
137    }
138}