Add sample funtion to Material trait, with default implementation

This commit is contained in:
Matthew Gordon 2019-11-29 22:27:43 -05:00
parent dcee4fb716
commit 5cd80ae05c
2 changed files with 34 additions and 6 deletions

View File

@ -23,25 +23,49 @@ pub struct WhittedIntegrator<T: RealField> {
// bounds and tangent direction // bounds and tangent direction
impl<T: RealField> Integrator<T> for WhittedIntegrator<T> { 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> {
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 self.lights
.iter() .iter()
.map(|light| { .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 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, Some(_) => self.ambient_light,
None => { None => {
info.material.bsdf()( info.material.bsdf()(
basis_change * info.retro, world_to_bsdf_space * info.retro,
basis_change * light.direction, world_to_bsdf_space * light.direction,
light.colour, light.colour,
) * light.direction.dot(&info.normal).abs() ) * 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) .fold(self.ambient_light, |a, b| a + b)
} }
} }

View File

@ -8,6 +8,10 @@ pub trait Material<T: RealField>: Debug {
fn bsdf<'a>( fn bsdf<'a>(
&'a self, &'a self,
) -> Box<dyn Fn(Vector3<T>, Vector3<T>, ColourRgbF<T>) -> ColourRgbF<T> + 'a>; ) -> Box<dyn Fn(Vector3<T>, Vector3<T>, ColourRgbF<T>) -> ColourRgbF<T> + 'a>;
fn sample(&self, _w_o: &Vector3<T>) -> Vec<Vector3<T>> {
vec![]
}
} }
#[derive(Debug)] #[derive(Debug)]