Add a sphere ray tracer
This commit is contained in:
parent
f15fa9dd48
commit
4f47d65ba5
|
@ -3334,12 +3334,15 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ray-tracer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.8.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
|
@ -3347,9 +3350,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.0"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rayon = "1.10.0"
|
||||
|
||||
[[bin]]
|
||||
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)]
|
||||
pub struct PPM(String);
|
||||
|
||||
impl From<Canvas> for PPM {
|
||||
fn from(c: Canvas) -> Self {
|
||||
impl From<&Canvas> for PPM {
|
||||
fn from(c: &Canvas) -> Self {
|
||||
// let v = vec![0.; c.width() * c.height() * 3];
|
||||
let header = format!("P3\n{} {}\n255\n", c.width(), c.height());
|
||||
|
||||
|
@ -68,7 +68,7 @@ mod tests {
|
|||
#[test]
|
||||
fn construct_ppm_header() {
|
||||
let c = Canvas::new(5, 3);
|
||||
let ppm = PPM::from(c);
|
||||
let ppm = PPM::from(&c);
|
||||
|
||||
assert!(ppm.starts_with(
|
||||
"P3\n\
|
||||
|
|
Loading…
Reference in New Issue