From 34232bb7d3352b2a4b646fbaef1e74d48a649107 Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Fri, 3 Apr 2020 23:12:40 -0400 Subject: [PATCH] Refactor Bsdf to not store references to material struct members This complicated the Material trait with explicit lifetimes and had no real benefit. --- src/materials.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/materials.rs b/src/materials.rs index 8f6875e..f34829e 100644 --- a/src/materials.rs +++ b/src/materials.rs @@ -5,10 +5,10 @@ use crate::Real; use std::fmt::Debug; -type Bsdf<'a, T> = Box, Vector3, ColourRgbF) -> ColourRgbF + 'a>; +type Bsdf = Box, Vector3, ColourRgbF) -> ColourRgbF>; pub trait Material: Debug + Sync + Send { - fn bsdf<'a>(&'a self) -> Bsdf<'a, T>; + fn bsdf(&self) -> Bsdf; fn sample(&self, _w_o: &Vector3) -> Vec> { vec![] @@ -31,11 +31,10 @@ impl LambertianMaterial { } impl Material for LambertianMaterial { - fn bsdf<'a>(&'a self) -> Bsdf<'a, T> { + fn bsdf(&self) -> Bsdf { + let colour = self.colour * self.diffuse_strength; Box::new( - move |_w_o: Vector3, _w_i: Vector3, colour_in: ColourRgbF| { - self.colour * colour_in * self.diffuse_strength - }, + move |_w_o: Vector3, _w_i: Vector3, colour_in: ColourRgbF| colour * colour_in, ) } } @@ -49,17 +48,20 @@ pub struct PhongMaterial { } impl Material for PhongMaterial { - fn bsdf<'a>(&'a self) -> Bsdf<'a, T> { + fn bsdf(&self) -> Bsdf { + let smoothness = self.smoothness; + let specular_strength = self.specular_strength; + let colour = self.colour * self.diffuse_strength; Box::new( move |w_o: Vector3, w_i: Vector3, colour_in: ColourRgbF| { if w_i.z < T::zero() || w_o.z < T::zero() { ColourRgbF::from_vector3(&Vector3::zeros()) } else { let reflection_vector = Vector3::new(-w_i.x, -w_i.y, w_i.z); - self.colour * colour_in * self.diffuse_strength + colour * colour_in + ColourRgbF::from_named(NamedColour::White) - * w_o.dot(&reflection_vector).abs().powf(self.smoothness) - * (self.specular_strength / w_i.dot(&Vector3::z_axis())) + * w_o.dot(&reflection_vector).abs().powf(smoothness) + * (specular_strength / w_i.dot(&Vector3::z_axis())) } }, ) @@ -74,15 +76,17 @@ pub struct ReflectiveMaterial { } impl Material for ReflectiveMaterial { - fn bsdf<'a>(&'a self) -> Bsdf<'a, T> { + fn bsdf(&self) -> Bsdf { + let diffuse_colour_factor = self.colour * self.diffuse_strength; + let reflection_strength = self.reflection_strength; Box::new( move |w_o: Vector3, w_i: Vector3, colour_in: ColourRgbF| { if w_i.z < T::zero() || w_o.z < T::zero() { ColourRgbF::new(T::zero(), T::one(), T::one()) } else { let reflection_vector = Vector3::new(-w_o.x, -w_o.y, w_o.z); - let reflection_colour = colour_in * self.reflection_strength; - let diffuse_colour = self.colour * colour_in * self.diffuse_strength; + let reflection_colour = colour_in * reflection_strength; + let diffuse_colour = diffuse_colour_factor * colour_in; let sigma: T = convert(0.05); let two: T = convert(2.0); // These are normalized vectors, but sometimes rounding errors cause the