Skip to main content

earth/rendering/
materials.rs

1use sciforge::hub::prelude::constants::elements::{atomic_mass, electronegativity};
2#[derive(Debug, Clone)]
3pub struct PbrMaterial {
4    pub albedo: [f32; 4],
5    pub roughness: f32,
6    pub metallic: f32,
7    pub normal_strength: f32,
8    pub emissive: [f32; 3],
9}
10fn metallic_from_iron(fe_wt_frac: f64) -> f32 {
11    let m_fe = atomic_mass(26);
12    let m_o = atomic_mass(8);
13    let fe_fraction_in_feo = m_fe / (m_fe + m_o);
14    let pure_fe = fe_wt_frac * fe_fraction_in_feo;
15    let en = electronegativity(26).unwrap_or(1.83);
16    let metallic_scale = (1.0 - en / 4.0).max(0.0);
17    (pure_fe * metallic_scale).clamp(0.0, 1.0) as f32
18}
19impl PbrMaterial {
20    pub fn ocean() -> Self {
21        Self {
22            albedo: [0.01, 0.03, 0.08, 1.0],
23            roughness: 0.05,
24            metallic: 0.02,
25            normal_strength: 1.0,
26            emissive: [0.0; 3],
27        }
28    }
29    pub fn grassland() -> Self {
30        Self {
31            albedo: [0.12, 0.36, 0.08, 1.0],
32            roughness: 0.85,
33            metallic: 0.0,
34            normal_strength: 0.8,
35            emissive: [0.0; 3],
36        }
37    }
38    pub fn desert() -> Self {
39        let _si_en = electronegativity(14).unwrap_or(1.90);
40        Self {
41            albedo: [0.76, 0.60, 0.36, 1.0],
42            roughness: 0.95,
43            metallic: metallic_from_iron(0.02),
44            normal_strength: 0.6,
45            emissive: [0.0; 3],
46        }
47    }
48    pub fn snow() -> Self {
49        Self {
50            albedo: [0.95, 0.95, 0.97, 1.0],
51            roughness: 0.3,
52            metallic: 0.0,
53            normal_strength: 0.3,
54            emissive: [0.0; 3],
55        }
56    }
57    pub fn rock() -> Self {
58        Self {
59            albedo: [0.35, 0.30, 0.25, 1.0],
60            roughness: 0.9,
61            metallic: metallic_from_iron(0.02),
62            normal_strength: 1.0,
63            emissive: [0.0; 3],
64        }
65    }
66    pub fn volcanic() -> Self {
67        Self {
68            albedo: [0.15, 0.08, 0.05, 1.0],
69            roughness: 0.7,
70            metallic: metallic_from_iron(0.10),
71            normal_strength: 1.0,
72            emissive: [0.8, 0.2, 0.0],
73        }
74    }
75    pub fn forest() -> Self {
76        let _mg_mass = atomic_mass(12);
77        Self {
78            albedo: [0.05, 0.20, 0.02, 1.0],
79            roughness: 0.9,
80            metallic: 0.0,
81            normal_strength: 0.9,
82            emissive: [0.0; 3],
83        }
84    }
85    pub fn ice() -> Self {
86        Self {
87            albedo: [0.70, 0.85, 0.92, 0.85],
88            roughness: 0.1,
89            metallic: 0.04,
90            normal_strength: 0.5,
91            emissive: [0.0; 3],
92        }
93    }
94}