aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2020-04-30 15:11:21 +0100
committerYann Herklotz <git@yannherklotz.com>2020-04-30 15:11:21 +0100
commitdd5ac7c5fe336e9cac794cfa72d139613a99b466 (patch)
treeaedc5d53bdb83404b6fb426b55756c66755adb80
parent60ae11a9271534a4f0b6c44d1fd967777855c52d (diff)
downloadleela-dd5ac7c5fe336e9cac794cfa72d139613a99b466.tar.gz
leela-dd5ac7c5fe336e9cac794cfa72d139613a99b466.zip
Add threads using Rayon
-rw-r--r--Cargo.lock124
-rw-r--r--Cargo.toml1
-rw-r--r--src/hittable.rs5
-rw-r--r--src/main.rs9
-rw-r--r--src/render.rs37
-rw-r--r--src/scene.rs4
-rw-r--r--src/sphere.rs4
7 files changed, 163 insertions, 21 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 700c46b..3416654 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -54,6 +54,59 @@ dependencies = [
]
[[package]]
+name = "crossbeam-deque"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+ "maybe-uninit",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
+dependencies = [
+ "autocfg 1.0.0",
+ "cfg-if",
+ "crossbeam-utils",
+ "lazy_static",
+ "maybe-uninit",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-queue"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
+dependencies = [
+ "autocfg 1.0.0",
+ "cfg-if",
+ "lazy_static",
+]
+
+[[package]]
+name = "either"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
+
+[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -71,11 +124,27 @@ dependencies = [
]
[[package]]
+name = "hermit-abi"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
name = "leela"
version = "0.1.0"
dependencies = [
"cgmath",
"rand 0.7.3",
+ "rayon",
]
[[package]]
@@ -85,6 +154,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
[[package]]
+name = "maybe-uninit"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
+
+[[package]]
+name = "memoffset"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
+dependencies = [
+ "autocfg 1.0.0",
+]
+
+[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -94,6 +178,16 @@ dependencies = [
]
[[package]]
+name = "num_cpus"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -247,6 +341,30 @@ dependencies = [
]
[[package]]
+name = "rayon"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
+dependencies = [
+ "crossbeam-deque",
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-queue",
+ "crossbeam-utils",
+ "lazy_static",
+ "num_cpus",
+]
+
+[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -256,6 +374,12 @@ dependencies = [
]
[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 530abd3..3c094a0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,3 +9,4 @@ edition = "2018"
[dependencies]
cgmath = "0.17.0"
rand = "0.7.3"
+rayon = "1.3.0"
diff --git a/src/hittable.rs b/src/hittable.rs
index 1c61872..dcc5006 100644
--- a/src/hittable.rs
+++ b/src/hittable.rs
@@ -7,11 +7,12 @@ pub struct Hit<'a> {
pub p: Vector3<f64>,
pub normal: Vector3<f64>,
pub front_face: bool,
- pub material: &'a (dyn Material)
+ pub material: &'a (dyn Material + std::marker::Sync)
}
impl<'a> Hit<'a> {
- pub fn new(ray: &Ray, t: f64, out_normal: Vector3<f64>, material: &'a(dyn Material)) -> Hit<'a> {
+ pub fn new(ray: &Ray, t: f64, out_normal: Vector3<f64>, material: &'a(dyn Material + std::marker::Sync))
+ -> Hit<'a> {
let front_face = dot(ray.dir, out_normal) < 0.0;
let normal = if front_face { out_normal } else { -out_normal };
let p = ray.at(t);
diff --git a/src/main.rs b/src/main.rs
index 1a0b001..f1a627f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -59,9 +59,10 @@ pub fn random_scene(rng: &mut ThreadRng) -> scene::Scene {
}
fn main() {
- let image_width = 1200;
- let image_height = 800;
- let samples = 100;
+ let image_width = 400;
+ let image_height = 200;
+ let samples = 50;
+ let threads = 1;
let max_depth = 50;
let aspect_ratio = image_width as f64 / image_height as f64;
@@ -78,7 +79,7 @@ fn main() {
let camera = camera::Camera::new(&lookfrom, &lookat, &vup,
20.0 * PI / 180.0, aspect_ratio, aperture, dist_to_focus);
- render::render(&scene, camera, image_height, image_width, samples, max_depth, &mut rng);
+ render::render(&scene, &camera, image_height, image_width, samples, max_depth, threads);
eprintln!("\nDone")
}
diff --git a/src/render.rs b/src/render.rs
index 740c3eb..47c6698 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -1,6 +1,7 @@
use cgmath::prelude::*;
use cgmath::{Vector3, vec3};
use rand::prelude::*;
+use rayon::prelude::*;
use std::f64::INFINITY;
use crate::camera::Camera;
use crate::scene::Scene;
@@ -23,20 +24,34 @@ fn ray_colour(rng: &mut ThreadRng, ray: &Ray, scene: &Scene, depth: i32) -> Vect
}
}
-pub fn render(world: &Scene, camera: Camera, image_height: i32, image_width: i32,
- samples: i32, max_depth: i32, rng: &mut ThreadRng) {
+pub fn thread_render(world: &Scene, camera: &Camera, rng: &mut ThreadRng, image_height: i32,
+ image_width: i32, samples: i32, max_depth: i32, i: i32, j: i32) -> Vector3<f64> {
+ let mut colour = vec3(0.0, 0.0, 0.0);
+ for _ in 0 .. samples {
+ let ru: f64 = rng.gen();
+ let rv: f64 = rng.gen();
+ let u = (i as f64 + ru) / image_width as f64;
+ let v = ((image_height - 1 - j) as f64 + rv) / image_height as f64;
+ let ray = camera.get_ray(rng, u, v);
+ colour += ray_colour(rng, &ray, &world, max_depth);
+ }
+ colour
+}
+
+pub fn render(world: &Scene, camera: &Camera, image_height: i32, image_width: i32,
+ samples: i32, max_depth: i32, threads: i32) {
for j in 0 .. image_height {
eprint!("\rScanlines: {:3} / {:3}", j+1, image_height);
for i in 0 .. image_width {
- let mut colour = vec3(0.0, 0.0, 0.0);
- for _ in 0 .. samples {
- let ru: f64 = rng.gen();
- let rv: f64 = rng.gen();
- let u = (i as f64 + ru) / image_width as f64;
- let v = ((image_height - 1 - j) as f64 + rv) / image_height as f64;
- let ray = camera.get_ray(rng, u, v);
- colour += ray_colour(rng, &ray, &world, max_depth);
- }
+ let colours = (0 .. threads)
+ .into_par_iter()
+ .map(|_| {
+ let mut trng = thread_rng();
+ thread_render(
+ world, camera, &mut trng, image_height, image_width,
+ samples / threads, max_depth, i, j)
+ });
+ let colour = colours.sum::<Vector3<f64>>();
print_colour(&colour, samples);
}
}
diff --git a/src/scene.rs b/src/scene.rs
index 368c784..0aa775c 100644
--- a/src/scene.rs
+++ b/src/scene.rs
@@ -2,7 +2,7 @@ use crate::hittable::{Hittable, Hit};
use crate::ray::Ray;
pub struct Scene {
- objects: Vec<Box<dyn Hittable>>
+ objects: Vec<Box<dyn Hittable + std::marker::Sync>>
}
impl Scene {
@@ -10,7 +10,7 @@ impl Scene {
Scene { objects: Vec::new() }
}
- pub fn add(&mut self, obj: Box<dyn Hittable>) {
+ pub fn add(&mut self, obj: Box<dyn Hittable + std::marker::Sync>) {
self.objects.push(obj)
}
diff --git a/src/sphere.rs b/src/sphere.rs
index 9ea9081..f1c88b6 100644
--- a/src/sphere.rs
+++ b/src/sphere.rs
@@ -8,11 +8,11 @@ use crate::ray::Ray;
pub struct Sphere {
center: Vector3<f64>,
radius: f64,
- material: Box<dyn Material>
+ material: Box<dyn Material + std::marker::Sync>
}
impl Sphere {
- pub fn new(center: Vector3<f64>, radius: f64, material: Box<dyn Material>) -> Sphere {
+ pub fn new(center: Vector3<f64>, radius: f64, material: Box<dyn Material + std::marker::Sync>) -> Sphere {
Sphere { center, radius, material }
}
}