#[derive(Debug, Clone, Copy)]
pub struct PbrMaterial {
pub name: &'static str,
pub albedo: [f32; 3],
pub roughness: f32,
pub metallic: f32,
pub emissive: [f32; 3],
pub normal_scale: f32,
pub ior: f32,
pub subsurface: f32,
}
impl PbrMaterial {
pub fn fresnel_r0(&self) -> f64 {
let n = self.ior as f64;
let r = (n - 1.0) / (n + 1.0);
r * r
}
pub fn default_regolith() -> Self {
Self {
name: "default_regolith",
albedo: [0.106, 0.100, 0.095],
roughness: 0.85,
metallic: 0.02,
emissive: [0.0, 0.0, 0.0],
normal_scale: 1.0,
ior: 1.50,
subsurface: 0.0,
}
}
pub fn smooth_plains() -> Self {
Self {
name: "smooth_plains",
albedo: [0.12, 0.115, 0.11],
roughness: 0.6,
metallic: 0.03,
emissive: [0.0, 0.0, 0.0],
normal_scale: 0.8,
ior: 1.52,
subsurface: 0.0,
}
}
pub fn crater_floor() -> Self {
Self {
name: "crater_floor",
albedo: [0.11, 0.105, 0.10],
roughness: 0.65,
metallic: 0.01,
emissive: [0.0, 0.0, 0.0],
normal_scale: 1.2,
ior: 1.50,
subsurface: 0.0,
}
}
pub fn crater_rim() -> Self {
Self {
name: "crater_rim",
albedo: [0.08, 0.075, 0.07],
roughness: 0.90,
metallic: 0.03,
emissive: [0.0, 0.0, 0.0],
normal_scale: 1.5,
ior: 1.54,
subsurface: 0.0,
}
}
pub fn hollows() -> Self {
Self {
name: "hollows",
albedo: [0.25, 0.24, 0.23],
roughness: 0.35,
metallic: 0.01,
emissive: [0.0, 0.0, 0.0],
normal_scale: 0.6,
ior: 1.45,
subsurface: 0.1,
}
}
pub fn polar_ice() -> Self {
Self {
name: "polar_ice",
albedo: [0.80, 0.82, 0.85],
roughness: 0.2,
metallic: 0.0,
emissive: [0.0, 0.0, 0.0],
normal_scale: 0.4,
ior: 1.31,
subsurface: 0.5,
}
}
pub fn thermal_emission(&self, surface_temp_k: f64) -> [f32; 3] {
if surface_temp_k < 400.0 {
return [0.0, 0.0, 0.0];
}
let t = (surface_temp_k / 700.0).min(1.0) as f32;
[t * 0.6, t * 0.15, t * 0.02]
}
}
pub fn albedo() -> f32 {
0.106
}
pub fn roughness() -> f32 {
0.8
}
pub fn all_mercury() -> [PbrMaterial; 6] {
[
PbrMaterial::default_regolith(),
PbrMaterial::smooth_plains(),
PbrMaterial::crater_floor(),
PbrMaterial::crater_rim(),
PbrMaterial::hollows(),
PbrMaterial::polar_ice(),
]
}