Render with the lighting model

This commit is contained in:
Savanni D'Gerinel 2024-06-23 19:13:04 -04:00
parent 59dfaf1696
commit 324d37f858
3 changed files with 28 additions and 14 deletions

View File

@ -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 => {},
}
});
});

View File

@ -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. {

View File

@ -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 {