// Demo code and the images generated by it (c) by SEGFAULT // // This code and all images generated by it is licensed under a // Creative Commons Attribution-ShareAlike 4.0 International License. // // You should have received a copy of the license along with this // work. If not, see . extern crate png; extern crate rand; extern crate rustic_zen; use std::env; use std::ffi::OsString; use std::fs::File; use std::io::BufWriter; use std::sync::Arc; use std::time; // To use encoder.set() use png::HasParameters; use rand::prelude::*; use rustic_zen::geom::Vector; use rustic_zen::material::Material; use rustic_zen::prelude::*; fn refraction(direction: &Vector, normal: &Vector, ior: f64) -> Option { let tangent = Vector { x: normal.y, y: -normal.x, }; let backface = normal.dot(direction); if backface <= 0.0 { let dti = direction.dot(&tangent) / ior; Some((tangent * (dti)) - (*normal * f64::sqrt(1.0 - dti.powi(2)))) } else { let dti = direction.dot(&tangent) * ior; if dti > 1.0 { Some(direction.reflect(normal)) } else { Some((tangent * (dti)) + (*normal * f64::sqrt(1.0 - dti.powi(2)))) } } } fn dispersion_law(ln: f64, b: f64, c: f64) -> f64 { let lm2 = (ln / 1000.0).powi(2); f64::sqrt(1.0 + ((b * lm2) / (lm2 - c))) } fn pbr_transparent_surface(index: f64, dispersion: f64) -> Material { Arc::new( move |direction: &Vector, normal: &Vector, l: f64, _: f64, _: &mut R| { refraction(direction, normal, dispersion_law(l, index, dispersion)) }, ) } fn main() { let args: Vec = env::args().collect(); let (quality, filename) = if args.len() < 2 { (1, "prism.png".to_owned()) } else { let quality = usize::from_str_radix(&args[1], 10).expect("Usage