Smooth shading

This commit is contained in:
Michael Zhang 2023-02-25 16:45:53 -06:00
parent 40c66154fc
commit 26ddd8d236
4 changed files with 35 additions and 28 deletions

View file

@ -20,7 +20,7 @@ Due: Friday March 3rd
correctly evaluating the Phong illumination equation using the unit length
normal of the plane in which the triangle lies. (10 pts)
- [ ] The program is capable of rendering triangles using smooth shading, in
- [x] The program is capable of rendering triangles using smooth shading, in
which every pixel within a triangle is assigned a unique color, obtained
by evaluating the Phong illumination equation using a unit length normal
direction correctly interpolated from the three normal directions defined

View file

@ -207,7 +207,7 @@ impl Scene {
"v" => scene.triangle_vertices.push(r!(Vector)),
// vn nx ny nz
"vn" => scene.normals.push(r!(Vector)),
"vn" => scene.vertex_normals.push(r!(Vector)),
// f v1 v2 v3
// f v1//n1 v2//n2 v3//n3

View file

@ -7,7 +7,7 @@ pub mod sphere;
pub mod texture;
pub mod triangle;
use crate::image::{Color, Image};
use crate::image::Color;
use crate::{Point, Point2, Vector};
use self::data::{Attenuation, DepthCueing, Light, Material};
@ -44,7 +44,5 @@ pub struct Scene {
/// Triangle vertices
pub triangle_vertices: Vec<Point>,
/// Normal vectors
pub normals: Vec<Vector>,
pub vertex_normals: Vec<Vector>,
}

View file

@ -5,7 +5,6 @@ use ordered_float::NotNan;
use crate::ray::Ray;
use crate::utils::{cross, dot};
use super::illumination::IntersectionContext;
use super::Scene;
@ -61,32 +60,42 @@ impl Triangle {
// Use barycentric coordinates to determine if the point is inside of the
// triangle
{
// p = p0 + beta * e1 + gamma * e2
// Using the whack linear algebra approach derived on slide 57
let ep = point - p0;
let d = Matrix2::new(dot(e1, e1), dot(e1, e2), dot(e2, e1), dot(e2, e2));
let p = Vector2::new(dot(e1, ep), dot(e2, ep));
// p = p0 + beta * e1 + gamma * e2
// Using the whack linear algebra approach derived on slide 57
let ep = point - p0;
let d = Matrix2::new(dot(e1, e1), dot(e1, e2), dot(e2, e1), dot(e2, e2));
let p = Vector2::new(dot(e1, ep), dot(e2, ep));
let d_inv = match d.try_inverse() {
Some(v) => v,
// TODO: Whack
None => return Ok(None),
};
let d_inv = match d.try_inverse() {
Some(v) => v,
// TODO: Whack
None => return Ok(None),
};
let sol = d_inv * p;
let beta = sol.x;
let gamma = sol.y;
let sol = d_inv * p;
let beta = sol.x;
let gamma = sol.y;
// Slide 46
let alpha = 1.0 - beta - gamma;
// Slide 46
let alpha = 1.0 - beta - gamma;
// Each of alpha, beta, and gamma must be between 0 and 1
if ![alpha, beta, gamma].into_iter().all(|v| 0.0 < v && v < 1.0) {
return Ok(None);
}
// Each of alpha, beta, and gamma must be between 0 and 1
if ![alpha, beta, gamma].into_iter().all(|v| 0.0 < v && v < 1.0) {
return Ok(None);
}
let normal = n.normalize();
// If surface normals are provided, then interpolate the normals to do
// smooth shading
let normal = match self.normals {
Some(normals) => {
let n0 = scene.vertex_normals[normals[self.vertices.x]];
let n1 = scene.vertex_normals[normals[self.vertices.y]];
let n2 = scene.vertex_normals[normals[self.vertices.z]];
(alpha * n0 + beta * n1 + gamma * n2).normalize()
}
None => n.normalize(),
};
Ok(Some(IntersectionContext {
time,