From 5d57304d95f238d463133ade9cf2894e1cb9530c Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sun, 18 Jul 2021 16:55:29 -0700 Subject: [PATCH] eoc8: implement the end of chapter 8 challenge. Note: This implementation looks like crap and I'm not sure why. --- rtchallenge/examples/eoc8.rs | 107 +++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 rtchallenge/examples/eoc8.rs diff --git a/rtchallenge/examples/eoc8.rs b/rtchallenge/examples/eoc8.rs new file mode 100644 index 0000000..1749eeb --- /dev/null +++ b/rtchallenge/examples/eoc8.rs @@ -0,0 +1,107 @@ +use std::{f32::consts::PI, time::Instant}; + +use anyhow::Result; +use structopt::StructOpt; + +use rtchallenge::{ + camera::{Camera, RenderStrategy}, + lights::PointLight, + materials::Material, + matrices::Matrix4x4, + spheres::Sphere, + transformations::view_transform, + tuples::{Color, Tuple}, + world::World, + WHITE, +}; + +/// End of chapter 8 challenge. +#[derive(StructOpt, Debug)] +#[structopt(name = "eoc8")] +struct Opt { + #[structopt(long, default_value = "rayon")] + render_strategy: RenderStrategy, +} + +fn main() -> Result<()> { + let start = Instant::now(); + let opt = Opt::from_args(); + let width = 2560; + let height = 1440; + let light_position = Tuple::point(-10., 10., -10.); + let light_color = WHITE; + let light = PointLight::new(light_position, light_color); + let mut camera = Camera::new(width, height, PI / 4.); + let from = Tuple::point(0., 1.5, -5.); + let to = Tuple::point(0., 1., 0.); + let up = Tuple::point(0., 1., 0.); + camera.set_transform(view_transform(from, to, up)); + camera.render_strategy = opt.render_strategy; + + let mut floor = Sphere::default(); + floor.set_transform(Matrix4x4::scaling(10., 0.01, 10.)); + floor.material = Material { + color: Color::new(1., 0.9, 0.9), + specular: 0., + ..Material::default() + }; + + let mut left_wall = Sphere::default(); + left_wall.set_transform( + Matrix4x4::translation(0., 0., 5.) + * Matrix4x4::rotation_y(-PI / 4.) + * Matrix4x4::rotation_x(PI / 2.) + * Matrix4x4::scaling(10., 0.01, 10.), + ); + left_wall.material = floor.material.clone(); + + let mut right_wall = Sphere::default(); + right_wall.set_transform( + Matrix4x4::translation(0., 0., 5.) + * Matrix4x4::rotation_y(PI / 4.) + * Matrix4x4::rotation_x(PI / 2.) + * Matrix4x4::scaling(10., 0.00001, 10.), + ); + right_wall.material = floor.material.clone(); + + let mut middle = Sphere::default(); + middle.set_transform(Matrix4x4::translation(-0.5, 1., 0.5)); + middle.material = Material { + color: Color::new(0.1, 1., 0.5), + diffuse: 0.7, + specular: 0.3, + ..Material::default() + }; + + let mut right = Sphere::default(); + right.set_transform(Matrix4x4::translation(1.5, 0.5, -0.5) * Matrix4x4::scaling(0.5, 0.5, 0.5)); + right.material = Material { + color: Color::new(0.5, 1., 0.1), + diffuse: 0.7, + specular: 0.3, + ..Material::default() + }; + + let mut left = Sphere::default(); + left.set_transform( + Matrix4x4::translation(-1.5, 0.33, -0.75) * Matrix4x4::scaling(0.33, 0.33, 0.33), + ); + left.material = Material { + color: Color::new(1., 0.8, 0.1), + diffuse: 0.7, + specular: 0.3, + ..Material::default() + }; + + let mut world = World::default(); + world.light = Some(light); + world.objects = vec![floor, left_wall, right_wall, middle, right, left]; + + let image = camera.render(&world); + + let path = "/tmp/eoc8.png"; + println!("saving output to {}", path); + image.write_to_file(path)?; + println!("Render time {:.3} seconds", start.elapsed().as_secs_f32()); + Ok(()) +}