diff --git a/src/color.rs b/src/color.rs index acd4315..296eff6 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,16 +1,4 @@ use super::{utility, Color, Rgb, RgbImage}; -use std::io::Write; - -pub fn write_color(out: &mut impl Write, pixel_color: &Color) { - write!( - out, - "{} {} {}\n", - (255.999 * pixel_color.x()) as u32, - (255.999 * pixel_color.y()) as u32, - (255.999 * pixel_color.z()) as u32 - ) - .unwrap(); -} pub fn put_color(img: &mut RgbImage, pixel_color: &Color, x: u32, y: u32, samples_per_pixel: u32) { let mut r = pixel_color.x(); @@ -18,9 +6,9 @@ pub fn put_color(img: &mut RgbImage, pixel_color: &Color, x: u32, y: u32, sample let mut b = pixel_color.z(); let scale = 1.0 / samples_per_pixel as f64; - r = (scale*r).sqrt(); - g = (scale*g).sqrt(); - b = (scale*b).sqrt(); + r = (scale * r).sqrt(); + g = (scale * g).sqrt(); + b = (scale * b).sqrt(); img.put_pixel( x, diff --git a/src/hittable.rs b/src/hittable.rs index 708f514..07712ea 100644 --- a/src/hittable.rs +++ b/src/hittable.rs @@ -14,7 +14,7 @@ pub struct Sphere { radius: f64, } -pub trait Hittable: Sync+Send { +pub trait Hittable: Sync + Send { fn hit(&self, r: &Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool; } diff --git a/src/hittable_list.rs b/src/hittable_list.rs index 6a877f8..ebbbcc9 100644 --- a/src/hittable_list.rs +++ b/src/hittable_list.rs @@ -13,9 +13,11 @@ impl HittableList { } } + /* pub fn clear(&mut self) { self.objects.clear(); } + */ pub fn add(&mut self, obj: Box) { self.objects.push(obj); diff --git a/src/main.rs b/src/main.rs index 769c145..2fb40dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,29 +8,27 @@ mod ray; mod utility; mod vec3; -use std::env; -use std::sync::atomic::AtomicU32; -//use std::fs::File; -//use std::io::BufWriter; -//use std::io::Write; use camera::Camera; use hittable::{HitRecord, Hittable, Sphere}; use hittable_list::HittableList; use image::{Rgb, RgbImage}; use ray::Ray; -use vec3::{Color, Point3, Vec3}; use rayon::prelude::*; +use std::env; +use std::sync::atomic::{AtomicU32, Ordering}; +use std::sync::Arc; +use vec3::{Color, Point3, Vec3}; fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color { let mut rec = HitRecord::empty(); if depth <= 0 { - return Color::new(0.0,0.0,0.0); + return Color::new(0.0, 0.0, 0.0); } if world.hit(r, 0.0, f64::INFINITY, &mut rec) { let target = rec.p + rec.normal + Vec3::random_unit_vector(); // rec.p + rec.normal.random_in_hemisphere(); - return 0.5 * ray_color(&Ray::new(rec.p, target - rec.p), world, depth-1); + return 0.5 * ray_color(&Ray::new(rec.p, target - rec.p), world, depth - 1); } let unit_direction = r.direction(); let t = 0.5 * (unit_direction.y() + 1.0); @@ -74,7 +72,7 @@ fn main() { /* for i in -15..15 { for j in -15..15 { - world.add(Box::::new(Sphere::new(Point3::new(j as f64/6.0 as f64, i as f64/6.0 as f64, -1.5), 0.05))); + world.add(Box::::new(Sphere::new(Point3::new(j as f64/5.0 as f64, i as f64/5.0 as f64, -1.5), 0.08))); } } */ @@ -90,31 +88,32 @@ fn main() { let mut image = RgbImage::new(image_width, image_height); - //let mut file = BufWriter::new(File::create(default_file).unwrap()); - //writeln!(&mut file, "P3\n{image_width} {image_height}\n255\n").unwrap(); + let atomic_counter = Arc::new(AtomicU32::new(0)); + let color_lines: Vec<_> = (0..image_height) + .into_par_iter() + .rev() + .map(|j| { + let v = atomic_counter.fetch_add(1, Ordering::Relaxed); + eprint!("\rScanlines remaining: {:5}", image_height - v); - let mut atomic_counter = AtomicU32::new(image_height); - let color_lines: Vec<_> = (0..image_height).into_par_iter().rev().map(|j| { - eprint!("\rScanlines remaining: {:5}", *atomic_counter.get_mut()); - let mut colors = Vec::new(); - for i in 0..image_width { - let mut pixel_color = Color::new(0.0, 0.0, 0.0); - for _ in 0..samples_per_pixel { - let u = (i as f64 + utility::random_f64()) / (image_width - 1) as f64; - let v = (j as f64 + utility::random_f64()) / (image_height - 1) as f64; - let r = cam.get_ray(u, v); - pixel_color += ray_color(&r, &world, max_depth); + let mut colors = Vec::new(); + for i in 0..image_width { + let mut pixel_color = Color::new(0.0, 0.0, 0.0); + for _ in 0..samples_per_pixel { + let u = (i as f64 + utility::random_f64()) / (image_width - 1) as f64; + let v = (j as f64 + utility::random_f64()) / (image_height - 1) as f64; + let r = cam.get_ray(u, v); + pixel_color += ray_color(&r, &world, max_depth); + } + colors.push(pixel_color); } - colors.push(pixel_color); - } - *atomic_counter.get_mut() -= 1; - - return colors; - } ).collect(); + return colors; + }) + .collect(); + eprint!("\rScanlines remaining: {:5}", 0); (0..image_height).into_iter().rev().for_each(|j| { (0..image_width).into_iter().for_each(|i| { - //color::write_color(&mut file, &pixel_color); color::put_color( &mut image, &color_lines[(image_height - j - 1) as usize][i as usize], diff --git a/src/vec3.rs b/src/vec3.rs index 67c3c86..dde0d13 100644 --- a/src/vec3.rs +++ b/src/vec3.rs @@ -1,5 +1,5 @@ -use std::ops::*; use super::utility; +use std::ops::*; #[derive(Clone, Copy, Debug)] pub struct Vec3 { @@ -39,17 +39,27 @@ impl Vec3 { } pub fn random_f64() -> Vec3 { - Vec3::new(utility::random_f64(),utility::random_f64(),utility::random_f64()) + Vec3::new( + utility::random_f64(), + utility::random_f64(), + utility::random_f64(), + ) } pub fn random_rng(min: f64, max: f64) -> Self { - Self::new(utility::random_rng(min,max), utility::random_rng(min,max), utility::random_rng(min,max)) + Self::new( + utility::random_rng(min, max), + utility::random_rng(min, max), + utility::random_rng(min, max), + ) } pub fn random_in_unit_sphere() -> Self { loop { let p = Vec3::random_rng(-1.0, 1.0); - if p.length_squared() >= 1.0 { continue }; + if p.length_squared() >= 1.0 { + continue; + }; return p; } } @@ -63,7 +73,7 @@ impl Vec3 { if Self::dot(in_unit_sphere, *self) > 0.0 { return in_unit_sphere; } else { - return -1.0*in_unit_sphere; + return -1.0 * in_unit_sphere; } }