diff --git a/assignment-1c/grading-criteria.md b/assignment-1c/grading-criteria.md index a99386f..046cd28 100644 --- a/assignment-1c/grading-criteria.md +++ b/assignment-1c/grading-criteria.md @@ -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 diff --git a/assignment-1c/src/scene/input_file.rs b/assignment-1c/src/scene/input_file.rs index 1dee08a..31313e3 100644 --- a/assignment-1c/src/scene/input_file.rs +++ b/assignment-1c/src/scene/input_file.rs @@ -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 diff --git a/assignment-1c/src/scene/mod.rs b/assignment-1c/src/scene/mod.rs index 23ad075..80bf7c8 100644 --- a/assignment-1c/src/scene/mod.rs +++ b/assignment-1c/src/scene/mod.rs @@ -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, - - /// Normal vectors - pub normals: Vec, + pub vertex_normals: Vec, } diff --git a/assignment-1c/src/scene/triangle.rs b/assignment-1c/src/scene/triangle.rs index c537586..690e04b 100644 --- a/assignment-1c/src/scene/triangle.rs +++ b/assignment-1c/src/scene/triangle.rs @@ -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,