diff --git a/ray-tracer/src/bin/sphere.rs b/ray-tracer/src/bin/sphere.rs index a309d85..dc8546b 100644 --- a/ray-tracer/src/bin/sphere.rs +++ b/ray-tracer/src/bin/sphere.rs @@ -6,7 +6,14 @@ use std::{ sync::{Arc, RwLock}, }; -const SIZE: usize = 100; +const SIZE: usize = 1000; + +const EPSILON: f64 = 0.00001; + +fn eq_f64(l: f64, r: f64) -> bool { + (l - r).abs() < EPSILON +} + fn render( camera: &Point, @@ -23,6 +30,7 @@ fn render( let ray = Ray::new(camera.clone(), (Point::new(0., 0., wall_z) - camera).normalize()); let xs = ray.intersect(sphere); + /* match xs.hit() { Some(hit) => { let point = ray.position(hit.t); @@ -33,6 +41,7 @@ fn render( } None => {} } + */ (0..SIZE).into_par_iter().for_each(|x| { (0..SIZE).into_par_iter().for_each(|y| { @@ -47,6 +56,7 @@ fn render( let point = ray.position(hit.t); let normal = hit.object.normal_at(&point); let eye = -ray.direction; + let color = hit .object .material() @@ -73,29 +83,43 @@ fn main() { let camera = Point::new(0., 0., -5.); let wall_z = 10.; let wall_size = 7.; + let light = PointLight::new(Point::new(-5., 5., -10.), Color::new(1., 1., 1.)); + render(&camera, &light, &sphere, wall_z, wall_size, "sphere_1.ppm"); + /* { let light = PointLight::new(Point::new(0., 0., -10.), Color::new(1., 1., 1.)); + println!("Light at {:0.2} {:0.2} {:0.2}", light.position.x(), light.position.y(), light.position.z()); render(&camera, &light, &sphere, wall_z, wall_size, "sphere_1.ppm"); + println!(); } { - let light = PointLight::new(Point::new(-1., 0., -10.), Color::new(1., 1., 1.)); + let light = PointLight::new(Point::new(-2., 0., -10.), Color::new(1., 1., 1.)); + println!("Light at {:0.2} {:0.2} {:0.2}", light.position.x(), light.position.y(), light.position.z()); render(&camera, &light, &sphere, wall_z, wall_size, "sphere_2.ppm"); + println!(); } { - let light = PointLight::new(Point::new(1., 0., -10.), Color::new(1., 1., 1.)); + let light = PointLight::new(Point::new(2., 0., -10.), Color::new(1., 1., 1.)); + println!("Light at {:0.2} {:0.2} {:0.2}", light.position.x(), light.position.y(), light.position.z()); render(&camera, &light, &sphere, wall_z, wall_size, "sphere_3.ppm"); + println!(); } { - let light = PointLight::new(Point::new(0., -1., -10.), Color::new(1., 1., 1.)); + let light = PointLight::new(Point::new(0., -2., -10.), Color::new(1., 1., 1.)); + println!("Light at {:0.2} {:0.2} {:0.2}", light.position.x(), light.position.y(), light.position.z()); render(&camera, &light, &sphere, wall_z, wall_size, "sphere_4.ppm"); + println!(); } { - let light = PointLight::new(Point::new(0., 1., -10.), Color::new(1., 1., 1.)); + let light = PointLight::new(Point::new(0., 2., -10.), Color::new(1., 1., 1.)); + println!("Light at {:0.2} {:0.2} {:0.2}", light.position.x(), light.position.y(), light.position.z()); render(&camera, &light, &sphere, wall_z, wall_size, "sphere_5.ppm"); + println!(); } + */ } diff --git a/ray-tracer/src/types/material.rs b/ray-tracer/src/types/material.rs index 391f3ac..7977755 100644 --- a/ray-tracer/src/types/material.rs +++ b/ray-tracer/src/types/material.rs @@ -1,4 +1,4 @@ -use super::{Color, Point, PointLight, Vector}; +use super::{eq_f64, Color, Point, PointLight, Vector}; #[derive(Debug, PartialEq)] pub struct Material { @@ -22,7 +22,25 @@ impl Default for Material { } impl Material { - pub fn lighting(&self, light: &PointLight, position: &Point, eye: &Vector, normal_v: &Vector) -> Color { + pub fn lighting( + &self, + light: &PointLight, + position: &Point, + eye: &Vector, + normal_v: &Vector, + ) -> Color { + // let debug = eq_f64(position.x(), -0.09344) + // || eq_f64(position.x(), 0.09344) && eq_f64(position.y(), 0.) + // || eq_f64(position.y(), -0.09344) + // || eq_f64(position.y(), 0.09344) && eq_f64(position.x(), 0.); + // if debug { + // println!( + // "Debugging {:0.5} {:0.5} {:0.5}", + // position.x(), + // position.y(), + // position.z() + // ); + // } let effective_color = self.color * light.intensity; let light_v = (light.position - position).normalize(); @@ -53,8 +71,8 @@ impl Material { #[cfg(test)] mod tests { - use crate::types::{Color, Point, PointLight, Vector}; use super::*; + use crate::types::{Color, Point, PointLight, Vector}; #[test] fn lighting_with_eye_between_light_and_surface() { @@ -65,7 +83,10 @@ mod tests { let normalv = Vector::new(0., 0., -1.); let light = PointLight::new(Point::new(0., 0., -10.), Color::new(1., 1., 1.)); - assert_eq!(m.lighting(&light, &position, &eyev, &normalv), Color::new(1.9, 1.9, 1.9)); + assert_eq!( + m.lighting(&light, &position, &eyev, &normalv), + Color::new(1.9, 1.9, 1.9) + ); } #[test] @@ -77,7 +98,10 @@ mod tests { let normalv = Vector::new(0., 0., -1.); let light = PointLight::new(Point::new(0., 0., -10.), Color::new(1., 1., 1.)); - assert_eq!(m.lighting(&light, &position, &eyev, &normalv), Color::new(1., 1., 1.)); + assert_eq!( + m.lighting(&light, &position, &eyev, &normalv), + Color::new(1., 1., 1.) + ); } #[test] @@ -89,7 +113,10 @@ mod tests { let normalv = Vector::new(0., 0., -1.); let light = PointLight::new(Point::new(0., 10., -10.), Color::new(1., 1., 1.)); - assert_eq!(m.lighting(&light, &position, &eyev, &normalv), Color::new(0.7364, 0.7364, 0.7364)); + assert_eq!( + m.lighting(&light, &position, &eyev, &normalv), + Color::new(0.7364, 0.7364, 0.7364) + ); } #[test] @@ -102,7 +129,10 @@ mod tests { let normalv = Vector::new(0., 0., -1.); let light = PointLight::new(Point::new(0., 10., -10.), Color::new(1., 1., 1.)); - assert_eq!(m.lighting(&light, &position, &eyev, &normalv), Color::new(1.6364, 1.6364, 1.6364)); + assert_eq!( + m.lighting(&light, &position, &eyev, &normalv), + Color::new(1.6364, 1.6364, 1.6364) + ); } #[test] @@ -114,6 +144,9 @@ mod tests { let normalv = Vector::new(0., 0., -1.); let light = PointLight::new(Point::new(0., 0., 10.), Color::new(1., 1., 1.)); - assert_eq!(m.lighting(&light, &position, &eyev, &normalv), Color::new(0.1, 0.1, 0.1)); + assert_eq!( + m.lighting(&light, &position, &eyev, &normalv), + Color::new(0.1, 0.1, 0.1) + ); } } diff --git a/ray-tracer/src/types/vector.rs b/ray-tracer/src/types/vector.rs index 3c8f88d..3c7908e 100644 --- a/ray-tracer/src/types/vector.rs +++ b/ray-tracer/src/types/vector.rs @@ -106,9 +106,7 @@ impl std::ops::Sub for Vector { impl std::ops::Neg for Vector { type Output = Vector; fn neg(self) -> Self::Output { - let mut t = -self.0; - t.0 = 0.; - Vector::from(t) + Vector::from(-self.0) } }