Factor out Sampler struct and add shadow casting
There are now bad rendering artifacts which I believe are caused by precision issues.
This commit is contained in:
parent
cefbc2873b
commit
77cf877210
|
|
@ -4,6 +4,7 @@ use super::colour::{ColourRgbF, NamedColour};
|
|||
use super::image::ImageRgbF;
|
||||
use super::integrators::{DirectionalLight, Integrator, PhongIntegrator};
|
||||
use super::raycasting::Ray;
|
||||
use super::sampler::Sampler;
|
||||
use super::scene::Scene;
|
||||
|
||||
struct ImageSampler<T: RealField> {
|
||||
|
|
@ -61,7 +62,7 @@ impl<T: RealField> ImageSampler<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn render_scene<'a, T: RealField>(output_image: &mut ImageRgbF<T>, scene: &Scene<T>) {
|
||||
pub fn render_scene<T: RealField>(output_image: &mut ImageRgbF<T>, scene: &Scene<T>) {
|
||||
let image_sampler = ImageSampler::new(
|
||||
output_image.get_width(),
|
||||
output_image.get_height(),
|
||||
|
|
@ -76,22 +77,14 @@ pub fn render_scene<'a, T: RealField>(output_image: &mut ImageRgbF<T>, scene: &S
|
|||
colour: ColourRgbF::from_named(NamedColour::White) * directional_intensity,
|
||||
}],
|
||||
};
|
||||
let sampler = Sampler { scene };
|
||||
for column in 0..output_image.get_width() {
|
||||
for row in 0..output_image.get_height() {
|
||||
let ray = image_sampler.ray_for_pixel(row, column);
|
||||
let hit = scene
|
||||
.objects
|
||||
.iter()
|
||||
.flat_map(|object| object.intersect(&ray))
|
||||
.min_by(
|
||||
|a, b| match PartialOrd::partial_cmp(&a.distance, &b.distance) {
|
||||
None => std::cmp::Ordering::Less,
|
||||
Some(ordering) => ordering,
|
||||
},
|
||||
);
|
||||
let hit = sampler.sample(&ray);
|
||||
let colour = match hit {
|
||||
None => ColourRgbF::from_named(NamedColour::Black),
|
||||
Some(intersection_info) => integrator.integrate(&intersection_info),
|
||||
Some(intersection_info) => integrator.integrate(&sampler, &intersection_info),
|
||||
};
|
||||
output_image.set_colour(row, column, colour);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use nalgebra::{RealField, Vector3};
|
||||
|
||||
use super::colour::ColourRgbF;
|
||||
use super::raycasting::IntersectionInfo;
|
||||
use super::raycasting::{IntersectionInfo, Ray};
|
||||
use super::sampler::Sampler;
|
||||
|
||||
pub trait Integrator<T: RealField> {
|
||||
fn integrate(&self, info: &IntersectionInfo<T>) -> ColourRgbF<T>;
|
||||
fn integrate(&self, sampler: &Sampler<T>, info: &IntersectionInfo<T>) -> ColourRgbF<T>;
|
||||
}
|
||||
|
||||
pub struct DirectionalLight<T: RealField> {
|
||||
|
|
@ -18,13 +19,18 @@ pub struct PhongIntegrator<T: RealField> {
|
|||
}
|
||||
|
||||
impl<T: RealField> Integrator<T> for PhongIntegrator<T> {
|
||||
fn integrate(&self, info: &IntersectionInfo<T>) -> ColourRgbF<T> {
|
||||
fn integrate(&self, sampler: &Sampler<T>, info: &IntersectionInfo<T>) -> ColourRgbF<T> {
|
||||
self.lights
|
||||
.iter()
|
||||
.map(|light| {
|
||||
.map(
|
||||
|light| match sampler.sample(&Ray::new(info.location, light.direction)) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@ pub mod image;
|
|||
pub mod integrators;
|
||||
pub mod materials;
|
||||
pub mod raycasting;
|
||||
pub mod sampler;
|
||||
pub mod scene;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
use super::raycasting::{IntersectionInfo, Ray};
|
||||
use super::scene::Scene;
|
||||
|
||||
use nalgebra::RealField;
|
||||
|
||||
pub struct Sampler<'a, T: RealField> {
|
||||
pub scene: &'a Scene<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: RealField> Sampler<'a, T> {
|
||||
pub fn sample(&self, ray: &Ray<T>) -> Option<IntersectionInfo<T>> {
|
||||
self.scene
|
||||
.objects
|
||||
.iter()
|
||||
.flat_map(|object| object.intersect(&ray))
|
||||
.min_by(
|
||||
|a, b| match PartialOrd::partial_cmp(&a.distance, &b.distance) {
|
||||
None => std::cmp::Ordering::Less,
|
||||
Some(ordering) => ordering,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue