Working multithreadding with Counter
This commit is contained in:
parent
ac4eca7e95
commit
47158af5ee
5 changed files with 49 additions and 50 deletions
18
src/color.rs
18
src/color.rs
|
@ -1,16 +1,4 @@
|
||||||
use super::{utility, Color, Rgb, RgbImage};
|
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) {
|
pub fn put_color(img: &mut RgbImage, pixel_color: &Color, x: u32, y: u32, samples_per_pixel: u32) {
|
||||||
let mut r = pixel_color.x();
|
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 mut b = pixel_color.z();
|
||||||
|
|
||||||
let scale = 1.0 / samples_per_pixel as f64;
|
let scale = 1.0 / samples_per_pixel as f64;
|
||||||
r = (scale*r).sqrt();
|
r = (scale * r).sqrt();
|
||||||
g = (scale*g).sqrt();
|
g = (scale * g).sqrt();
|
||||||
b = (scale*b).sqrt();
|
b = (scale * b).sqrt();
|
||||||
|
|
||||||
img.put_pixel(
|
img.put_pixel(
|
||||||
x,
|
x,
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub struct Sphere {
|
||||||
radius: f64,
|
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;
|
fn hit(&self, r: &Ray, t_min: f64, t_max: f64, rec: &mut HitRecord) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,11 @@ impl HittableList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.objects.clear();
|
self.objects.clear();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn add(&mut self, obj: Box<dyn Hittable>) {
|
pub fn add(&mut self, obj: Box<dyn Hittable>) {
|
||||||
self.objects.push(obj);
|
self.objects.push(obj);
|
||||||
|
|
57
src/main.rs
57
src/main.rs
|
@ -8,29 +8,27 @@ mod ray;
|
||||||
mod utility;
|
mod utility;
|
||||||
mod vec3;
|
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 camera::Camera;
|
||||||
use hittable::{HitRecord, Hittable, Sphere};
|
use hittable::{HitRecord, Hittable, Sphere};
|
||||||
use hittable_list::HittableList;
|
use hittable_list::HittableList;
|
||||||
use image::{Rgb, RgbImage};
|
use image::{Rgb, RgbImage};
|
||||||
use ray::Ray;
|
use ray::Ray;
|
||||||
use vec3::{Color, Point3, Vec3};
|
|
||||||
use rayon::prelude::*;
|
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 {
|
fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color {
|
||||||
let mut rec = HitRecord::empty();
|
let mut rec = HitRecord::empty();
|
||||||
|
|
||||||
if depth <= 0 {
|
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) {
|
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();
|
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 unit_direction = r.direction();
|
||||||
let t = 0.5 * (unit_direction.y() + 1.0);
|
let t = 0.5 * (unit_direction.y() + 1.0);
|
||||||
|
@ -74,7 +72,7 @@ fn main() {
|
||||||
/*
|
/*
|
||||||
for i in -15..15 {
|
for i in -15..15 {
|
||||||
for j in -15..15 {
|
for j in -15..15 {
|
||||||
world.add(Box::<Sphere>::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::<Sphere>::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 image = RgbImage::new(image_width, image_height);
|
||||||
|
|
||||||
//let mut file = BufWriter::new(File::create(default_file).unwrap());
|
let atomic_counter = Arc::new(AtomicU32::new(0));
|
||||||
//writeln!(&mut file, "P3\n{image_width} {image_height}\n255\n").unwrap();
|
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 mut colors = Vec::new();
|
||||||
let color_lines: Vec<_> = (0..image_height).into_par_iter().rev().map(|j| {
|
for i in 0..image_width {
|
||||||
eprint!("\rScanlines remaining: {:5}", *atomic_counter.get_mut());
|
let mut pixel_color = Color::new(0.0, 0.0, 0.0);
|
||||||
let mut colors = Vec::new();
|
for _ in 0..samples_per_pixel {
|
||||||
for i in 0..image_width {
|
let u = (i as f64 + utility::random_f64()) / (image_width - 1) as f64;
|
||||||
let mut pixel_color = Color::new(0.0, 0.0, 0.0);
|
let v = (j as f64 + utility::random_f64()) / (image_height - 1) as f64;
|
||||||
for _ in 0..samples_per_pixel {
|
let r = cam.get_ray(u, v);
|
||||||
let u = (i as f64 + utility::random_f64()) / (image_width - 1) as f64;
|
pixel_color += ray_color(&r, &world, max_depth);
|
||||||
let v = (j as f64 + utility::random_f64()) / (image_height - 1) as f64;
|
}
|
||||||
let r = cam.get_ray(u, v);
|
colors.push(pixel_color);
|
||||||
pixel_color += ray_color(&r, &world, max_depth);
|
|
||||||
}
|
}
|
||||||
colors.push(pixel_color);
|
return colors;
|
||||||
}
|
})
|
||||||
*atomic_counter.get_mut() -= 1;
|
.collect();
|
||||||
|
eprint!("\rScanlines remaining: {:5}", 0);
|
||||||
return colors;
|
|
||||||
} ).collect();
|
|
||||||
|
|
||||||
(0..image_height).into_iter().rev().for_each(|j| {
|
(0..image_height).into_iter().rev().for_each(|j| {
|
||||||
(0..image_width).into_iter().for_each(|i| {
|
(0..image_width).into_iter().for_each(|i| {
|
||||||
//color::write_color(&mut file, &pixel_color);
|
|
||||||
color::put_color(
|
color::put_color(
|
||||||
&mut image,
|
&mut image,
|
||||||
&color_lines[(image_height - j - 1) as usize][i as usize],
|
&color_lines[(image_height - j - 1) as usize][i as usize],
|
||||||
|
|
20
src/vec3.rs
20
src/vec3.rs
|
@ -1,5 +1,5 @@
|
||||||
use std::ops::*;
|
|
||||||
use super::utility;
|
use super::utility;
|
||||||
|
use std::ops::*;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Vec3 {
|
pub struct Vec3 {
|
||||||
|
@ -39,17 +39,27 @@ impl Vec3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn random_f64() -> 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 {
|
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 {
|
pub fn random_in_unit_sphere() -> Self {
|
||||||
loop {
|
loop {
|
||||||
let p = Vec3::random_rng(-1.0, 1.0);
|
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;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +73,7 @@ impl Vec3 {
|
||||||
if Self::dot(in_unit_sphere, *self) > 0.0 {
|
if Self::dot(in_unit_sphere, *self) > 0.0 {
|
||||||
return in_unit_sphere;
|
return in_unit_sphere;
|
||||||
} else {
|
} else {
|
||||||
return -1.0*in_unit_sphere;
|
return -1.0 * in_unit_sphere;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue