From 5cd80ae05c80c833854b66ef7137889775d41196 Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Fri, 29 Nov 2019 22:27:43 -0500 Subject: [PATCH] Add sample funtion to Material trait, with default implementation --- src/integrators.rs | 36 ++++++++++++++++++++++++++++++------ src/materials.rs | 4 ++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/integrators.rs b/src/integrators.rs index f473237..33b743a 100644 --- a/src/integrators.rs +++ b/src/integrators.rs @@ -23,25 +23,49 @@ pub struct WhittedIntegrator { // bounds and tangent direction impl Integrator for WhittedIntegrator { fn integrate(&self, sampler: &Sampler, info: &IntersectionInfo) -> ColourRgbF { + let world_to_bsdf_space = + try_change_of_basis_matrix(&info.tangent, &info.cotangent, &info.normal) + .expect("Normal, tangent and cotangent don't for a valid basis."); + let bsdf_to_world_space = world_to_bsdf_space + .try_inverse() + .expect("Expected matrix to be invertable."); self.lights .iter() .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 - .sample(&Ray::new(info.location, light.direction).bias(convert(0.000000001))) + .sample(&Ray::new(info.location, light.direction).bias(convert(0.0000001))) { Some(_) => self.ambient_light, None => { info.material.bsdf()( - basis_change * info.retro, - basis_change * light.direction, + world_to_bsdf_space * info.retro, + world_to_bsdf_space * light.direction, light.colour, ) * light.direction.dot(&info.normal).abs() } } }) + .chain( + info.material + .sample(&(world_to_bsdf_space * info.retro)) + .iter() + .map(|direction| { + let world_space_direction = bsdf_to_world_space * direction; + match sampler.sample( + &Ray::new(info.location, world_space_direction) + .bias(convert(0.0000001)), + ) { + Some(recursive_hit) => { + info.material.bsdf()( + world_to_bsdf_space * info.retro, + *direction, + self.integrate(&sampler, &recursive_hit), + ) * world_space_direction.dot(&info.normal).abs() + } + None => ColourRgbF::new(T::zero(), T::zero(), T::zero()), + } + }), + ) .fold(self.ambient_light, |a, b| a + b) } } diff --git a/src/materials.rs b/src/materials.rs index c7fcf59..f3bf3a1 100644 --- a/src/materials.rs +++ b/src/materials.rs @@ -8,6 +8,10 @@ pub trait Material: Debug { fn bsdf<'a>( &'a self, ) -> Box, Vector3, ColourRgbF) -> ColourRgbF + 'a>; + + fn sample(&self, _w_o: &Vector3) -> Vec> { + vec![] + } } #[derive(Debug)]