From f19c8cc40c5caf8abb4f04aaf9f91ec3a8c1ccbc Mon Sep 17 00:00:00 2001 From: Sakarias Johansson Date: Mon, 13 Mar 2023 22:00:44 +0100 Subject: =?UTF-8?q?=F0=9F=93=B8=20Add=20Camera=20defocus=20blur=20+=20Othe?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just wanted to add defocus blur but ended up changing a bunch of other this as well. - Moved scenes to a separate folder. - Updated readme with more pretty images. - Add interface for loading scenes. There is currently one for yaml and another if you want a slightly random scene. - Add image action to decide what to do with the final image once its rendered. Currently supports just showing the buffer until you press the render buffer again and saving the image as `png`. - When you use nix shell you will be dropped in the proper folder so you can just do cargo build etc without having to do `cd`. --- racer-tracer/src/main.rs | 76 +++++++++--------------------------------------- 1 file changed, 14 insertions(+), 62 deletions(-) (limited to 'racer-tracer/src/main.rs') diff --git a/racer-tracer/src/main.rs b/racer-tracer/src/main.rs index 5612649..6648c81 100644 --- a/racer-tracer/src/main.rs +++ b/racer-tracer/src/main.rs @@ -4,6 +4,7 @@ mod camera; mod config; mod geometry; mod image; +mod image_action; mod material; mod ray; mod render; @@ -15,14 +16,13 @@ extern crate image as img; use std::{ convert::TryFrom, - path::PathBuf, sync::RwLock, time::{Duration, Instant}, vec::Vec, }; +use image_action::ImageAction; use minifb::{Key, Window, WindowOptions}; -use sha2::{Digest, Sha256}; use synchronoise::SignalEvent; use crate::vec3::Vec3; @@ -38,18 +38,19 @@ use crate::{ fn run(config: Config) -> Result<(), TracerError> { let image = image::Image::new(config.screen.width, config.screen.height); let screen_buffer: RwLock> = RwLock::new(vec![0; image.width * image.height]); + let look_from = Vec3::new(13.0, 2.0, 3.0); + let look_at = Vec3::new(0.0, 0.0, 0.0); let camera = RwLock::new(Camera::new( - Vec3::new(-2.0, 2.0, 1.0), - Vec3::new(0.0, 0.0, -1.0), + look_from, + look_at, Vec3::new(0.0, 1.0, 0.0), - 90.0, + 20.0, &image, - 1.0, + 0.1, + 10.0, )); - let scene: Scene = config - .scene - .ok_or(TracerError::NoScene()) - .and_then(Scene::from_file)?; + + let scene = Scene::try_new((&config.loader).into())?; let mut window_res: Result<(), TracerError> = Ok(()); let mut render_res: Result<(), TracerError> = Ok(()); @@ -58,6 +59,8 @@ fn run(config: Config) -> Result<(), TracerError> { let cancel_render = SignalEvent::manual(false); let exit = SignalEvent::manual(false); + let image_action: Box = (&config.image_action).into(); + rayon::scope(|s| { s.spawn(|_| { while render_res.is_ok() { @@ -94,62 +97,11 @@ fn run(config: Config) -> Result<(), TracerError> { ) .and_then(|_| { render_image.reset(); - println!( "It took {} seconds to render the image.", Instant::now().duration_since(render_time).as_secs() ); - screen_buffer - .read() - .map_err(|e| { - TracerError::FailedToAcquireLock(e.to_string()) - }) - .map(|buf| { - // Convert ARGB8 to RGBA8 - buf.iter() - .map(|v| { - let a: u32 = (v >> 24) & 0xff; - let r: u32 = (v >> 16) & 0xff; - let g: u32 = (v >> 8) & 0xff; - let b: u32 = v & 0xff; - - (r << 24) | (g << 16) | (b << 8) | a - }) - .flat_map(|val| val.to_be_bytes()) - .collect::>() - }) - }) - .and_then(|buf| { - match &config.image_output_dir { - Some(image_dir) => { - println!("Saving image..."); - let mut sha = Sha256::new(); - - sha.update(buf.as_slice()); - - let mut file_path = PathBuf::from(image_dir); - file_path.push(format!("{:X}.png", sha.finalize())); - - img::save_buffer( - file_path.as_path(), - buf.as_slice(), - config.screen.width as u32, - config.screen.height as u32, - img::ColorType::Rgba8, - ) - .map_err(|e| { - let error = e.to_string(); - TracerError::ImageSave(error) - }) - .map(|_| { - println!( - "Saved image to: {}", - file_path.to_string_lossy() - ); - }) - } - None => Ok(()), - } + image_action.action(&screen_buffer, &render_image, &config) }) }, ) -- cgit v1.2.3