gltf_json/extensions/
material.rs

1#[allow(unused_imports)] // different features use different imports
2use crate::{material::StrengthFactor, texture, validation::Validate, Extras};
3use gltf_derive::Validate;
4use serde_derive::{Deserialize, Serialize};
5#[cfg(feature = "extensions")]
6use serde_json::{Map, Value};
7
8/// The material appearance of a primitive.
9#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
10pub struct Material {
11    #[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
12    #[serde(
13        default,
14        rename = "KHR_materials_pbrSpecularGlossiness",
15        skip_serializing_if = "Option::is_none"
16    )]
17    pub pbr_specular_glossiness: Option<PbrSpecularGlossiness>,
18
19    #[cfg(feature = "KHR_materials_unlit")]
20    #[serde(
21        default,
22        rename = "KHR_materials_unlit",
23        skip_serializing_if = "Option::is_none"
24    )]
25    pub unlit: Option<Unlit>,
26
27    #[cfg(feature = "KHR_materials_transmission")]
28    #[serde(
29        default,
30        rename = "KHR_materials_transmission",
31        skip_serializing_if = "Option::is_none"
32    )]
33    pub transmission: Option<Transmission>,
34
35    #[cfg(feature = "KHR_materials_volume")]
36    #[serde(
37        default,
38        rename = "KHR_materials_volume",
39        skip_serializing_if = "Option::is_none"
40    )]
41    pub volume: Option<Volume>,
42
43    #[cfg(feature = "KHR_materials_specular")]
44    #[serde(
45        default,
46        rename = "KHR_materials_specular",
47        skip_serializing_if = "Option::is_none"
48    )]
49    pub specular: Option<Specular>,
50
51    #[cfg(feature = "KHR_materials_ior")]
52    #[serde(
53        default,
54        rename = "KHR_materials_ior",
55        skip_serializing_if = "Option::is_none"
56    )]
57    pub ior: Option<Ior>,
58
59    #[cfg(feature = "KHR_materials_emissive_strength")]
60    #[serde(
61        default,
62        rename = "KHR_materials_emissive_strength",
63        skip_serializing_if = "Option::is_none"
64    )]
65    pub emissive_strength: Option<EmissiveStrength>,
66
67    #[cfg(feature = "extensions")]
68    #[serde(default, flatten)]
69    pub others: Map<String, Value>,
70}
71
72/// A set of parameter values that are used to define the metallic-roughness
73/// material model from Physically-Based Rendering (PBR) methodology.
74#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
75pub struct PbrMetallicRoughness {
76    #[cfg(feature = "extensions")]
77    #[serde(default, flatten)]
78    pub others: Map<String, Value>,
79}
80
81/// A set of parameter values that are used to define the specular-glossiness
82/// material model from Physically-Based Rendering (PBR) methodology.
83///
84/// This model supports more materials than metallic-roughness, at the cost of
85/// increased memory use. When both are available, specular-glossiness should be
86/// preferred.
87#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
88#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
89#[serde(default, rename_all = "camelCase")]
90pub struct PbrSpecularGlossiness {
91    /// The material's diffuse factor.
92    ///
93    /// The RGBA components of the reflected diffuse color of the
94    /// material. Metals have a diffuse value of `[0.0, 0.0, 0.0]`. The fourth
95    /// component (A) is the alpha coverage of the material. The `alphaMode`
96    /// property specifies how alpha is interpreted. The values are linear.
97    pub diffuse_factor: PbrDiffuseFactor,
98
99    /// The diffuse texture.
100    ///
101    /// This texture contains RGB(A) components of the reflected diffuse color
102    /// of the material in sRGB color space. If the fourth component (A) is
103    /// present, it represents the alpha coverage of the material. Otherwise, an
104    /// alpha of 1.0 is assumed. The `alphaMode` property specifies how alpha is
105    /// interpreted. The stored texels must not be premultiplied.
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub diffuse_texture: Option<texture::Info>,
108
109    /// The material's specular factor.
110    pub specular_factor: PbrSpecularFactor,
111
112    /// The glossiness or smoothness of the material.
113    ///
114    /// A value of 1.0 means the material has full glossiness or is perfectly
115    /// smooth. A value of 0.0 means the material has no glossiness or is
116    /// completely rough. This value is linear.
117    pub glossiness_factor: StrengthFactor,
118
119    /// The specular-glossiness texture.
120    ///
121    /// A RGBA texture, containing the specular color of the material (RGB
122    /// components) and its glossiness (A component). The values are in sRGB
123    /// space.
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub specular_glossiness_texture: Option<texture::Info>,
126
127    #[cfg(feature = "extensions")]
128    #[serde(default, flatten)]
129    pub others: Map<String, Value>,
130
131    /// Optional application specific data.
132    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
133    #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
134    pub extras: Extras,
135}
136
137/// Defines the normal texture of a material.
138#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
139pub struct NormalTexture {
140    #[cfg(feature = "extensions")]
141    #[serde(default, flatten)]
142    pub others: Map<String, Value>,
143}
144
145/// Defines the occlusion texture of a material.
146#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
147pub struct OcclusionTexture {
148    #[cfg(feature = "extensions")]
149    #[serde(default, flatten)]
150    pub others: Map<String, Value>,
151}
152
153/// The diffuse factor of a material.
154#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
155#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
156pub struct PbrDiffuseFactor(pub [f32; 4]);
157
158#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
159impl Default for PbrDiffuseFactor {
160    fn default() -> Self {
161        PbrDiffuseFactor([1.0, 1.0, 1.0, 1.0])
162    }
163}
164
165#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
166impl Validate for PbrDiffuseFactor {}
167
168/// The specular factor of a material.
169#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
170#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
171pub struct PbrSpecularFactor(pub [f32; 3]);
172
173#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
174impl Default for PbrSpecularFactor {
175    fn default() -> Self {
176        PbrSpecularFactor([1.0, 1.0, 1.0])
177    }
178}
179
180#[cfg(feature = "KHR_materials_pbrSpecularGlossiness")]
181impl Validate for PbrSpecularFactor {}
182
183/// Empty struct that should be present for primitives which should not be shaded with the PBR shading model.
184#[cfg(feature = "KHR_materials_unlit")]
185#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
186pub struct Unlit {}
187
188/// A number in the inclusive range [0.0, 1.0] with a default value of 0.0.
189#[cfg(feature = "KHR_materials_transmission")]
190#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
191pub struct TransmissionFactor(pub f32);
192
193#[cfg(feature = "KHR_materials_transmission")]
194impl Default for TransmissionFactor {
195    fn default() -> Self {
196        TransmissionFactor(0.0)
197    }
198}
199
200#[cfg(feature = "KHR_materials_transmission")]
201impl Validate for TransmissionFactor {}
202
203#[cfg(feature = "KHR_materials_transmission")]
204#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
205#[serde(default, rename_all = "camelCase")]
206pub struct Transmission {
207    /// The base percentage of light that is transmitted through the surface.
208    ///
209    /// The amount of light that is transmitted by the surface rather than diffusely re-emitted.
210    /// This is a percentage of all the light that penetrates a surface (i.e. isn’t specularly reflected)
211    /// rather than a percentage of the total light that hits a surface.
212    /// A value of 1.0 means that 100% of the light that penetrates the surface is transmitted through.
213    pub transmission_factor: TransmissionFactor,
214
215    /// The transmission texture.
216    ///
217    /// The R channel of this texture defines the amount of light that is transmitted by the surface
218    /// rather than diffusely re-emitted. A value of 1.0 in the red channel means that 100% of the light
219    /// that penetrates the surface (i.e. isn’t specularly reflected) is transmitted through.
220    /// The value is linear and is multiplied by the transmissionFactor to determine the total transmission value.
221    #[serde(skip_serializing_if = "Option::is_none")]
222    pub transmission_texture: Option<texture::Info>,
223
224    /// Optional application specific data.
225    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
226    #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
227    pub extras: Extras,
228}
229
230/// A positive number with default value of 1.5
231#[cfg(feature = "KHR_materials_ior")]
232#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
233pub struct IndexOfRefraction(pub f32);
234
235#[cfg(feature = "KHR_materials_ior")]
236impl Default for IndexOfRefraction {
237    fn default() -> Self {
238        IndexOfRefraction(1.5)
239    }
240}
241
242#[cfg(feature = "KHR_materials_ior")]
243impl Validate for IndexOfRefraction {}
244
245#[cfg(feature = "KHR_materials_ior")]
246#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
247#[serde(default, rename_all = "camelCase")]
248pub struct Ior {
249    /// The index of refraction.
250    ///
251    /// Typical values for the index of refraction range from 1 to 2.
252    /// In rare cases values greater than 2 are possible.
253    /// For example, the ior of water is 1.33, and diamond is 2.42
254    pub ior: IndexOfRefraction,
255
256    /// Optional application specific data.
257    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
258    #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
259    pub extras: Extras,
260}
261
262/// A positive number with 1.0 as the default value.
263#[cfg(feature = "KHR_materials_emissive_strength")]
264#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
265pub struct EmissiveStrengthFactor(pub f32);
266
267#[cfg(feature = "KHR_materials_emissive_strength")]
268impl Default for EmissiveStrengthFactor {
269    fn default() -> Self {
270        EmissiveStrengthFactor(1.0)
271    }
272}
273
274#[cfg(feature = "KHR_materials_emissive_strength")]
275impl Validate for EmissiveStrengthFactor {}
276
277#[cfg(feature = "KHR_materials_emissive_strength")]
278#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
279#[serde(default, rename_all = "camelCase")]
280pub struct EmissiveStrength {
281    /// The factor by which to scale the emissive factor or emissive texture.
282    pub emissive_strength: EmissiveStrengthFactor,
283}
284
285/// A number in the inclusive range [0.0, +inf] with a default value of 0.0.
286#[cfg(feature = "KHR_materials_volume")]
287#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
288pub struct ThicknessFactor(pub f32);
289
290#[cfg(feature = "KHR_materials_volume")]
291impl Default for ThicknessFactor {
292    fn default() -> Self {
293        ThicknessFactor(0.0)
294    }
295}
296
297#[cfg(feature = "KHR_materials_volume")]
298impl Validate for ThicknessFactor {}
299
300/// A number in the inclusive range [0.0, +inf] with a default value of +inf.
301#[cfg(feature = "KHR_materials_volume")]
302#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
303pub struct AttenuationDistance(pub f32);
304
305#[cfg(feature = "KHR_materials_volume")]
306impl Default for AttenuationDistance {
307    fn default() -> Self {
308        AttenuationDistance(f32::INFINITY)
309    }
310}
311
312#[cfg(feature = "KHR_materials_volume")]
313impl Validate for AttenuationDistance {}
314
315/// A colour in the inclusive range [[0.0; 3], [1.0; 3]] with a default value of [1.0; 3].
316#[cfg(feature = "KHR_materials_volume")]
317#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
318pub struct AttenuationColor(pub [f32; 3]);
319
320#[cfg(feature = "KHR_materials_volume")]
321impl Default for AttenuationColor {
322    fn default() -> Self {
323        AttenuationColor([1.0, 1.0, 1.0])
324    }
325}
326
327#[cfg(feature = "KHR_materials_volume")]
328impl Validate for AttenuationColor {}
329
330#[cfg(feature = "KHR_materials_volume")]
331#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
332#[serde(default, rename_all = "camelCase")]
333pub struct Volume {
334    /// The thickness of the volume beneath the surface. The value is
335    /// given in the coordinate space of the mesh. If the value is 0
336    /// the material is thin-walled. Otherwise the material is a
337    /// volume boundary. The `doubleSided` property has no effect on
338    /// volume boundaries. Range is [0, +inf).
339    pub thickness_factor: ThicknessFactor,
340
341    /// A texture that defines the thickness, stored in the G channel.
342    /// This will be multiplied by `thickness_factor`. Range is [0, 1].
343    #[serde(skip_serializing_if = "Option::is_none")]
344    pub thickness_texture: Option<texture::Info>,
345
346    /// Density of the medium given as the average distance that light
347    /// travels in the medium before interacting with a particle. The
348    /// value is given in world space. Range is (0, +inf).
349    pub attenuation_distance: AttenuationDistance,
350
351    /// The color that white light turns into due to absorption when
352    /// reaching the attenuation distance.
353    pub attenuation_color: AttenuationColor,
354
355    /// Optional application specific data.
356    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
357    #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
358    pub extras: Extras,
359}
360
361/// A number in the inclusive range [0.0, +inf] with a default value of 1.0.
362#[cfg(feature = "KHR_materials_specular")]
363#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
364pub struct SpecularFactor(pub f32);
365
366#[cfg(feature = "KHR_materials_specular")]
367impl Default for SpecularFactor {
368    fn default() -> Self {
369        SpecularFactor(1.0)
370    }
371}
372
373#[cfg(feature = "KHR_materials_specular")]
374impl Validate for SpecularFactor {}
375
376/// A colour in the inclusive range [[0.0; 3], [1.0; 3]] with a default value of [1.0; 3].
377#[cfg(feature = "KHR_materials_specular")]
378#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
379pub struct SpecularColorFactor(pub [f32; 3]);
380
381#[cfg(feature = "KHR_materials_specular")]
382impl Default for SpecularColorFactor {
383    fn default() -> Self {
384        SpecularColorFactor([1.0, 1.0, 1.0])
385    }
386}
387
388#[cfg(feature = "KHR_materials_specular")]
389impl Validate for SpecularColorFactor {}
390
391#[cfg(feature = "KHR_materials_specular")]
392#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
393#[serde(default, rename_all = "camelCase")]
394pub struct Specular {
395    /// The strength of the specular reflection.
396    pub specular_factor: SpecularFactor,
397
398    /// A texture that defines the strength of the specular reflection,
399    /// stored in the alpha (`A`) channel. This will be multiplied by
400    /// `specular_factor`.
401    #[serde(skip_serializing_if = "Option::is_none")]
402    pub specular_texture: Option<texture::Info>,
403
404    /// The F0 color of the specular reflection (linear RGB).
405    pub specular_color_factor: SpecularColorFactor,
406
407    /// A texture that defines the F0 color of the specular reflection,
408    /// stored in the `RGB` channels and encoded in sRGB. This texture
409    /// will be multiplied by `specular_color_factor`.
410    #[serde(skip_serializing_if = "Option::is_none")]
411    pub specular_color_texture: Option<texture::Info>,
412
413    /// Optional application specific data.
414    #[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
415    #[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
416    pub extras: Extras,
417}