// Demo code (c) by SEGFAULT // // This code and all image 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 . // // The images produced by this code are of a likeness to original art (c) Micha Scott // All images generated by this program are (c) Micha Scott - All rights reserved. extern crate png; extern crate rand; extern crate rustic_zen; use std::fs::File; use std::io::BufWriter; use std::path::Path; use std::sync::Arc; use std::time; // To use encoder.set() use png::HasParameters; use rand::Rng; //Scene Parameters use rustic_zen::prelude::*; fn laser(angle: f64, wavelength: f64) -> Light { Light::new( (180.0, 80.0), 1.0, (2.0, 0.0), (360.0, 0.0), angle, wavelength, ) } fn main() { //Initialising scene! let now = time::Instant::now(); let width: f64 = 1920.0; let height: f64 = 1080.0; let rays = 1_000_000; //(width * height).round() as usize; let threads = 8; let wall_m = material::hqz_legacy(1.0, 0.0, 0.0); let floor_m = material::hqz_legacy(0.1, 0.3, 0.5); let top = Segment::line_from_points((0.0, 0.0), (width, 0.0), wall_m.clone()); let bottom = Segment::line_from_points((0.0, height), (width, height), wall_m.clone()); let left = Segment::line_from_points((0.0, 0.0), (0.0, height), wall_m.clone()); let right = Segment::line_from_points((width, 0.0), (width, height), wall_m.clone()); let floor = Segment::line_from_points( (0.0, height * 0.72), (width, ((height * 0.72) + 70.0, (height * 0.72) - 20.0)), floor_m, ); let r = Scene::new(width as usize, height as usize) .with_light(laser(30.0, 694.0)) .with_light(laser(31.0, 676.0)) .with_light(laser(32.0, 647.0)) .with_light(laser(33.0, 635.0)) .with_light(laser(34.0, 633.0)) .with_light(laser(35.0, 628.0)) .with_light(laser(36.0, 612.0)) .with_light(laser(37.0, 594.0)) .with_light(laser(38.0, 578.0)) .with_light(laser(39.0, 568.0)) .with_light(laser(40.0, 543.0)) .with_light(laser(41.0, 532.0)) .with_light(laser(42.0, 530.0)) .with_light(laser(43.0, 514.0)) .with_light(laser(44.0, 511.0)) .with_light(laser(45.0, 501.0)) .with_light(laser(46.0, 496.0)) .with_light(laser(47.0, 488.0)) .with_light(laser(48.0, 475.0)) .with_light(laser(49.0, 458.0)) .with_light(laser(50.0, 442.0)) .with_light(laser(51.0, 428.0)) .with_light(laser(52.0, 416.0)) .with_object(floor) .with_object(top) .with_object(bottom) .with_object(left) .with_object(right); let mut image = Arc::new(Image::new(width as usize, height as usize)); let setup = now.elapsed(); println!("Tracing {} rays, with {} threads!\n", rays, threads); let now = time::Instant::now(); let rays = r.render(rays, threads, &mut image); let tracing = now.elapsed(); //Downsampling Image! let now: time::Instant = time::Instant::now(); let data = image.to_rgba8(rays, 0.2, 1.0 / 2.2); //1.0/2.2 let downsampling = now.elapsed(); //Saving! let path = Path::new("laser-rainbow.png"); let file = File::create(path).unwrap(); let ref mut w = BufWriter::new(file); let mut encoder = png::Encoder::new(w, width as u32, height as u32); encoder.set(png::ColorType::RGBA).set(png::BitDepth::Eight); let mut writer = encoder.write_header().unwrap(); writer.write_image_data(&data).unwrap(); println!("\nTiming Summary:"); println!(" Setup: {}ms", setup.as_millis()); println!( " Tracing: {}ms ({}cpu ms)", tracing.as_millis(), tracing.as_millis() * threads as u128 ); println!(" Downsampling: {}ms\n", downsampling.as_millis()); println!( "{} rays in {}ms: {}rays/s", rays, tracing.as_millis(), rays as f32 / (tracing.as_millis() as f32 / 1000.0) ); }