Moved ray intersection code into ray class

This commit is contained in:
STP
2023-11-20 20:19:38 -05:00
parent 512f81031b
commit 6d332199e1
3 changed files with 44 additions and 58 deletions

View File

@@ -1,57 +1,11 @@
use crate::{light::Light, primitive::Intersection, ray::Ray, scene::*, INFINITY};
use crate::{light::Light, primitive::Intersection, scene::*};
use nalgebra::{Unit, Vector3};
static ZERO_VECTOR: Vector3<f32> = Vector3::new(0.0, 0.0, 0.0);
pub fn shade_rays(scene: &Scene, rays: &Vec<Ray>, width: i32, height: i32) -> Vec<Vector3<u8>> {
let mut pixel_data = vec![Vector3::new(0, 0, 0); (width * height) as usize];
for (pixel_index, ray) in rays.iter().enumerate() {
let intersect = get_closest_intersection(&scene.nodes, ray);
let colour = match intersect {
Some(intersect) => phong_shade_point(scene, &intersect),
None => {
// Handle rays that miss objects (e.g., use a background color or environment map)
Vector3::new(0, 0, 0)
}
};
pixel_data[pixel_index] = colour;
}
pixel_data
}
//Shade a single ray
pub fn shade_ray(scene: &Scene, ray: &Ray) -> Option<Vector3<u8>> {
let intersect = get_closest_intersection(&scene.nodes, ray);
match intersect {
Some(intersect) => Some(phong_shade_point(&scene, &intersect)),
None => None,
}
}
// Find the closest intersection, given a ray in world coordinates
pub fn get_closest_intersection(nodes: &Vec<Node>, ray: &Ray) -> Option<Intersection> {
let mut closest_distance = INFINITY;
let mut closest_intersect: Option<Intersection> = None;
for node in nodes {
let primitive = node.primitive.clone();
if let Some(intersect) = primitive.intersect_ray(ray) {
if intersect.distance < closest_distance {
closest_distance = intersect.distance;
closest_intersect = Some(intersect);
}
}
}
closest_intersect
}
// We want to shade a point placed in our scene
// Function to shade a point in the scene using Phong shading model
pub fn phong_shade_point(scene: &Scene, intersect: &Intersection) -> Vector3<u8> {
//Useful vectors !!!! CHECK IF WE CAN OPTIMISE
//Unpack the intersection data
let Intersection {
point,
normal,
@@ -63,9 +17,8 @@ pub fn phong_shade_point(scene: &Scene, intersect: &Intersection) -> Vector3<u8>
let kd = material.kd;
let ks = material.ks;
let shininess = material.shininess;
// We should now have all the information for our ray-tracer
// Let us first compute the ambient light component and set it as out base colour
// Compute the ambient light component and set it as base colour
let mut colour = kd.component_mul(ambient_light);
for light in &scene.lights {
@@ -75,7 +28,7 @@ pub fn phong_shade_point(scene: &Scene, intersect: &Intersection) -> Vector3<u8>
falloff: light_falloff,
} = light;
// Get light incidence vector
// Compute light incidence vector and its distance
let to_light = light_position - point;
let light_distance = to_light.norm();
let light_incidence = Unit::new_normalize(to_light);
@@ -103,8 +56,11 @@ pub fn phong_shade_point(scene: &Scene, intersect: &Intersection) -> Vector3<u8>
ZERO_VECTOR
};
// Update colour with diffuse and specular components
colour += light_colour.component_mul(&((diffuse + specular) * falloff));
}
// Clamp colour values to [0, 255] and convert to u8
let r = nalgebra::clamp(colour.x * 255.0, 0.0, 255.0) as u8;
let g = nalgebra::clamp(colour.y * 255.0, 0.0, 255.0) as u8;
let b = nalgebra::clamp(colour.z * 255.0, 0.0, 255.0) as u8;