#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct SpecularViewConfig {
pub show_roughness: bool,
pub roughness_scale: f32,
pub f0_scale: f32,
}
impl Default for SpecularViewConfig {
fn default() -> Self {
Self { show_roughness: true, roughness_scale: 1.0, f0_scale: 1.0 }
}
}
#[derive(Debug, Clone)]
pub struct SpecularView {
pub config: SpecularViewConfig,
pub enabled: bool,
}
impl Default for SpecularView {
fn default() -> Self {
Self { config: SpecularViewConfig::default(), enabled: false }
}
}
pub fn spv_enable(view: &mut SpecularView) {
view.enabled = true;
}
pub fn spv_disable(view: &mut SpecularView) {
view.enabled = false;
}
pub fn spv_set_roughness_scale(view: &mut SpecularView, scale: f32) {
view.config.roughness_scale = scale.clamp(0.0, 4.0);
}
pub fn spv_to_color(roughness: f32, f0: f32, config: &SpecularViewConfig) -> [f32; 4] {
let r = (roughness * config.roughness_scale).clamp(0.0, 1.0);
let f = (f0 * config.f0_scale).clamp(0.0, 1.0);
if config.show_roughness {
[r, r, r, 1.0]
} else {
[f, f, f, 1.0]
}
}
pub fn spv_perceptual_roughness(linear: f32) -> f32 {
linear.clamp(0.0, 1.0).sqrt()
}
pub fn spv_f0_from_ior(ior: f32) -> f32 {
let n = ior.max(1.0);
let ratio = (n - 1.0) / (n + 1.0);
ratio * ratio
}
pub fn spv_to_json(view: &SpecularView) -> String {
format!(
r#"{{"show_roughness":{},"roughness_scale":{:.2},"enabled":{}}}"#,
view.config.show_roughness, view.config.roughness_scale, view.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_disabled() {
let v = SpecularView::default();
assert!(!v.enabled);
}
#[test]
fn test_enable_disable() {
let mut v = SpecularView::default();
spv_enable(&mut v);
assert!(v.enabled);
spv_disable(&mut v);
assert!(!v.enabled);
}
#[test]
fn test_roughness_scale() {
let mut v = SpecularView::default();
spv_set_roughness_scale(&mut v, 2.0);
assert!((v.config.roughness_scale - 2.0).abs() < 1e-6);
}
#[test]
fn test_roughness_scale_clamp() {
let mut v = SpecularView::default();
spv_set_roughness_scale(&mut v, 100.0);
assert!((v.config.roughness_scale - 4.0).abs() < 1e-6);
}
#[test]
fn test_to_color_roughness_mode() {
let cfg = SpecularViewConfig { show_roughness: true, ..Default::default() };
let c = spv_to_color(0.5, 0.04, &cfg);
assert!((c[0] - c[1]).abs() < 1e-6);
}
#[test]
fn test_perceptual_roughness() {
assert!((spv_perceptual_roughness(1.0) - 1.0).abs() < 1e-6);
}
#[test]
fn test_perceptual_roughness_quarter() {
assert!((spv_perceptual_roughness(0.25) - 0.5).abs() < 1e-6);
}
#[test]
fn test_f0_from_ior() {
let f0 = spv_f0_from_ior(1.5);
assert!((f0 - 0.04).abs() < 0.001);
}
#[test]
fn test_to_json_enabled() {
let mut v = SpecularView::default();
spv_enable(&mut v);
let json = spv_to_json(&v);
assert!(json.contains("true"));
}
}