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
|
correctly evaluating the Phong illumination equation using the unit length
|
||||||
normal of the plane in which the triangle lies. (10 pts)
|
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
|
which every pixel within a triangle is assigned a unique color, obtained
|
||||||
by evaluating the Phong illumination equation using a unit length normal
|
by evaluating the Phong illumination equation using a unit length normal
|
||||||
direction correctly interpolated from the three normal directions defined
|
direction correctly interpolated from the three normal directions defined
|
||||||
|
|
|
@ -207,7 +207,7 @@ impl Scene {
|
||||||
"v" => scene.triangle_vertices.push(r!(Vector)),
|
"v" => scene.triangle_vertices.push(r!(Vector)),
|
||||||
|
|
||||||
// vn nx ny nz
|
// vn nx ny nz
|
||||||
"vn" => scene.normals.push(r!(Vector)),
|
"vn" => scene.vertex_normals.push(r!(Vector)),
|
||||||
|
|
||||||
// f v1 v2 v3
|
// f v1 v2 v3
|
||||||
// f v1//n1 v2//n2 v3//n3
|
// f v1//n1 v2//n2 v3//n3
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub mod sphere;
|
||||||
pub mod texture;
|
pub mod texture;
|
||||||
pub mod triangle;
|
pub mod triangle;
|
||||||
|
|
||||||
use crate::image::{Color, Image};
|
use crate::image::Color;
|
||||||
use crate::{Point, Point2, Vector};
|
use crate::{Point, Point2, Vector};
|
||||||
|
|
||||||
use self::data::{Attenuation, DepthCueing, Light, Material};
|
use self::data::{Attenuation, DepthCueing, Light, Material};
|
||||||
|
@ -44,7 +44,5 @@ pub struct Scene {
|
||||||
|
|
||||||
/// Triangle vertices
|
/// Triangle vertices
|
||||||
pub triangle_vertices: Vec<Point>,
|
pub triangle_vertices: Vec<Point>,
|
||||||
|
pub vertex_normals: Vec<Vector>,
|
||||||
/// Normal vectors
|
|
||||||
pub normals: Vec<Vector>,
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ use ordered_float::NotNan;
|
||||||
use crate::ray::Ray;
|
use crate::ray::Ray;
|
||||||
use crate::utils::{cross, dot};
|
use crate::utils::{cross, dot};
|
||||||
|
|
||||||
|
|
||||||
use super::illumination::IntersectionContext;
|
use super::illumination::IntersectionContext;
|
||||||
use super::Scene;
|
use super::Scene;
|
||||||
|
|
||||||
|
@ -61,32 +60,42 @@ impl Triangle {
|
||||||
|
|
||||||
// Use barycentric coordinates to determine if the point is inside of the
|
// Use barycentric coordinates to determine if the point is inside of the
|
||||||
// triangle
|
// triangle
|
||||||
{
|
// p = p0 + beta * e1 + gamma * e2
|
||||||
// p = p0 + beta * e1 + gamma * e2
|
// Using the whack linear algebra approach derived on slide 57
|
||||||
// Using the whack linear algebra approach derived on slide 57
|
let ep = point - p0;
|
||||||
let ep = point - p0;
|
let d = Matrix2::new(dot(e1, e1), dot(e1, e2), dot(e2, e1), dot(e2, e2));
|
||||||
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 p = Vector2::new(dot(e1, ep), dot(e2, ep));
|
|
||||||
|
|
||||||
let d_inv = match d.try_inverse() {
|
let d_inv = match d.try_inverse() {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
// TODO: Whack
|
// TODO: Whack
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let sol = d_inv * p;
|
let sol = d_inv * p;
|
||||||
let beta = sol.x;
|
let beta = sol.x;
|
||||||
let gamma = sol.y;
|
let gamma = sol.y;
|
||||||
|
|
||||||
// Slide 46
|
// Slide 46
|
||||||
let alpha = 1.0 - beta - gamma;
|
let alpha = 1.0 - beta - gamma;
|
||||||
|
|
||||||
// Each of alpha, beta, and gamma must be between 0 and 1
|
// 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) {
|
if ![alpha, beta, gamma].into_iter().all(|v| 0.0 < v && v < 1.0) {
|
||||||
return Ok(None);
|
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 {
|
Ok(Some(IntersectionContext {
|
||||||
time,
|
time,
|
||||||
|
|
Loading…
Reference in a new issue