Render with the lighting model
This commit is contained in:
parent
59dfaf1696
commit
324d37f858
|
@ -1,16 +1,21 @@
|
||||||
use ray_tracer::{transforms::*, types::*, PPM};
|
use ray_tracer::{types::*, PPM};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::{fs::File, io::Write, sync::{Arc, RwLock}};
|
use std::{fs::File, io::Write, sync::{Arc, RwLock}};
|
||||||
|
|
||||||
const SIZE: usize = 1000;
|
const SIZE: usize = 100;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let canvas = Arc::new(RwLock::new(Canvas::new(SIZE, SIZE)));
|
let canvas = Arc::new(RwLock::new(Canvas::new(SIZE, SIZE)));
|
||||||
let mut sphere = Sphere::default();
|
let mut sphere = Sphere::default();
|
||||||
*sphere.transformation_mut() = shearing(1., 0., 0., 0., 0., 0.);
|
|
||||||
|
|
||||||
let camera = Point::new(0., 1., -5.);
|
let mut material = Material::default();
|
||||||
let wall_z = 10.;
|
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 wall_size = 7.;
|
||||||
let half = wall_size / 2.;
|
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(|x| {
|
||||||
(0..SIZE).into_par_iter().for_each(|y| {
|
(0..SIZE).into_par_iter().for_each(|y| {
|
||||||
let wall_x = -half + pixel_size * x as f64;
|
let world_x = -half + pixel_size * x as f64;
|
||||||
let wall_y = half - pixel_size * y 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(
|
let ray = Ray::new(
|
||||||
camera.clone(),
|
camera.clone(),
|
||||||
Vector::new(wall_x, wall_y, wall_z).normalize(),
|
(position - camera).normalize(),
|
||||||
);
|
);
|
||||||
let xs = ray.intersect(&sphere);
|
let xs = ray.intersect(&sphere);
|
||||||
if xs.hit().is_some() {
|
match xs.hit() {
|
||||||
*canvas.write().unwrap().pixel_mut(x, y) = Color::new(0., 0., 1.);
|
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 => {},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,19 +22,19 @@ impl Default for Material {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 effective_color = self.color * light.intensity;
|
||||||
|
|
||||||
let light_v = (light.position - position).normalize();
|
let light_v = (light.position - position).normalize();
|
||||||
let ambient = effective_color * self.ambient;
|
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. {
|
let (diffuse, specular) = if light_dot_normal < 0. {
|
||||||
(Color::new(0., 0., 0.), Color::new(0., 0., 0.))
|
(Color::new(0., 0., 0.), Color::new(0., 0., 0.))
|
||||||
} else {
|
} else {
|
||||||
let diffuse = effective_color * self.diffuse * light_dot_normal;
|
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 reflect_dot_eye = reflect_v.dot(&eye);
|
||||||
|
|
||||||
let specular = if reflect_dot_eye <= 0. {
|
let specular = if reflect_dot_eye <= 0. {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use super::{Intersection, Intersections, Matrix, Point, Sphere, Vector};
|
use super::{Intersection, Intersections, Matrix, Point, Sphere, Vector};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Ray {
|
pub struct Ray {
|
||||||
origin: Point,
|
origin: Point,
|
||||||
direction: Vector,
|
pub direction: Vector,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ray {
|
impl Ray {
|
||||||
|
|
Loading…
Reference in New Issue