pub mod cone_trace;
pub mod irradiance;
pub mod probe_bake;
use crate::compiled::real::LawMinMax;
use glam::Vec3;
pub use cone_trace::{cone_trace, trace_hemisphere, ConeTraceConfig, ConeTraceResult};
pub use irradiance::{IrradianceGrid, IrradianceProbe};
pub use probe_bake::{bake_irradiance_grid, BakeGiConfig};
#[derive(Debug, Clone, Copy)]
pub struct DirectionalLight {
pub direction: Vec3,
pub color: Vec3,
}
impl Default for DirectionalLight {
fn default() -> Self {
Self {
direction: Vec3::new(0.5, 1.0, 0.3).normalize(),
color: Vec3::new(1.0, 0.95, 0.8),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct PointLight {
pub position: Vec3,
pub color: Vec3,
pub radius: f32,
}
#[inline]
pub fn sky_color(direction: Vec3) -> Vec3 {
let t = direction.y * 0.5 + 0.5; let ground = Vec3::new(0.1, 0.08, 0.05);
let sky = Vec3::new(0.4, 0.6, 1.0);
ground + (sky - ground) * t
}
#[inline]
pub fn direct_lighting(normal: Vec3, light: &DirectionalLight) -> Vec3 {
let ndotl = normal.dot(light.direction).law_max(0.0);
light.color * ndotl
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sky_color() {
let up = sky_color(Vec3::Y);
let down = sky_color(Vec3::NEG_Y);
assert!(up.z > down.z);
}
#[test]
fn test_direct_lighting() {
let light = DirectionalLight::default();
let lit = direct_lighting(Vec3::Y, &light);
assert!(lit.length() > 0.0);
let unlit = direct_lighting(Vec3::NEG_Y, &light);
assert!(unlit.length() < lit.length());
}
#[test]
fn test_directional_light_default() {
let light = DirectionalLight::default();
assert!((light.direction.length() - 1.0).abs() < 0.001);
}
}