Fix a vector negation bug.
This commit is contained in:
parent
f347e2e47d
commit
4d67ea4af2
|
@ -6,7 +6,14 @@ use std::{
|
||||||
sync::{Arc, RwLock},
|
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(
|
fn render(
|
||||||
camera: &Point,
|
camera: &Point,
|
||||||
|
@ -23,6 +30,7 @@ fn render(
|
||||||
|
|
||||||
let ray = Ray::new(camera.clone(), (Point::new(0., 0., wall_z) - camera).normalize());
|
let ray = Ray::new(camera.clone(), (Point::new(0., 0., wall_z) - camera).normalize());
|
||||||
let xs = ray.intersect(sphere);
|
let xs = ray.intersect(sphere);
|
||||||
|
/*
|
||||||
match xs.hit() {
|
match xs.hit() {
|
||||||
Some(hit) => {
|
Some(hit) => {
|
||||||
let point = ray.position(hit.t);
|
let point = ray.position(hit.t);
|
||||||
|
@ -33,6 +41,7 @@ fn render(
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
(0..SIZE).into_par_iter().for_each(|x| {
|
(0..SIZE).into_par_iter().for_each(|x| {
|
||||||
(0..SIZE).into_par_iter().for_each(|y| {
|
(0..SIZE).into_par_iter().for_each(|y| {
|
||||||
|
@ -47,6 +56,7 @@ fn render(
|
||||||
let point = ray.position(hit.t);
|
let point = ray.position(hit.t);
|
||||||
let normal = hit.object.normal_at(&point);
|
let normal = hit.object.normal_at(&point);
|
||||||
let eye = -ray.direction;
|
let eye = -ray.direction;
|
||||||
|
|
||||||
let color = hit
|
let color = hit
|
||||||
.object
|
.object
|
||||||
.material()
|
.material()
|
||||||
|
@ -73,29 +83,43 @@ fn main() {
|
||||||
let camera = Point::new(0., 0., -5.);
|
let camera = Point::new(0., 0., -5.);
|
||||||
let wall_z = 10.;
|
let wall_z = 10.;
|
||||||
let wall_size = 7.;
|
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.));
|
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");
|
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");
|
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");
|
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");
|
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");
|
render(&camera, &light, &sphere, wall_z, wall_size, "sphere_5.ppm");
|
||||||
|
println!();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{Color, Point, PointLight, Vector};
|
use super::{eq_f64, Color, Point, PointLight, Vector};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct Material {
|
pub struct Material {
|
||||||
|
@ -22,7 +22,25 @@ impl Default for Material {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 effective_color = self.color * light.intensity;
|
||||||
|
|
||||||
let light_v = (light.position - position).normalize();
|
let light_v = (light.position - position).normalize();
|
||||||
|
@ -53,8 +71,8 @@ impl Material {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::types::{Color, Point, PointLight, Vector};
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::types::{Color, Point, PointLight, Vector};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lighting_with_eye_between_light_and_surface() {
|
fn lighting_with_eye_between_light_and_surface() {
|
||||||
|
@ -65,7 +83,10 @@ mod tests {
|
||||||
let normalv = Vector::new(0., 0., -1.);
|
let normalv = Vector::new(0., 0., -1.);
|
||||||
let light = PointLight::new(Point::new(0., 0., -10.), Color::new(1., 1., 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]
|
#[test]
|
||||||
|
@ -77,7 +98,10 @@ mod tests {
|
||||||
let normalv = Vector::new(0., 0., -1.);
|
let normalv = Vector::new(0., 0., -1.);
|
||||||
let light = PointLight::new(Point::new(0., 0., -10.), Color::new(1., 1., 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]
|
#[test]
|
||||||
|
@ -89,7 +113,10 @@ mod tests {
|
||||||
let normalv = Vector::new(0., 0., -1.);
|
let normalv = Vector::new(0., 0., -1.);
|
||||||
let light = PointLight::new(Point::new(0., 10., -10.), Color::new(1., 1., 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]
|
#[test]
|
||||||
|
@ -102,7 +129,10 @@ mod tests {
|
||||||
let normalv = Vector::new(0., 0., -1.);
|
let normalv = Vector::new(0., 0., -1.);
|
||||||
let light = PointLight::new(Point::new(0., 10., -10.), Color::new(1., 1., 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]
|
#[test]
|
||||||
|
@ -114,6 +144,9 @@ mod tests {
|
||||||
let normalv = Vector::new(0., 0., -1.);
|
let normalv = Vector::new(0., 0., -1.);
|
||||||
let light = PointLight::new(Point::new(0., 0., 10.), Color::new(1., 1., 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)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,9 +106,7 @@ impl std::ops::Sub for Vector {
|
||||||
impl std::ops::Neg for Vector {
|
impl std::ops::Neg for Vector {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
let mut t = -self.0;
|
Vector::from(-self.0)
|
||||||
t.0 = 0.;
|
|
||||||
Vector::from(t)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue