diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 12 | ||||
-rw-r--r-- | src/render/coordinator.rs | 14 | ||||
-rw-r--r-- | src/sample/mod.rs | 2 | ||||
-rw-r--r-- | src/sample/uniform.rs | 6 | ||||
-rw-r--r-- | src/world/mod.rs | 8 |
5 files changed, 31 insertions, 11 deletions
diff --git a/src/main.rs b/src/main.rs index 215e0d4..0f6502e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use rendering::render::{RenderContext, RenderCoord}; use rendering::sample::UniformSampler; use rendering::material::{Reflectant, Lambertian}; -use std::rc::Rc; +use std::sync::Arc; fn main() { let res = Vector2i::new_xy(500, 500); @@ -21,9 +21,9 @@ fn main() { aperture: Some(20.0), }); - let brown = Rc::new(Lambertian::new(Spectrum::new_rgb(0.5, 0.3, 0.0))); - let blue = Rc::new(Lambertian::new(Spectrum::new_rgb(0.0, 0.3, 0.7))); - let metal = Rc::new(Reflectant::new(Spectrum::new_rgb(0.75, 0.75, 0.75), None)); + let brown = Arc::new(Lambertian::new(Spectrum::new_rgb(0.5, 0.3, 0.0))); + let blue = Arc::new(Lambertian::new(Spectrum::new_rgb(0.0, 0.3, 0.7))); + let metal = Arc::new(Reflectant::new(Spectrum::new_rgb(0.75, 0.75, 0.75), None)); let mut scn = Scene::new(); scn.add_objects(vec![ @@ -40,9 +40,9 @@ fn main() { let mut film = Film::new(res); { - let coord = RenderCoord::new(&mut film, Vector2i::new_xy(32, 32), 100); + let coord = RenderCoord::new(&mut film, Vector2i::new_xy(32, 32), 300); - coord.work(&ctx, &mut sampler); + coord.run_threaded(&ctx, &mut sampler, 8); } let image = film.finalize_image(); diff --git a/src/render/coordinator.rs b/src/render/coordinator.rs index a9a7d06..a8d8afb 100644 --- a/src/render/coordinator.rs +++ b/src/render/coordinator.rs @@ -7,7 +7,8 @@ use crate::camera::Film; use crate::core::{Bound2i, Vector2i}; use crate::sample::Sampler; -use std::sync::Mutex; +use std::sync::{Arc, Mutex}; +use std::thread; struct Tiler { tilesize: Vector2i, @@ -112,4 +113,15 @@ impl<'a> RenderCoord<'a> { self.finish_task(&task); } } + + pub fn run_threaded(&self, ctx: &RenderContext, sampler: &mut (dyn Sampler + Send), threads: u32) { + crossbeam::scope(|scope| { + for _ in 0..threads { + let mut sampler = sampler.clone_and_seed(); + scope.spawn(move |_| { + self.work(ctx, sampler.as_mut()); + }); + } + }).unwrap(); + } } diff --git a/src/sample/mod.rs b/src/sample/mod.rs index 88e1aa9..1a53921 100644 --- a/src/sample/mod.rs +++ b/src/sample/mod.rs @@ -16,6 +16,8 @@ pub trait Sampler { Vector2f::new_xy(self.get_sample(), self.get_sample()) } + fn clone_and_seed(&mut self) -> Box<dyn Sampler + Send>; + fn get_unit_vector(&mut self) -> Vector3f { let s2d = self.get_sample_2d(); diff --git a/src/sample/uniform.rs b/src/sample/uniform.rs index 2cd3156..c144f27 100644 --- a/src/sample/uniform.rs +++ b/src/sample/uniform.rs @@ -30,4 +30,10 @@ impl Sampler for UniformSampler { fn get_sample(&mut self) -> Float { self.d.sample(&mut self.r) } + + fn clone_and_seed(&mut self) -> Box<dyn Sampler + Send> { + let mut n = self.clone(); + n.r = Pcg32::seed_from_u64(self.r.next_u64()); + Box::new(n) + } } diff --git a/src/world/mod.rs b/src/world/mod.rs index ef239db..f0ba8d2 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -4,17 +4,17 @@ pub mod shapes; mod scene; pub use scene::*; -use std::rc::Rc; +use std::sync::Arc; use crate::core::Hittable; use crate::material::Material; pub struct Object { - pub shape: Box<dyn Hittable>, - pub mat: Rc<dyn Material>, + pub shape: Box<dyn Hittable + Sync>, + pub mat: Arc<dyn Material + Sync + Send>, } impl Object { - pub fn new(mat: Rc<dyn Material>, shape: Box<dyn Hittable>) -> Self { + pub fn new(mat: Arc<dyn Material + Sync + Send>, shape: Box<dyn Hittable + Sync>) -> Self { Object { mat, shape, |