diff --git a/ray-tracer/src/bin/sphere.rs b/ray-tracer/src/bin/sphere.rs index 6af0048..86a1361 100644 --- a/ray-tracer/src/bin/sphere.rs +++ b/ray-tracer/src/bin/sphere.rs @@ -1,16 +1,21 @@ -use ray_tracer::{transforms::*, types::*, PPM}; +use ray_tracer::{types::*, PPM}; use rayon::prelude::*; use std::{fs::File, io::Write, sync::{Arc, RwLock}}; -const SIZE: usize = 1000; +const SIZE: usize = 100; fn main() { let canvas = Arc::new(RwLock::new(Canvas::new(SIZE, SIZE))); let mut sphere = Sphere::default(); - *sphere.transformation_mut() = shearing(1., 0., 0., 0., 0., 0.); - let camera = Point::new(0., 1., -5.); - let wall_z = 10.; + let mut material = Material::default(); + material.color = Color::new(1., 0.2, 1.); + *sphere.material_mut() = material; + + let light = PointLight::new(Point::new(-10., 10., -10.), Color::new(1., 1., 1.)); + + let camera = Point::new(0., 0., -5.); + let world_z = 10.; let wall_size = 7.; let half = wall_size / 2.; @@ -18,16 +23,24 @@ fn main() { (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 world_x = -half + pixel_size * x as f64; + let world_y = half - pixel_size * y as f64; + let position = Point::new(world_x, world_y, world_z); let ray = Ray::new( camera.clone(), - Vector::new(wall_x, wall_y, wall_z).normalize(), + (position - camera).normalize(), ); let xs = ray.intersect(&sphere); - if xs.hit().is_some() { - *canvas.write().unwrap().pixel_mut(x, y) = Color::new(0., 0., 1.); + match xs.hit() { + Some(hit) => { + let point = ray.position(hit.t); + let normal = hit.object.normal_at(&point); + let eye = -ray.direction; + let color = hit.object.material().lighting(&light, &point, &eye, &normal); + *canvas.write().unwrap().pixel_mut(x, y) = color; + } + None => {}, } }); }); diff --git a/ray-tracer/src/types/material.rs b/ray-tracer/src/types/material.rs index 85dbd23..0ad0d57 100644 --- a/ray-tracer/src/types/material.rs +++ b/ray-tracer/src/types/material.rs @@ -22,19 +22,19 @@ impl Default for Material { } impl Material { - pub fn lighting(&self, light: &PointLight, position: &Point, eye: &Vector, normal: &Vector) -> Color { + pub fn lighting(&self, light: &PointLight, position: &Point, eye: &Vector, normal_v: &Vector) -> Color { let effective_color = self.color * light.intensity; let light_v = (light.position - position).normalize(); let ambient = effective_color * self.ambient; - let light_dot_normal = light_v.dot(&normal); + let light_dot_normal = light_v.dot(&normal_v); let (diffuse, specular) = if light_dot_normal < 0. { (Color::new(0., 0., 0.), Color::new(0., 0., 0.)) } else { let diffuse = effective_color * self.diffuse * light_dot_normal; - let reflect_v = (-light_v).reflect(&normal); + let reflect_v = (-light_v).reflect(&normal_v); let reflect_dot_eye = reflect_v.dot(&eye); let specular = if reflect_dot_eye <= 0. { diff --git a/ray-tracer/src/types/ray.rs b/ray-tracer/src/types/ray.rs index 9956615..9d26523 100644 --- a/ray-tracer/src/types/ray.rs +++ b/ray-tracer/src/types/ray.rs @@ -1,8 +1,9 @@ use super::{Intersection, Intersections, Matrix, Point, Sphere, Vector}; +#[derive(Debug)] pub struct Ray { origin: Point, - direction: Vector, + pub direction: Vector, } impl Ray {