Bias shadow rays to fix noise in image

This commit is contained in:
Matthew Gordon 2019-11-23 22:08:50 -05:00
parent 77cf877210
commit 5a0646aaa2
3 changed files with 29 additions and 14 deletions

View File

@ -2,7 +2,7 @@ use nalgebra::{convert, RealField, Vector3};
use super::colour::{ColourRgbF, NamedColour}; use super::colour::{ColourRgbF, NamedColour};
use super::image::ImageRgbF; use super::image::ImageRgbF;
use super::integrators::{DirectionalLight, Integrator, PhongIntegrator}; use super::integrators::{DirectionalLight, Integrator, WhittedIntegrator};
use super::raycasting::Ray; use super::raycasting::Ray;
use super::sampler::Sampler; use super::sampler::Sampler;
use super::scene::Scene; use super::scene::Scene;
@ -69,13 +69,20 @@ pub fn render_scene<T: RealField>(output_image: &mut ImageRgbF<T>, scene: &Scene
scene.camera_location, scene.camera_location,
); );
let ambient_intensity: T = convert(0.0); let ambient_intensity: T = convert(0.0);
let directional_intensity: T = convert(0.9); let directional_intensity1: T = convert(0.7);
let integrator = PhongIntegrator::<T> { let directional_intensity2: T = convert(0.3);
let integrator = WhittedIntegrator::<T> {
ambient_light: ColourRgbF::from_named(NamedColour::White) * ambient_intensity, ambient_light: ColourRgbF::from_named(NamedColour::White) * ambient_intensity,
lights: vec![DirectionalLight { lights: vec![
direction: Vector3::new(convert(1.0), convert(1.0), convert(-1.0)).normalize(), DirectionalLight {
colour: ColourRgbF::from_named(NamedColour::White) * directional_intensity, direction: Vector3::new(convert(1.0), convert(1.0), convert(-1.0)).normalize(),
}], colour: ColourRgbF::from_named(NamedColour::White) * directional_intensity1,
},
DirectionalLight {
direction: Vector3::new(convert(-0.5), convert(2.0), convert(-0.5)).normalize(),
colour: ColourRgbF::from_named(NamedColour::White) * directional_intensity2,
},
],
}; };
let sampler = Sampler { scene }; let sampler = Sampler { scene };
for column in 0..output_image.get_width() { for column in 0..output_image.get_width() {

View File

@ -1,4 +1,4 @@
use nalgebra::{RealField, Vector3}; use nalgebra::{convert, RealField, Vector3};
use super::colour::ColourRgbF; use super::colour::ColourRgbF;
use super::raycasting::{IntersectionInfo, Ray}; use super::raycasting::{IntersectionInfo, Ray};
@ -13,24 +13,28 @@ pub struct DirectionalLight<T: RealField> {
pub colour: ColourRgbF<T>, pub colour: ColourRgbF<T>,
} }
pub struct PhongIntegrator<T: RealField> { pub struct WhittedIntegrator<T: RealField> {
pub ambient_light: ColourRgbF<T>, pub ambient_light: ColourRgbF<T>,
pub lights: Vec<DirectionalLight<T>>, pub lights: Vec<DirectionalLight<T>>,
} }
impl<T: RealField> Integrator<T> for PhongIntegrator<T> { // TODO: Get rid of the magic bias number, which should be calculated base on expected error
// bounds and tangent direction
impl<T: RealField> Integrator<T> for WhittedIntegrator<T> {
fn integrate(&self, sampler: &Sampler<T>, info: &IntersectionInfo<T>) -> ColourRgbF<T> { fn integrate(&self, sampler: &Sampler<T>, info: &IntersectionInfo<T>) -> ColourRgbF<T> {
self.lights self.lights
.iter() .iter()
.map( .map(|light| {
|light| match sampler.sample(&Ray::new(info.location, light.direction)) { match sampler
.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()(info.retro, light.direction, light.colour)
* light.direction.dot(&info.normal) * light.direction.dot(&info.normal)
} }
}, }
) })
.fold(self.ambient_light, |a, b| a + b) .fold(self.ambient_light, |a, b| a + b)
} }
} }

View File

@ -21,6 +21,10 @@ impl<T: RealField> Ray<T> {
pub fn point_at(&self, t: T) -> Vector3<T> { pub fn point_at(&self, t: T) -> Vector3<T> {
return self.origin + self.direction * t; return self.origin + self.direction * t;
} }
pub fn bias(&self, amount: T) -> Ray<T> {
Ray::new(self.origin + self.direction * amount, self.direction)
}
} }
#[derive(Debug)] #[derive(Debug)]