diff --git a/Cargo.lock b/Cargo.lock index 05494a1..ffbe2c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3334,12 +3334,15 @@ dependencies = [ [[package]] name = "ray-tracer" version = "0.1.0" +dependencies = [ + "rayon", +] [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3347,9 +3350,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", diff --git a/ray-tracer/Cargo.toml b/ray-tracer/Cargo.toml index bdd6b82..a973b97 100644 --- a/ray-tracer/Cargo.toml +++ b/ray-tracer/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +rayon = "1.10.0" [[bin]] name = "projectile" diff --git a/ray-tracer/src/bin/sphere.rs b/ray-tracer/src/bin/sphere.rs new file mode 100644 index 0000000..3fef19e --- /dev/null +++ b/ray-tracer/src/bin/sphere.rs @@ -0,0 +1,40 @@ +use ray_tracer::{transforms::*, types::*, PPM}; +use rayon::prelude::*; +use std::{fs::File, io::Write, sync::{Arc, RwLock}}; + +const SIZE: usize = 1000; + +fn main() { + let canvas = Arc::new(RwLock::new(Canvas::new(SIZE, SIZE))); + let mut sphere = Sphere::default(); + sphere.set_transformation(shearing(1., 0., 0., 0., 0., 0.)); + + let camera = Point::new(0., 1., -5.); + let wall_z = 10.; + let wall_size = 7.; + let half = wall_size / 2.; + + let pixel_size = wall_size / SIZE as f64; + + (0..SIZE).into_par_iter().for_each(|x| { + (0..SIZE).into_par_iter().for_each(|y| { + let wall_x = -half + pixel_size * x as f64; + let wall_y = half - pixel_size * y as f64; + + let ray = Ray::new( + camera.clone(), + Vector::new(wall_x, wall_y, wall_z).normalize(), + ); + let xs = ray.intersect(&sphere); + if xs.hit().is_some() { + *canvas.write().unwrap().pixel_mut(x, y) = Color::new(0., 0., 1.); + } + }); + }); + + let canvas = canvas.read().unwrap(); + + let ppm = PPM::from(&*canvas); + let mut file = File::create("sphere.ppm").unwrap(); + let _ = file.write(ppm.as_bytes()); +} diff --git a/ray-tracer/src/ppm.rs b/ray-tracer/src/ppm.rs index ee45f57..575d43a 100644 --- a/ray-tracer/src/ppm.rs +++ b/ray-tracer/src/ppm.rs @@ -29,8 +29,8 @@ fn join_to_line_limit(data: impl IntoIterator) -> Vec { #[derive(Debug)] pub struct PPM(String); -impl From for PPM { - fn from(c: Canvas) -> Self { +impl From<&Canvas> for PPM { + fn from(c: &Canvas) -> Self { // let v = vec![0.; c.width() * c.height() * 3]; let header = format!("P3\n{} {}\n255\n", c.width(), c.height()); @@ -68,7 +68,7 @@ mod tests { #[test] fn construct_ppm_header() { let c = Canvas::new(5, 3); - let ppm = PPM::from(c); + let ppm = PPM::from(&c); assert!(ppm.starts_with( "P3\n\