#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DeferredConfig {
pub ambient_intensity: f32,
pub max_lights: u32,
pub output_count: u32,
pub pass_name: String,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DeferredShading {
pub config: DeferredConfig,
}
#[allow(dead_code)]
pub fn new_deferred_config(ambient: f32, max_lights: u32) -> DeferredConfig {
DeferredConfig {
ambient_intensity: ambient,
max_lights,
output_count: 1,
pass_name: "deferred".to_owned(),
}
}
#[allow(dead_code)]
pub fn default_deferred_config() -> DeferredConfig {
new_deferred_config(0.1, 32)
}
#[allow(dead_code)]
pub fn shade_gbuffer_point(cfg: &DeferredConfig, albedo: [f32; 4]) -> [f32; 4] {
let a = cfg.ambient_intensity;
[albedo[0] * a, albedo[1] * a, albedo[2] * a, albedo[3]]
}
#[allow(dead_code)]
pub fn deferred_ambient(cfg: &DeferredConfig, albedo: [f32; 3]) -> [f32; 3] {
let a = cfg.ambient_intensity;
[albedo[0] * a, albedo[1] * a, albedo[2] * a]
}
#[allow(dead_code)]
pub fn deferred_directional(normal: [f32; 3], light_dir: [f32; 3], color: [f32; 3]) -> [f32; 3] {
let ndotl = (normal[0] * light_dir[0] + normal[1] * light_dir[1] + normal[2] * light_dir[2])
.max(0.0);
[color[0] * ndotl, color[1] * ndotl, color[2] * ndotl]
}
#[allow(dead_code)]
pub fn deferred_point_light(pos: [f32; 3], light_pos: [f32; 3], color: [f32; 3], radius: f32) -> [f32; 3] {
let dx = pos[0] - light_pos[0];
let dy = pos[1] - light_pos[1];
let dz = pos[2] - light_pos[2];
let dist = (dx * dx + dy * dy + dz * dz).sqrt();
let att = (1.0 - (dist / radius.max(f32::EPSILON)).min(1.0)).max(0.0);
[color[0] * att, color[1] * att, color[2] * att]
}
#[allow(dead_code)]
pub fn deferred_output_count(cfg: &DeferredConfig) -> u32 {
cfg.output_count
}
#[allow(dead_code)]
pub fn deferred_pass_name(cfg: &DeferredConfig) -> &str {
&cfg.pass_name
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let cfg = default_deferred_config();
assert!(cfg.ambient_intensity > 0.0);
assert!(cfg.max_lights > 0);
}
#[test]
fn test_new_deferred_config() {
let cfg = new_deferred_config(0.2, 16);
assert!((cfg.ambient_intensity - 0.2).abs() < 1e-6);
assert_eq!(cfg.max_lights, 16);
}
#[test]
fn test_shade_gbuffer_point_scales_albedo() {
let cfg = new_deferred_config(0.5, 8);
let result = shade_gbuffer_point(&cfg, [1.0, 1.0, 1.0, 1.0]);
assert!((result[0] - 0.5).abs() < 1e-5);
}
#[test]
fn test_deferred_ambient() {
let cfg = new_deferred_config(0.3, 8);
let a = deferred_ambient(&cfg, [1.0, 1.0, 1.0]);
assert!((a[0] - 0.3).abs() < 1e-5);
}
#[test]
fn test_deferred_directional_facing() {
let n = [0.0_f32, 1.0, 0.0];
let l = [0.0_f32, 1.0, 0.0];
let c = deferred_directional(n, l, [1.0, 1.0, 1.0]);
assert!((c[0] - 1.0).abs() < 1e-5);
}
#[test]
fn test_deferred_directional_away() {
let n = [0.0_f32, 1.0, 0.0];
let l = [0.0_f32, -1.0, 0.0];
let c = deferred_directional(n, l, [1.0, 1.0, 1.0]);
assert!(c[0].abs() < 1e-6);
}
#[test]
fn test_deferred_point_light_near() {
let pos = [0.0_f32; 3];
let light = [0.0_f32; 3];
let c = deferred_point_light(pos, light, [1.0, 1.0, 1.0], 5.0);
assert!((c[0] - 1.0).abs() < 1e-5);
}
#[test]
fn test_deferred_point_light_far() {
let pos = [100.0_f32, 0.0, 0.0];
let light = [0.0_f32; 3];
let c = deferred_point_light(pos, light, [1.0, 1.0, 1.0], 5.0);
assert!(c[0].abs() < 1e-5);
}
#[test]
fn test_deferred_output_count() {
let cfg = default_deferred_config();
assert_eq!(deferred_output_count(&cfg), 1);
}
#[test]
fn test_deferred_pass_name() {
let cfg = default_deferred_config();
assert_eq!(deferred_pass_name(&cfg), "deferred");
}
}