easy_gltf/scene/model/material/
pbr.rs

1use crate::utils::GltfData;
2use cgmath::*;
3use image::{GrayImage, RgbaImage};
4use std::sync::Arc;
5
6#[derive(Clone, Debug)]
7/// A set of parameter values that are used to define the metallic-roughness
8/// material model from Physically-Based Rendering (PBR) methodology.
9pub struct PbrMaterial {
10    /// The `base_color_factor` contains scaling factors for the red, green,
11    /// blue and alpha component of the color. If no texture is used, these
12    /// values will define the color of the whole object in **RGB** color space.
13    pub base_color_factor: Vector4<f32>,
14
15    /// The `base_color_texture` is the main texture that will be applied to the
16    /// object.
17    ///
18    /// The texture contains RGB(A) components in **sRGB** color space.
19    pub base_color_texture: Option<Arc<RgbaImage>>,
20
21    /// Contains the metalness value
22    pub metallic_texture: Option<Arc<GrayImage>>,
23
24    /// `metallic_factor` is multiply to the `metallic_texture` value. If no
25    /// texture is given, then the factor define the metalness for the whole
26    /// object.
27    pub metallic_factor: f32,
28
29    /// Contains the roughness value
30    pub roughness_texture: Option<Arc<GrayImage>>,
31
32    /// `roughness_factor` is multiply to the `roughness_texture` value. If no
33    /// texture is given, then the factor define the roughness for the whole
34    /// object.
35    pub roughness_factor: f32,
36}
37
38impl PbrMaterial {
39    pub(crate) fn load(pbr: gltf::material::PbrMetallicRoughness, data: &mut GltfData) -> Self {
40        let mut material = Self {
41            base_color_factor: pbr.base_color_factor().into(),
42            ..Default::default()
43        };
44        if let Some(texture) = pbr.base_color_texture() {
45            material.base_color_texture = Some(data.load_base_color_image(&texture.texture()));
46        }
47
48        material.roughness_factor = pbr.roughness_factor();
49        material.metallic_factor = pbr.metallic_factor();
50
51        if let Some(texture) = pbr.metallic_roughness_texture() {
52            if material.metallic_factor > 0. {
53                material.metallic_texture = Some(data.load_gray_image(&texture.texture(), 2));
54            }
55            if material.roughness_factor > 0. {
56                material.roughness_texture = Some(data.load_gray_image(&texture.texture(), 1));
57            }
58        }
59
60        material
61    }
62}
63
64impl Default for PbrMaterial {
65    fn default() -> Self {
66        PbrMaterial {
67            base_color_factor: Vector4::new(1., 1., 1., 1.),
68            base_color_texture: None,
69            metallic_factor: 0.,
70            metallic_texture: None,
71            roughness_factor: 0.,
72            roughness_texture: None,
73        }
74    }
75}