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::image::ImageRgbF;
|
||||
use super::integrators::{DirectionalLight, Integrator, PhongIntegrator};
|
||||
use super::integrators::{DirectionalLight, Integrator, WhittedIntegrator};
|
||||
use super::raycasting::Ray;
|
||||
use super::sampler::Sampler;
|
||||
use super::scene::Scene;
|
||||
|
|
@ -69,13 +69,20 @@ pub fn render_scene<T: RealField>(output_image: &mut ImageRgbF<T>, scene: &Scene
|
|||
scene.camera_location,
|
||||
);
|
||||
let ambient_intensity: T = convert(0.0);
|
||||
let directional_intensity: T = convert(0.9);
|
||||
let integrator = PhongIntegrator::<T> {
|
||||
let directional_intensity1: T = convert(0.7);
|
||||
let directional_intensity2: T = convert(0.3);
|
||||
let integrator = WhittedIntegrator::<T> {
|
||||
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(),
|
||||
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 };
|
||||
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::raycasting::{IntersectionInfo, Ray};
|
||||
|
|
@ -13,24 +13,28 @@ pub struct DirectionalLight<T: RealField> {
|
|||
pub colour: ColourRgbF<T>,
|
||||
}
|
||||
|
||||
pub struct PhongIntegrator<T: RealField> {
|
||||
pub struct WhittedIntegrator<T: RealField> {
|
||||
pub ambient_light: ColourRgbF<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> {
|
||||
self.lights
|
||||
.iter()
|
||||
.map(
|
||||
|light| match sampler.sample(&Ray::new(info.location, light.direction)) {
|
||||
.map(|light| {
|
||||
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)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
.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> {
|
||||
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)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue