use super::*;
#[derive(Copy, Clone, Debug)]
pub struct LambertianRBxdf {
pub reflectance: RGBSpectrumf,
}
impl LambertianRBxdf {
pub fn new(reflectance: RGBSpectrumf) -> LambertianRBxdf {
LambertianRBxdf{
reflectance: reflectance
}
}
}
impl Bxdf for LambertianRBxdf {
#[inline]
fn kind(&self) -> BxdfType {
BXDF_REFLECTION | BXDF_DIFFUSE
}
#[inline]
fn evaluate(&self, _wo: Vector3f, _wi: Vector3f) -> RGBSpectrumf {
self.reflectance * float::frac_1_pi()
}
#[inline]
fn rho_hd(&self, _wo: Vector3f, _samples: &[Point2f]) -> RGBSpectrumf {
self.reflectance
}
#[inline]
fn rho_hh(&self, _samples0: &[Point2f], _samples1: &[Point2f]) -> RGBSpectrumf {
self.reflectance
}
}
#[derive(Copy, Clone, Debug)]
pub struct LambertianTBxdf {
pub transmittance: RGBSpectrumf,
}
impl LambertianTBxdf {
pub fn new(transmittance: RGBSpectrumf) -> LambertianTBxdf {
LambertianTBxdf{
transmittance
}
}
}
impl Bxdf for LambertianTBxdf {
#[inline]
fn kind(&self) -> BxdfType {
BXDF_TRANSMISSION | BXDF_DIFFUSE
}
#[inline]
fn evaluate(&self, _wo: Vector3f, _wi: Vector3f) -> RGBSpectrumf {
self.transmittance * float::frac_1_pi()
}
#[inline]
fn rho_hd(&self, _wo: Vector3f, _samples: &[Point2f]) -> RGBSpectrumf {
self.transmittance
}
#[inline]
fn rho_hh(&self, _samples0: &[Point2f], _samples1: &[Point2f]) -> RGBSpectrumf {
self.transmittance
}
#[inline]
fn evaluate_sampled(&self, wo: Vector3f, u: Point2f
) -> (RGBSpectrumf, Vector3f, Float, BxdfType) {
let mut wi = sample::sample_cosw_hemisphere(u);
if wo.z > 0.0 as Float {wi.z = -wi.z;}
let pdf = self.pdf(wo, wi);
let spectrum = self.evaluate(wo, wi);
(spectrum, wi, pdf, self.kind())
}
#[inline]
fn pdf(&self, wo: Vector3f, wi: Vector3f) -> Float {
if wo.z * wi.z >= 0. as Float {
0. as Float
} else {
normal::cos_theta(wi).abs() * float::frac_1_pi()
}
}
}