Add Phong material

This commit is contained in:
Matthew Gordon 2019-11-27 17:05:51 -05:00
parent 0a7963097c
commit dbbd855c73
4 changed files with 44 additions and 6 deletions

View File

@ -1,5 +1,6 @@
use nalgebra::{convert, RealField, Vector3};
use super::algebra_utils::try_change_of_basis_matrix;
use super::colour::ColourRgbF;
use super::raycasting::{IntersectionInfo, Ray};
use super::sampler::Sampler;
@ -25,13 +26,19 @@ impl<T: RealField> Integrator<T> for WhittedIntegrator<T> {
self.lights
.iter()
.map(|light| {
let basis_change =
try_change_of_basis_matrix(&info.tangent, &info.cotangent, &info.normal)
.expect("Normal, tangent and cotangent don't for a valid basis.");
match sampler
.sample(&Ray::new(info.location, light.direction).bias(convert(0.000000001)))
{
Some(_) => self.ambient_light,
None => {
info.material.bsdf()(info.retro, light.direction, light.colour)
* light.direction.dot(&info.normal)
info.material.bsdf()(
basis_change * info.retro,
basis_change * light.direction,
light.colour,
) * light.direction.dot(&info.normal).abs()
}
}
})

View File

@ -1,3 +1,4 @@
pub mod algebra_utils;
pub mod camera;
pub mod colour;
pub mod image;

View File

@ -13,7 +13,7 @@ use std::rc::Rc;
use vanrijn::camera::partial_render_scene;
use vanrijn::colour::{ColourRgbF, NamedColour};
use vanrijn::image::{ClampingToneMapper, ImageRgbF, ImageRgbU8, ToneMapper};
use vanrijn::materials::LambertianMaterial;
use vanrijn::materials::{LambertianMaterial, PhongMaterial};
use vanrijn::raycasting::{Plane, Sphere};
use vanrijn::scene::Scene;
@ -88,9 +88,11 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
Box::new(Sphere::new(
Vector3::new(0.0, 1.5, 6.0),
1.0,
Rc::new(LambertianMaterial {
Rc::new(PhongMaterial {
colour: ColourRgbF::from_named(NamedColour::Red),
diffuse_strength: 0.1,
diffuse_strength: 0.05,
smoothness: 20.0,
specular_strength: 250.0,
}),
)),
],

View File

@ -1,6 +1,6 @@
use nalgebra::{RealField, Vector3};
use super::colour::ColourRgbF;
use super::colour::{ColourRgbF, NamedColour};
use std::fmt::Debug;
@ -36,3 +36,31 @@ impl<T: RealField> Material<T> for LambertianMaterial<T> {
)
}
}
#[derive(Debug)]
pub struct PhongMaterial<T: RealField> {
pub colour: ColourRgbF<T>,
pub diffuse_strength: T,
pub specular_strength: T,
pub smoothness: T,
}
impl<T: RealField> Material<T> for PhongMaterial<T> {
fn bsdf<'a>(
&'a self,
) -> Box<dyn Fn(Vector3<T>, Vector3<T>, ColourRgbF<T>) -> ColourRgbF<T> + 'a> {
Box::new(
move |w_o: Vector3<T>, w_i: Vector3<T>, colour_in: ColourRgbF<T>| {
if w_i.z < T::zero() || w_o.z < T::zero() {
ColourRgbF::from_vector3(&Vector3::zeros())
} else {
let reflection_vector = Vector3::new(-w_i.x, -w_i.y, w_i.z);
self.colour * colour_in * self.diffuse_strength
+ ColourRgbF::from_named(NamedColour::White)
* w_o.dot(&reflection_vector).abs().powf(self.smoothness)
* (self.specular_strength / w_i.dot(&Vector3::z_axis()))
}
},
)
}
}