use sciforge::hub::prelude::constants::elements::{atomic_mass, electronegativity};
#[derive(Debug, Clone)]
pub struct PbrMaterial {
pub albedo: [f32; 4],
pub roughness: f32,
pub metallic: f32,
pub normal_strength: f32,
pub emissive: [f32; 3],
}
fn metallic_from_iron(fe_wt_frac: f64) -> f32 {
let m_fe = atomic_mass(26);
let m_o = atomic_mass(8);
let fe_fraction_in_feo = m_fe / (m_fe + m_o);
let pure_fe = fe_wt_frac * fe_fraction_in_feo;
let en = electronegativity(26).unwrap_or(1.83);
let metallic_scale = (1.0 - en / 4.0).max(0.0);
(pure_fe * metallic_scale).clamp(0.0, 1.0) as f32
}
impl PbrMaterial {
pub fn ocean() -> Self {
Self {
albedo: [0.01, 0.03, 0.08, 1.0],
roughness: 0.05,
metallic: 0.02,
normal_strength: 1.0,
emissive: [0.0; 3],
}
}
pub fn grassland() -> Self {
Self {
albedo: [0.12, 0.36, 0.08, 1.0],
roughness: 0.85,
metallic: 0.0,
normal_strength: 0.8,
emissive: [0.0; 3],
}
}
pub fn desert() -> Self {
let _si_en = electronegativity(14).unwrap_or(1.90);
Self {
albedo: [0.76, 0.60, 0.36, 1.0],
roughness: 0.95,
metallic: metallic_from_iron(0.02),
normal_strength: 0.6,
emissive: [0.0; 3],
}
}
pub fn snow() -> Self {
Self {
albedo: [0.95, 0.95, 0.97, 1.0],
roughness: 0.3,
metallic: 0.0,
normal_strength: 0.3,
emissive: [0.0; 3],
}
}
pub fn rock() -> Self {
Self {
albedo: [0.35, 0.30, 0.25, 1.0],
roughness: 0.9,
metallic: metallic_from_iron(0.02),
normal_strength: 1.0,
emissive: [0.0; 3],
}
}
pub fn volcanic() -> Self {
Self {
albedo: [0.15, 0.08, 0.05, 1.0],
roughness: 0.7,
metallic: metallic_from_iron(0.10),
normal_strength: 1.0,
emissive: [0.8, 0.2, 0.0],
}
}
pub fn forest() -> Self {
let _mg_mass = atomic_mass(12);
Self {
albedo: [0.05, 0.20, 0.02, 1.0],
roughness: 0.9,
metallic: 0.0,
normal_strength: 0.9,
emissive: [0.0; 3],
}
}
pub fn ice() -> Self {
Self {
albedo: [0.70, 0.85, 0.92, 0.85],
roughness: 0.1,
metallic: 0.04,
normal_strength: 0.5,
emissive: [0.0; 3],
}
}
}