Add a sphere ray tracer
This commit is contained in:
parent
f15fa9dd48
commit
4f47d65ba5
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
|
@ -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\
|
||||||
|
|
Loading…
Reference in New Issue