Add Phong material
This commit is contained in:
parent
0a7963097c
commit
dbbd855c73
|
|
@ -1,5 +1,6 @@
|
||||||
use nalgebra::{convert, RealField, Vector3};
|
use nalgebra::{convert, RealField, Vector3};
|
||||||
|
|
||||||
|
use super::algebra_utils::try_change_of_basis_matrix;
|
||||||
use super::colour::ColourRgbF;
|
use super::colour::ColourRgbF;
|
||||||
use super::raycasting::{IntersectionInfo, Ray};
|
use super::raycasting::{IntersectionInfo, Ray};
|
||||||
use super::sampler::Sampler;
|
use super::sampler::Sampler;
|
||||||
|
|
@ -25,13 +26,19 @@ impl<T: RealField> Integrator<T> for WhittedIntegrator<T> {
|
||||||
self.lights
|
self.lights
|
||||||
.iter()
|
.iter()
|
||||||
.map(|light| {
|
.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
|
match sampler
|
||||||
.sample(&Ray::new(info.location, light.direction).bias(convert(0.000000001)))
|
.sample(&Ray::new(info.location, light.direction).bias(convert(0.000000001)))
|
||||||
{
|
{
|
||||||
Some(_) => self.ambient_light,
|
Some(_) => self.ambient_light,
|
||||||
None => {
|
None => {
|
||||||
info.material.bsdf()(info.retro, light.direction, light.colour)
|
info.material.bsdf()(
|
||||||
* light.direction.dot(&info.normal)
|
basis_change * info.retro,
|
||||||
|
basis_change * light.direction,
|
||||||
|
light.colour,
|
||||||
|
) * light.direction.dot(&info.normal).abs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod algebra_utils;
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
pub mod colour;
|
pub mod colour;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use std::rc::Rc;
|
||||||
use vanrijn::camera::partial_render_scene;
|
use vanrijn::camera::partial_render_scene;
|
||||||
use vanrijn::colour::{ColourRgbF, NamedColour};
|
use vanrijn::colour::{ColourRgbF, NamedColour};
|
||||||
use vanrijn::image::{ClampingToneMapper, ImageRgbF, ImageRgbU8, ToneMapper};
|
use vanrijn::image::{ClampingToneMapper, ImageRgbF, ImageRgbU8, ToneMapper};
|
||||||
use vanrijn::materials::LambertianMaterial;
|
use vanrijn::materials::{LambertianMaterial, PhongMaterial};
|
||||||
use vanrijn::raycasting::{Plane, Sphere};
|
use vanrijn::raycasting::{Plane, Sphere};
|
||||||
use vanrijn::scene::Scene;
|
use vanrijn::scene::Scene;
|
||||||
|
|
||||||
|
|
@ -88,9 +88,11 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
Box::new(Sphere::new(
|
Box::new(Sphere::new(
|
||||||
Vector3::new(0.0, 1.5, 6.0),
|
Vector3::new(0.0, 1.5, 6.0),
|
||||||
1.0,
|
1.0,
|
||||||
Rc::new(LambertianMaterial {
|
Rc::new(PhongMaterial {
|
||||||
colour: ColourRgbF::from_named(NamedColour::Red),
|
colour: ColourRgbF::from_named(NamedColour::Red),
|
||||||
diffuse_strength: 0.1,
|
diffuse_strength: 0.05,
|
||||||
|
smoothness: 20.0,
|
||||||
|
specular_strength: 250.0,
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use nalgebra::{RealField, Vector3};
|
use nalgebra::{RealField, Vector3};
|
||||||
|
|
||||||
use super::colour::ColourRgbF;
|
use super::colour::{ColourRgbF, NamedColour};
|
||||||
|
|
||||||
use std::fmt::Debug;
|
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()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue