Skip to content

Commit

Permalink
Chap 16: CSG
Browse files Browse the repository at this point in the history
(threads)
  • Loading branch information
fremag committed Mar 24, 2024
1 parent 2336826 commit ee744a3
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 5 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified img/menger_castle_scene.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion ray-tracer-cli/src/scenes/menger_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl Scene for MengerCastleScene {
floor.set_material(material_floor.clone());
world.objects.push(floor);

let menger_sponge = MengerSponge::new(3);
let menger_sponge = MengerSponge::new(4);
let mut cube = build_cube();
cube.set_transformation(&scaling(2.0, 1.0, 2.0) * &translation(0.0, 1.0, 0.0));

Expand Down
3 changes: 2 additions & 1 deletion ray-tracer-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ edition = "2021"
sorted-vec = "0.8.3"
rand = { version = "0.8.5", features = [] }
png = { version = "0.17.11", features = [] }
thousands = {version = "0.2.0"}
thousands = {version = "0.2.0"}
rayon = { version = "1.9.0"}
76 changes: 75 additions & 1 deletion ray-tracer-lib/src/camera.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use io::stdout;
use std::io;
use std::io::Write;
use std::sync::atomic::Ordering;
use std::sync::atomic::{AtomicUsize, Ordering};
use rayon::prelude::*;
use crate::canvas::Canvas;
use crate::core::math::Float;
use crate::core::matrix::Matrix;
Expand All @@ -10,6 +11,9 @@ use crate::core::tuple::point;
use crate::object::{INTERSECTION_COUNTER, OBJECT_COUNTER};
use crate::world::World;
use thousands::Separable;
use crate::colors::Color;
use std::time::{Instant};
use std::sync::{Arc, Mutex};

pub struct Camera {
pub h_size: usize,
Expand All @@ -22,6 +26,20 @@ pub struct Camera {
pub inverse_transform: Matrix<4>,
}

pub struct Pixel {
x : usize,
y : usize,
color : Color,
}

pub struct Block {
x_min : usize,
x_max : usize,
y_min : usize,
y_max : usize,
pixels : Vec<Pixel>
}

impl Camera {
pub fn new(h_size: usize, v_size: usize, field_of_view: Float) -> Camera {
let half_view = (field_of_view / 2.0).tan() as Float;
Expand Down Expand Up @@ -67,6 +85,62 @@ impl Camera {
}

pub fn render(&self, world: &World, file_path: &str) -> Canvas {
let mut blocks: Vec<Block> = vec![];
let n = 20;
let nx = self.v_size / n;
let ny = self.h_size / n;

for i in 0..nx {
for j in 0..ny {
let block = Block {
x_min: usize::min(i * n, self.v_size-1),
x_max: usize::min((i+1) * n, self.v_size-1),
y_min: usize::min(j * n, self.h_size-1),
y_max: usize::min((j+1) * n, self.h_size-1),
pixels: vec![],
};
blocks.push(block);
}
}

let num_block = AtomicUsize::new(0);
let num_pixel = AtomicUsize::new(0);
let nb_objects = OBJECT_COUNTER.load(Ordering::Relaxed).separate_with_commas();
let start = Arc::new(Mutex::new(Instant::now()));

let mut image = Canvas::new(self.h_size, self.v_size);
blocks.par_iter_mut().for_each(|block| {
num_block.fetch_add(1, Ordering::SeqCst);
for x in block.x_min..block.x_max {
for y in block.y_min..block.y_max {
let ray = self.ray_for_pixel(x, y);
let color = world.color_at(&ray, 5);
let pixel = Pixel { x, y, color };
block.pixels.push(pixel);
let nb_pixels = num_pixel.fetch_add(1, Ordering::SeqCst);
let mut guard = start.lock().unwrap();
let t = guard.elapsed().as_secs();
if t > 1 {
let pct= nb_pixels as f32 / (self.v_size*self.h_size) as f32 * 100.0;
print!("\r{:3.2} % - {} / {} - {} - {} inters - {} Objs, {}", pct, nb_pixels, self.v_size*self.h_size, file_path, INTERSECTION_COUNTER.load(Ordering::Relaxed).separate_with_commas(), OBJECT_COUNTER.load(Ordering::Relaxed).separate_with_commas(), nb_objects);
let _ = stdout().flush();
*guard = Instant::now();
}
}
}
});

for block in blocks.iter() {
for pixel in block.pixels.iter() {
image.write_pixel(pixel.x, pixel.y, pixel.color);
}
}

println!();
image
}

pub fn _render(&self, world: &World, file_path: &str) -> Canvas {
let mut image = Canvas::new(self.h_size, self.v_size);
let nb_objects = OBJECT_COUNTER.load(Ordering::Relaxed).separate_with_commas();

Expand Down

0 comments on commit ee744a3

Please sign in to comment.