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.
#[serde(flatten)]
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 {
@ -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<ReflTransEnum>,
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),
)
)
}

View file

@ -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<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 {
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)
}
}

View file

@ -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(),
))
)
}

View file

@ -104,6 +104,8 @@ impl TryFrom<Wavefront> 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<Wavefront> 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(),

View file

@ -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!(

View file

@ -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(),