library: core: light_properties: add emitted light

This commit is contained in:
Bruno BELANYI 2020-04-01 23:43:01 +02:00
parent 7eefd7b574
commit 96995e7ef1
6 changed files with 61 additions and 14 deletions

View file

@ -33,6 +33,9 @@ pub struct LightProperties {
/// The transparency or reflectivity properties. /// The transparency or reflectivity properties.
#[serde(flatten)] #[serde(flatten)]
pub refl_trans: Option<ReflTransEnum>, pub refl_trans: Option<ReflTransEnum>,
/// The emitted light from this object, only used for path-tracing rendering techniques
#[serde(default)]
pub emitted: LinearColor,
} }
impl LightProperties { impl LightProperties {
@ -48,17 +51,20 @@ impl LightProperties {
/// LinearColor::new(0.25, 0.5, 1.), /// LinearColor::new(0.25, 0.5, 1.),
/// LinearColor::new(0.75, 0.375, 0.125), /// LinearColor::new(0.75, 0.375, 0.125),
/// Some(ReflTransEnum::Reflectivity { coef: 0.5 }), /// Some(ReflTransEnum::Reflectivity { coef: 0.5 }),
/// LinearColor::new(0., 0., 0.),
/// ); /// );
/// ``` /// ```
pub fn new( pub fn new(
diffuse: LinearColor, diffuse: LinearColor,
specular: LinearColor, specular: LinearColor,
refl_trans: Option<ReflTransEnum>, refl_trans: Option<ReflTransEnum>,
emitted: LinearColor,
) -> Self { ) -> Self {
LightProperties { LightProperties {
diffuse, diffuse,
specular, specular,
refl_trans, refl_trans,
emitted,
} }
} }
} }
@ -72,14 +78,20 @@ mod test {
let diffuse = LinearColor::new(0.25, 0.5, 1.); let diffuse = LinearColor::new(0.25, 0.5, 1.);
let specular = LinearColor::new(0.75, 0.375, 0.125); let specular = LinearColor::new(0.75, 0.375, 0.125);
let refl_trans = Some(ReflTransEnum::Reflectivity { coef: 0.5 }); let refl_trans = Some(ReflTransEnum::Reflectivity { coef: 0.5 });
let properties = let emitted = LinearColor::new(0., 1., 0.);
LightProperties::new(diffuse.clone(), specular.clone(), refl_trans.clone()); let properties = LightProperties::new(
diffuse.clone(),
specular.clone(),
refl_trans.clone(),
emitted.clone(),
);
assert_eq!( assert_eq!(
properties, properties,
LightProperties { LightProperties {
diffuse, diffuse,
specular, specular,
refl_trans, refl_trans,
emitted,
} }
) )
} }
@ -96,7 +108,8 @@ mod test {
LightProperties::new( LightProperties::new(
LinearColor::new(1., 0.5, 0.25), LinearColor::new(1., 0.5, 0.25),
LinearColor::new(0.25, 0.125, 0.75), LinearColor::new(0.25, 0.125, 0.75),
None None,
LinearColor::black(),
) )
) )
} }
@ -118,7 +131,8 @@ mod test {
Some(ReflTransEnum::Transparency { Some(ReflTransEnum::Transparency {
coef: 0.5, coef: 0.5,
index: 1.5 index: 1.5
}) }),
LinearColor::black(),
) )
) )
} }
@ -136,7 +150,27 @@ mod test {
LightProperties::new( LightProperties::new(
LinearColor::new(1., 0.5, 0.25), LinearColor::new(1., 0.5, 0.25),
LinearColor::new(0.25, 0.125, 0.75), 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),
) )
) )
} }

View file

@ -12,19 +12,21 @@ pub struct TriangleMaterial {
specular: [LinearColor; 3], specular: [LinearColor; 3],
/// The transparency or reflectivity properties, this is not interpolated. /// The transparency or reflectivity properties, this is not interpolated.
#[serde(flatten)] #[serde(flatten)]
pub refl_trans: Option<ReflTransEnum>, refl_trans: Option<ReflTransEnum>,
/// The amount of light emitted by the material, only used during path-tracing rendering.
emitted: [LinearColor; 3],
} }
impl Material for TriangleMaterial { impl Material for TriangleMaterial {
fn properties(&self, point: Point2D) -> LightProperties { fn properties(&self, point: Point2D) -> LightProperties {
let (u, v) = (point.x, point.y); let (u, v) = (point.x, point.y);
let diffuse = self.diffuse[0].clone() * (1. - u - v) let sample = |param: &[LinearColor; 3]| -> LinearColor {
+ self.diffuse[1].clone() * u param[0].clone() * (1. - u - v) + param[1].clone() * u + param[2].clone() * v
+ self.diffuse[2].clone() * v; };
let specular = self.specular[0].clone() * (1. - u - v) let diffuse = sample(&self.diffuse);
+ self.specular[1].clone() * u let specular = sample(&self.specular);
+ self.specular[2].clone() * v; let emitted = sample(&self.emitted);
LightProperties::new(diffuse, specular, self.refl_trans.clone()) LightProperties::new(diffuse, specular, self.refl_trans.clone(), emitted)
} }
} }

View file

@ -24,6 +24,7 @@ impl UniformMaterial {
/// LinearColor::new(1.0, 0.0, 0.0), // diffuse component /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component
/// LinearColor::new(0.0, 0.0, 0.0), // specular component /// LinearColor::new(0.0, 0.0, 0.0), // specular component
/// None, /// None,
/// LinearColor::black(), // Emitted light
/// ), /// ),
/// ); /// );
/// ``` /// ```
@ -50,6 +51,7 @@ mod test {
diffuse: LinearColor::new(0., 0.5, 0.), diffuse: LinearColor::new(0., 0.5, 0.),
specular: LinearColor::new(1., 1., 1.), specular: LinearColor::new(1., 1., 1.),
refl_trans: None, refl_trans: None,
emitted: LinearColor::black(),
}; };
let mat = UniformMaterial::new(properties.clone()); let mat = UniformMaterial::new(properties.clone());
assert_eq!(mat, UniformMaterial { properties }) assert_eq!(mat, UniformMaterial { properties })
@ -61,6 +63,7 @@ mod test {
LinearColor::new(0., 0.5, 0.), LinearColor::new(0., 0.5, 0.),
LinearColor::new(1., 1., 1.), LinearColor::new(1., 1., 1.),
None, None,
LinearColor::black(),
); );
let mat = UniformMaterial::new(properties.clone()); let mat = UniformMaterial::new(properties.clone());
assert_eq!(mat.properties(Point2D::origin()), properties) assert_eq!(mat.properties(Point2D::origin()), properties)
@ -79,7 +82,8 @@ mod test {
UniformMaterial::new(LightProperties::new( UniformMaterial::new(LightProperties::new(
LinearColor::new(1., 0.5, 0.25), LinearColor::new(1., 0.5, 0.25),
LinearColor::new(0.25, 0.125, 0.75), LinearColor::new(0.25, 0.125, 0.75),
Some(ReflTransEnum::Reflectivity { coef: 0.25 }) Some(ReflTransEnum::Reflectivity { coef: 0.25 }),
LinearColor::black(),
)) ))
) )
} }

View file

@ -104,6 +104,8 @@ impl TryFrom<Wavefront> for Mesh {
// FIXME: material.dissolve is supposed to be "the alpha term" // FIXME: material.dissolve is supposed to be "the alpha term"
// Needs translation to our ReflTransEnum // Needs translation to our ReflTransEnum
None, None,
// FIXME: parse 'Ke' component for emitted light
LinearColor::black(),
)); ));
// we only handle uniform textures // we only handle uniform textures
@ -118,6 +120,7 @@ impl TryFrom<Wavefront> for Mesh {
LinearColor::new(0.5, 0.5, 0.5), LinearColor::new(0.5, 0.5, 0.5),
LinearColor::new(0.1, 0.1, 0.1), LinearColor::new(0.1, 0.1, 0.1),
None, None,
LinearColor::black(),
)) ))
.into(), .into(),
UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(), UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(),

View file

@ -42,6 +42,7 @@ impl Object {
/// LinearColor::new(1.0, 0.0, 0.0), // diffuse component /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component
/// LinearColor::new(0.0, 0.0, 0.0), // specular component /// LinearColor::new(0.0, 0.0, 0.0), // specular component
/// None, /// None,
/// LinearColor::black(), // Emitted light
/// ), /// ),
/// ).into(), /// ).into(),
/// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).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(0.5, 0.5, 0.5),
LinearColor::new(1., 1., 1.), LinearColor::new(1., 1., 1.),
None, None,
LinearColor::black(),
)); ));
let texture = UniformTexture::new(LinearColor::new(0.25, 0.5, 1.)); let texture = UniformTexture::new(LinearColor::new(0.25, 0.5, 1.));
Object::new(shape.into(), material.into(), texture.into()) Object::new(shape.into(), material.into(), texture.into())
@ -99,6 +101,7 @@ mod test {
LinearColor::new(0.5, 0.5, 0.5), LinearColor::new(0.5, 0.5, 0.5),
LinearColor::new(1., 1., 1.), LinearColor::new(1., 1., 1.),
None, None,
LinearColor::black(),
)); ));
let texture = UniformTexture::new(LinearColor::new(0.25, 0.5, 1.)); let texture = UniformTexture::new(LinearColor::new(0.25, 0.5, 1.));
assert_eq!( assert_eq!(

View file

@ -43,6 +43,7 @@ impl Scene {
/// LinearColor::new(1.0, 0.0, 0.0), // diffuse component /// LinearColor::new(1.0, 0.0, 0.0), // diffuse component
/// LinearColor::new(0.0, 0.0, 0.0), // specular component /// LinearColor::new(0.0, 0.0, 0.0), // specular component
/// None, /// None,
/// LinearColor::black(), // Emitted light
/// ), /// ),
/// ).into(), /// ).into(),
/// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(), /// UniformTexture::new(LinearColor::new(0.5, 0.5, 0.5)).into(),