Smooth shading
This commit is contained in:
parent
40c66154fc
commit
26ddd8d236
4 changed files with 35 additions and 28 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue