mod perlin; mod vec3; mod image; use std::{println, format}; use crate::perlin::Perlin; use crate::vec3::{Vec3,Point3, Color}; use crate::image::Image; fn hex_color(string: &str) -> Color { Color { x: i64::from_str_radix(&string[0..2], 16).unwrap() as f64 / 255.0, y: i64::from_str_radix(&string[2..4], 16).unwrap() as f64 / 255.0, z: i64::from_str_radix(&string[4..6], 16).unwrap() as f64 / 255.0, } } // maps [0.0, 1.0] -> Color[0.0, 1.0] trait Palette { fn sample(&self, index: f64) -> Color; } struct IdenPalette {} impl Palette for IdenPalette { fn sample(&self, index: f64) -> Color { Color{x: index, y: index, z: index} } } struct FirePalette {} impl Palette for FirePalette { fn sample(&self, index: f64) -> Color { Color { //x: index / 3.0, x: 0.46 - (index / 3.0), y: 1.0, z: ((index + 0.03) * 2.0).min(1.0), }.hsl_to_rgb() } } struct GradientPalette { start: Color, end: Color, } impl Palette for GradientPalette { fn sample(&self, index: f64) -> Color { Color { x: (index * self.start.x) + ((1.0 - index) * self.end.x), y: (index * self.start.y) + ((1.0 - index) * self.end.y), z: (index * self.start.z) + ((1.0 - index) * self.end.z), } } } // fn palette_func_pink(index: f64) -> Color { // Color { // x: 1.0 - (index / 3.0), // y: 1.0, // z: (index * 2.0).min(1.0), // }.hsl_to_rgb() // } // fn palette_func_quant(index: f64) -> Color { // Color { // x: (index * 8.0).round() / 8.0, // y: 1.0, // z: (index * 2.0).min(1.0), // }.hsl_to_rgb() // } fn sample(h: f64, l: f64) -> Color { let start_hue = 0.75; let end_hue = start_hue + 0.2; let lightness_scale = 0.5; Color { x: (h * (end_hue - start_hue)) + start_hue, y: 1.0, z: (l * lightness_scale) + (lightness_scale / 2.0), }.hsl_to_rgb() } // fn main() { // // params // let height = 512; // let width = 512; // let scale = 1.0; // let turb_depth = 20; // let dsw_factor = 1.5; // //let palette = GradientPalette{start: hex_color("0000ff"), end: hex_color("ff0000")}; // //let palette = IdenPalette{}; // let palette = FirePalette{}; // let hue_perlin = Perlin::new(); // //let light_perlin = Perlin::new(); // let mut image = Image::new(width, height); // for x in 0..width { // for y in 0..height { // let hue_noise = hue_perlin.turb_dsw(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: 0.0}, turb_depth, dsw_factor); // //let light_noise = light_perlin.turb_dsw(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: 0.0}, 7); // //image.set(x, y, &sample(hue_noise, light_noise)).unwrap(); // //image.set(x, y, &Color{x: hue_noise, y: hue_noise, z: hue_noise}).unwrap(); // image.set(x, y, &palette.sample(hue_noise)).unwrap(); // } // } // image.write(&mut std::io::stdout()); // } fn main() { // params let height = 512; let width = 512; let frames = 600; let scale = 1.0; let turb_depth = 20; let dsw_factor = 1.5; let palette = FirePalette{}; let hue_perlin = Perlin::new(); let mut image = Image::new(width, height); for f in 0..frames { for x in 0..width { for y in 0..height { let hue_noise = hue_perlin.turb_dsw(&Point3{x: (x as f64 / width as f64) * scale, y: (y as f64 / height as f64) * scale, z: (f as f64 / frames as f64) * scale}, turb_depth, dsw_factor); image.set(x, y, &palette.sample(hue_noise)).unwrap(); } } let path = format!("./anim/{}.ppm", f); image.write(&mut std::fs::File::create(path).unwrap()); println!("Finished frame {} of {}!", f, frames); } }