This commit is contained in:
Michael Zhang 2023-01-31 15:07:02 -06:00
parent e694cc8863
commit 6085f5df26
3 changed files with 132 additions and 29 deletions

View file

@ -17,6 +17,7 @@ dependencies = [
"itertools",
"num",
"ordered-float",
"rayon",
]
[[package]]
@ -37,6 +38,12 @@ version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.1.4"
@ -74,6 +81,49 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
]
[[package]]
name = "either"
version = "1.8.1"
@ -159,6 +209,15 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"autocfg",
]
[[package]]
name = "num"
version = "0.4.0"
@ -238,6 +297,16 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.17.0"
@ -301,6 +370,28 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "rustix"
version = "0.36.7"
@ -315,6 +406,12 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.152"

View file

@ -11,3 +11,4 @@ clap = { version = "4.1.4", features = ["derive"] }
itertools = "0.10.5"
num = { version = "0.4.0", features = ["serde"] }
ordered-float = "3.4.0"
rayon = "1.6.1"

View file

@ -15,8 +15,9 @@ use anyhow::Result;
use clap::Parser;
use itertools::Itertools;
use ordered_float::NotNan;
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
use crate::image::{Image, Pixel};
use crate::image::Image;
use crate::input_file::parse_input_file;
use crate::ray::Ray;
use crate::scene_data::Object;
@ -98,40 +99,44 @@ fn main() -> Result<()> {
}
};
// This is an L because par_bridge is unordered
let pixels = (0..scene.image_width)
.cartesian_product(0..scene.image_height)
.collect_vec();
// Loop through every single pixel of the output file
let mut pixels =
vec![Pixel::default(); scene.image_width * scene.image_width];
for (px, py) in
(0..scene.image_width).cartesian_product(0..scene.image_height)
{
let pixel_in_space = pixel_translation(px, py);
let ray = Ray::from_endpoints(scene.eye_pos, pixel_in_space);
let pixels = pixels
.into_par_iter()
.map(|(px, py)| {
let pixel_in_space = pixel_translation(px, py);
let ray = Ray::from_endpoints(scene.eye_pos, pixel_in_space);
let earliest_intersection = scene
.objects
.iter()
.filter_map(|object| {
let sphere = match object {
Object::Sphere(v) => v,
_ => return None, /* TODO: Handle other object types for
* intersection as well */
};
let earliest_intersection = scene
.objects
.iter()
.filter_map(|object| {
let sphere = match object {
Object::Sphere(v) => v,
_ => return None, /* TODO: Handle other object types for
* intersection as well */
};
ray.intersects_at(sphere).map(|t| (t, sphere))
})
.min_by_key(|(t, _)| NotNan::new(*t).unwrap());
ray.intersects_at(sphere).map(|t| (t, sphere))
})
.min_by_key(|(t, _)| NotNan::new(*t).unwrap());
let pixel_color = match earliest_intersection {
Some((_, sphere)) => scene.material_colors[sphere.material],
// There was no intersection, so this should default to the background
// color
None => scene.bkg_color,
};
let pixel_color = match earliest_intersection {
Some((_, sphere)) => scene.material_colors[sphere.material],
// There was no intersection, so this should default to the background
// color
None => scene.bkg_color,
};
// println!("({px}, {py}): {intersection:?}\t{ray:?} {sphere:?}");
// println!("({px}, {py}): {intersection:?}\t{ray:?} {sphere:?}");
pixels[py * scene.image_height + px] = pixel_color.to_pixel();
}
pixel_color.to_pixel()
})
.collect::<Vec<_>>();
let image = Image {
width: scene.image_width,