Bias shadow rays to fix noise in image
This commit is contained in:
parent
77cf877210
commit
5a0646aaa2
|
|
@ -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![
|
||||||
|
DirectionalLight {
|
||||||
direction: Vector3::new(convert(1.0), convert(1.0), convert(-1.0)).normalize(),
|
direction: Vector3::new(convert(1.0), convert(1.0), convert(-1.0)).normalize(),
|
||||||
colour: ColourRgbF::from_named(NamedColour::White) * directional_intensity,
|
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() {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue