use std::sync::Arc;
use spectrum::RGBSpectrumf;
use super::*;
use bxdf::prelude::*;
use bxdf::microfacet::roughness_to_alpha;
#[derive(Clone)]
pub struct TranslucentMaterial {
pub diffuse: Arc<Texture<Texel=RGBSpectrumf>>,
pub specular: Arc<Texture<Texel=RGBSpectrumf>>,
pub roughness: Arc<Texture<Texel=Float>>,
pub dissolve: Float,
pub bump: Option<Arc<Texture<Texel=Float>>>,
}
impl TranslucentMaterial {
pub fn new(
diffuse: Arc<Texture<Texel=RGBSpectrumf>>,
specular: Arc<Texture<Texel=RGBSpectrumf>>,
roughness: Arc<Texture<Texel=Float>>,
dissolve: Float,
bump: Option<Arc<Texture<Texel=Float>>>
) -> TranslucentMaterial {
TranslucentMaterial{
diffuse, specular, roughness, dissolve, bump
}
}
}
impl Material for TranslucentMaterial {
fn compute_scattering<'a>(
&self,
si: &mut SurfaceInteraction,
dxy: &DxyInfo,
alloc: &'a Allocator
) -> bsdf::Bsdf<'a> {
if let Some(ref bump) = self.bump {
add_bumping(si, dxy, &**bump);
}
let diffuse = self.diffuse.evaluate(si, dxy);
let specular = self.specular.evaluate(si, dxy);
let roughness = self.roughness.evaluate(si, dxy);
let alpha = roughness_to_alpha(roughness);
let mut ret = bsdf::Bsdf::new(si, 1.0 as Float);
if !relative_eq!(self.dissolve, 0. as Float) {
ret.add(alloc.alloc(
AshikhminShirleyBxdf::new(
diffuse*self.dissolve, specular*self.dissolve,
Trowbridge{
ax: alpha, ay: alpha
}
)
));
}
if !diffuse.is_black() {
ret.add(alloc.alloc(
LambertianTBxdf::new(
diffuse * (1.0 as Float - self.dissolve)
)
));
}
ret
}
}