Added phong shading
This commit is contained in:
@@ -1,12 +1,13 @@
|
|||||||
use crate::ray::Ray;
|
use crate::ray::Ray;
|
||||||
use crate::{EPSILON, INFINITY};
|
use crate::{EPSILON, INFINITY};
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use nalgebra::{distance, Matrix4, Point3, Vector3};
|
use nalgebra::{distance, Matrix4, Point3, Vector3};
|
||||||
use roots::{find_roots_quadratic, Roots};
|
use roots::{find_roots_quadratic, Roots};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref MAGENTA_MATERIAL: Material = Material::magenta();
|
static ref MAGENTA_MATERIAL: Material = Material::magenta();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
light::Light,
|
||||||
primitive::{Intersection, Primitive},
|
primitive::{Intersection, Primitive},
|
||||||
ray::Ray,
|
ray::Ray,
|
||||||
scene::Scene,
|
scene::Scene,
|
||||||
INFINITY,
|
INFINITY,
|
||||||
};
|
};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
lazy_static! {
|
||||||
|
static ref VEC3_ONE: Vector3<f32> = Vector3::new(1.0, 1.0, 1.0);
|
||||||
|
static ref VEC3_ZERO: Vector3<f32> = Vector3::new(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
use nalgebra::{distance, Matrix4, Point3, Vector3, Vector4};
|
use nalgebra::{distance, Matrix4, Point3, Vector3, Vector4};
|
||||||
|
|
||||||
// Find the closest intersection, given a ray in world coordinates
|
// Find the closest intersection, given a ray in world coordinates
|
||||||
@@ -30,23 +37,64 @@ fn get_closest_intersection<'a>(scene: &'a Scene, ray: &Ray) -> Option<Intersect
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We want to shade a point placed in our scene
|
// We want to shade a point placed in our scene
|
||||||
fn phong_shade_point(scene: &Scene, intersect: &Intersection) -> Option<Vector4<f32>> {
|
fn phong_shade_point(scene: &Scene, intersect: &Intersection) -> Vector3<f32> {
|
||||||
|
//Useful vectors !!!! CHECK IF WE CAN OPTIMISE
|
||||||
|
let zero_vector = Vector3::new(0.0, 0.0, 0.0);
|
||||||
|
let one_vector = Vector3::new(1.0, 1.0, 1.0);
|
||||||
//Unpack the intersection data
|
//Unpack the intersection data
|
||||||
let Intersection {
|
let Intersection {
|
||||||
primitive,
|
primitive,
|
||||||
point,
|
point,
|
||||||
normal,
|
normal,
|
||||||
incidence,
|
incidence,
|
||||||
distance,
|
..
|
||||||
} = intersect;
|
} = intersect;
|
||||||
let ambient_light = scene.ambient_light;
|
let ambient_light = scene.ambient_light;
|
||||||
let material = primitive.get_material();
|
let material = primitive.get_material();
|
||||||
let kd = material.kd;
|
let kd = material.kd;
|
||||||
let ks = material.kd;
|
let ks = material.ks;
|
||||||
let shininess = material.shininess;
|
let shininess = material.shininess;
|
||||||
// We should now have all the information for our ray-tracer
|
// We should now have all the information for our ray-tracer
|
||||||
|
|
||||||
// Let us first compute the ambient light component
|
// Let us first compute the ambient light component and set it as out base colour
|
||||||
let ambient = ambient_light * kd;
|
let mut colour = kd.component_mul(&ambient_light);
|
||||||
None
|
|
||||||
|
for light in &scene.lights {
|
||||||
|
let Light {
|
||||||
|
position: light_position,
|
||||||
|
colour: light_colour,
|
||||||
|
falloff: light_falloff,
|
||||||
|
} = light;
|
||||||
|
|
||||||
|
// Get light incidence vector
|
||||||
|
let to_light = light_position - point;
|
||||||
|
let light_distance = to_light.norm();
|
||||||
|
let light_incidence = to_light.normalize();
|
||||||
|
|
||||||
|
// Compute light falloff
|
||||||
|
let falloff = 1.0
|
||||||
|
/ (light_falloff[0]
|
||||||
|
+ light_falloff[1] * light_distance
|
||||||
|
+ light_falloff[2] * light_distance * light_distance);
|
||||||
|
|
||||||
|
// Compute diffuse
|
||||||
|
let n_dot_l = normal.dot(&light_incidence);
|
||||||
|
let diffuse = if n_dot_l > 0.0 {
|
||||||
|
kd * n_dot_l
|
||||||
|
} else {
|
||||||
|
zero_vector
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compute specular
|
||||||
|
let h = (light_incidence + incidence).normalize();
|
||||||
|
let n_dot_h = normal.dot(&h);
|
||||||
|
let specular = if n_dot_h > 0.0 {
|
||||||
|
ks * n_dot_h.powf(shininess)
|
||||||
|
} else {
|
||||||
|
zero_vector
|
||||||
|
};
|
||||||
|
|
||||||
|
colour += light_colour.component_mul(&((diffuse + specular) * falloff));
|
||||||
|
}
|
||||||
|
nalgebra::clamp(colour, zero_vector, one_vector)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use nalgebra::Vector3;
|
|||||||
|
|
||||||
pub struct Scene<'a> {
|
pub struct Scene<'a> {
|
||||||
pub primitives: Vec<Box<dyn Primitive<'a>>>,
|
pub primitives: Vec<Box<dyn Primitive<'a>>>,
|
||||||
lights: Vec<Light>,
|
pub lights: Vec<Light>,
|
||||||
camera: Camera,
|
pub cameras: Vec<Camera>,
|
||||||
pub ambient_light: Vector3<f32>,
|
pub ambient_light: Vector3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user