Add a sphere ray tracer

This commit is contained in:
Savanni D'Gerinel 2024-06-23 16:20:10 -04:00
parent f15fa9dd48
commit 4f47d65ba5
4 changed files with 51 additions and 7 deletions

11
Cargo.lock generated
View File

@ -3334,12 +3334,15 @@ dependencies = [
[[package]] [[package]]
name = "ray-tracer" name = "ray-tracer"
version = "0.1.0" version = "0.1.0"
dependencies = [
"rayon",
]
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.8.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [ dependencies = [
"either", "either",
"rayon-core", "rayon-core",
@ -3347,9 +3350,9 @@ dependencies = [
[[package]] [[package]]
name = "rayon-core" name = "rayon-core"
version = "1.12.0" version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [ dependencies = [
"crossbeam-deque", "crossbeam-deque",
"crossbeam-utils", "crossbeam-utils",

View File

@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
rayon = "1.10.0"
[[bin]] [[bin]]
name = "projectile" name = "projectile"

View File

@ -0,0 +1,40 @@
use ray_tracer::{transforms::*, types::*, PPM};
use rayon::prelude::*;
use std::{fs::File, io::Write, sync::{Arc, RwLock}};
const SIZE: usize = 1000;
fn main() {
let canvas = Arc::new(RwLock::new(Canvas::new(SIZE, SIZE)));
let mut sphere = Sphere::default();
sphere.set_transformation(shearing(1., 0., 0., 0., 0., 0.));
let camera = Point::new(0., 1., -5.);
let wall_z = 10.;
let wall_size = 7.;
let half = wall_size / 2.;
let pixel_size = wall_size / SIZE as f64;
(0..SIZE).into_par_iter().for_each(|x| {
(0..SIZE).into_par_iter().for_each(|y| {
let wall_x = -half + pixel_size * x as f64;
let wall_y = half - pixel_size * y as f64;
let ray = Ray::new(
camera.clone(),
Vector::new(wall_x, wall_y, wall_z).normalize(),
);
let xs = ray.intersect(&sphere);
if xs.hit().is_some() {
*canvas.write().unwrap().pixel_mut(x, y) = Color::new(0., 0., 1.);
}
});
});
let canvas = canvas.read().unwrap();
let ppm = PPM::from(&*canvas);
let mut file = File::create("sphere.ppm").unwrap();
let _ = file.write(ppm.as_bytes());
}

View File

@ -29,8 +29,8 @@ fn join_to_line_limit(data: impl IntoIterator<Item = String>) -> Vec<String> {
#[derive(Debug)] #[derive(Debug)]
pub struct PPM(String); pub struct PPM(String);
impl From<Canvas> for PPM { impl From<&Canvas> for PPM {
fn from(c: Canvas) -> Self { fn from(c: &Canvas) -> Self {
// let v = vec![0.; c.width() * c.height() * 3]; // let v = vec![0.; c.width() * c.height() * 3];
let header = format!("P3\n{} {}\n255\n", c.width(), c.height()); let header = format!("P3\n{} {}\n255\n", c.width(), c.height());
@ -68,7 +68,7 @@ mod tests {
#[test] #[test]
fn construct_ppm_header() { fn construct_ppm_header() {
let c = Canvas::new(5, 3); let c = Canvas::new(5, 3);
let ppm = PPM::from(c); let ppm = PPM::from(&c);
assert!(ppm.starts_with( assert!(ppm.starts_with(
"P3\n\ "P3\n\