diff --git a/rtiow/src/output.rs b/rtiow/src/output.rs index d4f9a61..012c73e 100644 --- a/rtiow/src/output.rs +++ b/rtiow/src/output.rs @@ -9,6 +9,7 @@ use image; use lazy_static::lazy_static; use log::info; +use crate::renderer::Scene; use crate::vec3::Vec3; // Main RGB image output from rendering the scene. @@ -35,8 +36,9 @@ struct ImageMetadata { } #[derive(Serialize)] #[serde(rename_all = "camelCase")] -struct Data { +struct Data<'s> { timestamp: i64, + scene: &'s Scene, image_metadata: Vec, } @@ -113,7 +115,7 @@ trait ImageSaver { Q: AsRef + Sized; } -pub fn write_images>(output_dir: P) -> std::io::Result<()> { +pub fn write_images>(scene: &Scene, output_dir: P) -> std::io::Result<()> { let output_dir: &Path = output_dir.as_ref(); let debugger = DEBUGGER.lock().unwrap(); let now = Local::now(); @@ -202,6 +204,7 @@ pub fn write_images>(output_dir: P) -> std::io::Result<()> { f, &Data { timestamp: now.timestamp(), + scene, image_metadata, }, )?; diff --git a/rtiow/src/renderer.rs b/rtiow/src/renderer.rs index 45ccb93..21e3151 100644 --- a/rtiow/src/renderer.rs +++ b/rtiow/src/renderer.rs @@ -32,31 +32,33 @@ use crate::vec3::Vec3; #[derive(Debug)] pub enum Model { + BVH, Bench, Book, - Tutorial, - BVH, - Test, CornellBox, CornellSmoke, - PerlinDebug, Final, Mandelbrot, + PerlinDebug, + Spheramid, + Test, + Tutorial, } impl Model { pub fn scene(&self, opt: &Opt) -> Scene { match self { - Model::Book => scenes::book::new(&opt), - Model::Bench => scenes::bench::new(&opt), - Model::Tutorial => scenes::tutorial::new(&opt), Model::BVH => scenes::bvh::new(&opt), - Model::Test => scenes::test::new(&opt), + Model::Bench => scenes::bench::new(&opt), + Model::Book => scenes::book::new(&opt), Model::CornellBox => scenes::cornell_box::new(&opt), Model::CornellSmoke => scenes::cornell_smoke::new(&opt), - Model::PerlinDebug => scenes::perlin_debug::new(&opt), Model::Final => scenes::final_scene::new(&opt), Model::Mandelbrot => scenes::mandelbrot::new(&opt), + Model::PerlinDebug => scenes::perlin_debug::new(&opt), + Model::Spheramid => scenes::spheramid::new(&opt), + Model::Test => scenes::test::new(&opt), + Model::Tutorial => scenes::tutorial::new(&opt), } } } @@ -76,14 +78,15 @@ impl str::FromStr for Model { match s { "bench" => Ok(Model::Bench), "book" => Ok(Model::Book), - "tutorial" => Ok(Model::Tutorial), "bvh" => Ok(Model::BVH), - "test" => Ok(Model::Test), "cornell_box" => Ok(Model::CornellBox), "cornell_smoke" => Ok(Model::CornellSmoke), - "perlin_debug" => Ok(Model::PerlinDebug), "final" => Ok(Model::Final), "mandelbrot" => Ok(Model::Mandelbrot), + "perlin_debug" => Ok(Model::PerlinDebug), + "spheramid" => Ok(Model::Spheramid), + "test" => Ok(Model::Test), + "tutorial" => Ok(Model::Tutorial), _ => Err(ModelParseError(s.to_owned())), } } @@ -92,16 +95,17 @@ impl str::FromStr for Model { impl std::string::ToString for Model { fn to_string(&self) -> String { match self { + Model::BVH => "bvh".to_string(), Model::Bench => "bench".to_string(), Model::Book => "book".to_string(), - Model::Tutorial => "tutorial".to_string(), - Model::BVH => "bvh".to_string(), - Model::Test => "test".to_string(), Model::CornellBox => "cornell_box".to_string(), Model::CornellSmoke => "cornell_smoke".to_string(), - Model::PerlinDebug => "perlin_debug".to_string(), Model::Final => "final".to_string(), Model::Mandelbrot => "mandelbrot".to_string(), + Model::PerlinDebug => "perlin_debug".to_string(), + Model::Spheramid => "spheramid".to_string(), + Model::Test => "test".to_string(), + Model::Tutorial => "tutorial".to_string(), } } } @@ -151,8 +155,13 @@ pub fn opt_hash(opt: &Opt) -> String { ) } +// TODO(wathiede): implement the skips and then the renderer could use json as an input file type. +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] pub struct Scene { + #[serde(skip)] pub world: Box, + #[serde(skip)] pub camera: Camera, pub subsamples: usize, /// overrides subsamples setting. @@ -161,6 +170,7 @@ pub struct Scene { pub width: usize, pub height: usize, pub global_illumination: bool, + #[serde(skip)] pub env_map: Option, } @@ -631,5 +641,5 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i progress(&Default::default(), ¤t_stat, time_diff, pixel_total) ); - output::write_images(output_dir) + output::write_images(&scene, output_dir) } diff --git a/rtiow/src/scenes/mod.rs b/rtiow/src/scenes/mod.rs index 13fea3b..deab28d 100644 --- a/rtiow/src/scenes/mod.rs +++ b/rtiow/src/scenes/mod.rs @@ -6,5 +6,6 @@ pub mod cornell_smoke; pub mod final_scene; pub mod mandelbrot; pub mod perlin_debug; +pub mod spheramid; pub mod test; pub mod tutorial; diff --git a/rtiow/src/scenes/spheramid.rs b/rtiow/src/scenes/spheramid.rs new file mode 100644 index 0000000..3c145b1 --- /dev/null +++ b/rtiow/src/scenes/spheramid.rs @@ -0,0 +1,88 @@ +use crate::camera::Camera; +use crate::hitable::Hit; +use crate::hitable_list::HitableList; +use crate::kdtree::KDTree; +use crate::material::Dielectric; +use crate::material::Lambertian; +use crate::material::Metal; +use crate::moving_sphere::MovingSphere; +use crate::renderer::Opt; +use crate::renderer::Scene; +use crate::sphere::Sphere; +use crate::texture::CheckerTexture; +use crate::texture::ConstantTexture; +use crate::texture::Texture; +use crate::vec3::Vec3; + +pub fn new(opt: &Opt) -> Scene { + let lookfrom = Vec3::new(3., 4., 2.); + let lookat = Vec3::new(0., 0., -1.); + let dist_to_focus = (lookfrom - lookat).length(); + let aperture = 0.1; + let time_min = 0.; + let time_max = 0.; + let camera = Camera::new( + lookfrom, + lookat, + Vec3::new(0., 1., 0.), + 45., + opt.width as f32 / opt.height as f32, + aperture, + dist_to_focus, + time_min, + time_max, + ); + let ground_color: Box = if opt.use_accel { + Box::new(CheckerTexture::new( + ConstantTexture::new([0., 0., 0.]), + ConstantTexture::new([1.0, 0.4, 0.4]), + )) + } else { + Box::new(ConstantTexture::new(Vec3::new(0.4, 1.0, 0.4))) + }; + + let objects: Vec> = vec![ + //let world: Box = Box::new(HitableList::new(vec![ + Box::new(Sphere::new([1., 0.5, 1.], 0.5, Dielectric::new(1.5))), + Box::new(Sphere::new( + Vec3::new(0., 0., -1.), + 0.5, + Lambertian::new(ConstantTexture::new(Vec3::new(0.1, 0.2, 0.5))), + )), + Box::new(Sphere::new( + Vec3::new(0., -1000.5, -1.), + 1000., + Lambertian::new(ground_color), + )), + Box::new(Sphere::new( + Vec3::new(1., 0., -1.), + 0.5, + Metal::new(Vec3::new(0.8, 0.6, 0.2), 0.2), + )), + Box::new(MovingSphere::new( + Vec3::new(-1., 0., -1.25), + Vec3::new(-1., 0., -0.75), + 0.5, + 0., + 1., + Lambertian::new(ConstantTexture::new(Vec3::new(0.2, 0.8, 0.2))), + )), + ]; + let world: Box = if opt.use_accel { + Box::new(KDTree::new(objects, time_min, time_max)) + } else { + Box::new(HitableList::new(objects)) + }; + Scene { + camera, + world, + subsamples: opt.subsamples, + adaptive_subsampling: None, + // adaptive_subsampling: Some(0.5), + num_threads: opt.num_threads, + width: opt.width, + height: opt.height, + global_illumination: true, + ..Default::default() + } +} diff --git a/rtiow/src/scenes/tutorial.rs b/rtiow/src/scenes/tutorial.rs index 2c172e6..3c145b1 100644 --- a/rtiow/src/scenes/tutorial.rs +++ b/rtiow/src/scenes/tutorial.rs @@ -15,7 +15,7 @@ use crate::texture::Texture; use crate::vec3::Vec3; pub fn new(opt: &Opt) -> Scene { - let lookfrom = Vec3::new(3., 2., 2.); + let lookfrom = Vec3::new(3., 4., 2.); let lookat = Vec3::new(0., 0., -1.); let dist_to_focus = (lookfrom - lookat).length(); let aperture = 0.1;