diff --git a/pathtracer/src/core/light_properties.rs b/pathtracer/src/core/light_properties.rs index 9cc6bcc..6a75319 100644 --- a/pathtracer/src/core/light_properties.rs +++ b/pathtracer/src/core/light_properties.rs @@ -33,6 +33,9 @@ pub struct LightProperties { /// The transparency or reflectivity properties. #[serde(flatten)] pub refl_trans: Option, + /// The emitted light from this object, only used for path-tracing rendering techniques + #[serde(default)] + pub emitted: LinearColor, } impl LightProperties { @@ -48,17 +51,20 @@ impl LightProperties { /// LinearColor::new(0.25, 0.5, 1.), /// LinearColor::new(0.75, 0.375, 0.125), /// Some(ReflTransEnum::Reflectivity { coef: 0.5 }), + /// LinearColor::new(0., 0., 0.), /// ); /// ``` pub fn new( diffuse: LinearColor, specular: LinearColor, refl_trans: Option, + emitted: LinearColor, ) -> Self { LightProperties { diffuse, specular, refl_trans, + emitted, } } } @@ -72,14 +78,20 @@ mod test { let diffuse = LinearColor::new(0.25, 0.5, 1.); let specular = LinearColor::new(0.75, 0.375, 0.125); let refl_trans = Some(ReflTransEnum::Reflectivity { coef: 0.5 }); - let properties = - LightProperties::new(diffuse.clone(), specular.clone(), refl_trans.clone()); + let emitted = LinearColor::new(0., 1., 0.); + let properties = LightProperties::new( + diffuse.clone(), + specular.clone(), + refl_trans.clone(), + emitted.clone(), + ); assert_eq!( properties, LightProperties { diffuse, specular, refl_trans, + emitted, } ) } @@ -96,7 +108,8 @@ mod test { LightProperties::new( LinearColor::new(1., 0.5, 0.25), LinearColor::new(0.25, 0.125, 0.75), - None + None, + LinearColor::black(), ) ) } @@ -118,7 +131,8 @@ mod test { Some(ReflTransEnum::Transparency { coef: 0.5, index: 1.5 - }) + }), + LinearColor::black(), ) ) } @@ -136,7 +150,27 @@ mod test { LightProperties::new( LinearColor::new(1., 0.5, 0.25), LinearColor::new(0.25, 0.125, 0.75), - Some(ReflTransEnum::Reflectivity { coef: 0.25 }) + Some(ReflTransEnum::Reflectivity { coef: 0.25 }), + LinearColor::black(), + ) + ) + } + + #[test] + fn deserialization_with_emitted_works() { + let yaml = r#" + diffuse: {r: 1.0, g: 0.5, b: 0.25} + specular: {r: 0.25, g: 0.125, b: 0.75} + emitted: {r: 0.25, g: 0.5, b: 1.0} + "#; + let properties: LightProperties = serde_yaml::from_str(yaml).unwrap(); + assert_eq!( + properties, + LightProperties::new( + LinearColor::new(1., 0.5, 0.25), + LinearColor::new(0.25, 0.125, 0.75), + None, + LinearColor::new(0.25, 0.5, 1.0), ) ) } diff --git a/pathtracer/src/material/triangle.rs b/pathtracer/src/material/triangle.rs index 72790f2..66a0b72 100644 --- a/pathtracer/src/material/triangle.rs +++ b/pathtracer/src/material/triangle.rs @@ -12,19 +12,21 @@ pub struct TriangleMaterial { specular: [LinearColor; 3], /// The transparency or reflectivity properties, this is not interpolated. #[serde(flatten)] - pub refl_trans: Option, + refl_trans: Option, + /// The amount of light emitted by the material, only used during path-tracing rendering. + emitted: [LinearColor; 3], } impl Material for TriangleMaterial { fn properties(&self, point: Point2D) -> LightProperties { let (u, v) = (point.x, point.y); - let diffuse = self.diffuse[0].clone() * (1. - u - v) - + self.diffuse[1].clone() * u - + self.diffuse[2].clone() * v; - let specular = self.specular[0].clone() * (1. - u - v) - + self.specular[1].clone() * u - + self.specular[2].clone() * v; - LightProperties::new(diffuse, specular, self.refl_trans.clone()) + let sample = |param: &[LinearColor; 3]| -> LinearColor { + param[0].clone() * (1. - u - v) + param[1].clone() * u + param[2].clone() * v + }; + let diffuse = sample(&self.diffuse); + let specular = sample(&self.specular); + let emitted = sample(&self.emitted); + LightProperties::new(diffuse, specular, self.refl_trans.clone(), emitted) } } diff --git a/pathtracer/src/material/uniform.rs b/pathtracer/src/material/uniform.rs index 93fff05..030dd36 100644 --- a/pathtracer/src/material/uniform.rs +++ b/pathtracer/src/material/uniform.rs @@ -24,6 +24,7 @@ impl UniformMaterial { /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component /// LinearColor::new(0.0, 0.0, 0.0), // specular component /// None, + /// LinearColor::black(), // Emitted light /// ), /// ); /// ``` @@ -50,6 +51,7 @@ mod test { diffuse: LinearColor::new(0., 0.5, 0.), specular: LinearColor::new(1., 1., 1.), refl_trans: None, + emitted: LinearColor::black(), }; let mat = UniformMaterial::new(properties.clone()); assert_eq!(mat, UniformMaterial { properties }) @@ -61,6 +63,7 @@ mod test { LinearColor::new(0., 0.5, 0.), LinearColor::new(1., 1., 1.), None, + LinearColor::black(), ); let mat = UniformMaterial::new(properties.clone()); assert_eq!(mat.properties(Point2D::origin()), properties) @@ -79,7 +82,8 @@ mod test { UniformMaterial::new(LightProperties::new( LinearColor::new(1., 0.5, 0.25), LinearColor::new(0.25, 0.125, 0.75), - Some(ReflTransEnum::Reflectivity { coef: 0.25 }) + Some(ReflTransEnum::Reflectivity { coef: 0.25 }), + LinearColor::black(), )) ) } diff --git a/pathtracer/src/scene/mesh.rs b/pathtracer/src/scene/mesh.rs index 3080c9c..d04cb4c 100644 --- a/pathtracer/src/scene/mesh.rs +++ b/pathtracer/src/scene/mesh.rs @@ -104,6 +104,8 @@ impl TryFrom for Mesh { // FIXME: material.dissolve is supposed to be "the alpha term" // Needs translation to our ReflTransEnum None, + // FIXME: parse 'Ke' component for emitted light + LinearColor::black(), )); // we only handle uniform textures @@ -118,6 +120,7 @@ impl TryFrom for Mesh { LinearColor::new(0.5, 0.5, 0.5), LinearColor::new(0.1, 0.1, 0.1), None, + LinearColor::black(), )) .into(), UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(), diff --git a/pathtracer/src/scene/object.rs b/pathtracer/src/scene/object.rs index 21720d9..19a2585 100644 --- a/pathtracer/src/scene/object.rs +++ b/pathtracer/src/scene/object.rs @@ -42,6 +42,7 @@ impl Object { /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component /// LinearColor::new(0.0, 0.0, 0.0), // specular component /// None, + /// LinearColor::black(), // Emitted light /// ), /// ).into(), /// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(), @@ -87,6 +88,7 @@ mod test { LinearColor::new(0.5, 0.5, 0.5), LinearColor::new(1., 1., 1.), None, + LinearColor::black(), )); let texture = UniformTexture::new(LinearColor::new(0.25, 0.5, 1.)); Object::new(shape.into(), material.into(), texture.into()) @@ -99,6 +101,7 @@ mod test { LinearColor::new(0.5, 0.5, 0.5), LinearColor::new(1., 1., 1.), None, + LinearColor::black(), )); let texture = UniformTexture::new(LinearColor::new(0.25, 0.5, 1.)); assert_eq!( diff --git a/pathtracer/src/scene/scene.rs b/pathtracer/src/scene/scene.rs index 6bf9386..c4165d2 100644 --- a/pathtracer/src/scene/scene.rs +++ b/pathtracer/src/scene/scene.rs @@ -43,6 +43,7 @@ impl Scene { /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component /// LinearColor::new(0.0, 0.0, 0.0), // specular component /// None, + /// LinearColor::black(), // Emitted light /// ), /// ).into(), /// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(),