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 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 => {},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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. {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue