use super::*;
use super::fresnel::*;
use spectrum::Spectrum;
#[derive(Clone, Copy, Debug)]
pub struct SpecularRBxdf<F> {
pub reflectance: RGBSpectrumf,
pub fresnel: F,
}
impl<F: Fresnel> SpecularRBxdf<F> {
#[inline]
pub fn new(reflectance: RGBSpectrumf, fresnel: F) -> SpecularRBxdf<F> {
SpecularRBxdf{
reflectance: reflectance, fresnel: fresnel
}
}
}
impl<T: Fresnel> Bxdf for SpecularRBxdf<T> {
#[inline]
fn kind(&self) -> BxdfType {
BXDF_REFLECTION | BXDF_SPECULAR
}
#[inline]
fn evaluate(&self, _wo: Vector3f, _wi: Vector3f) -> RGBSpectrumf {
RGBSpectrumf::black()
}
#[inline]
fn evaluate_sampled(&self, wo: Vector3f, _sample: Point2f) -> (RGBSpectrumf, Vector3f, Float, BxdfType) {
let r = Vector3f::new(-wo.x, -wo.y, wo.z);
let cos = normal::cos_theta(r);
let s = self.fresnel.evaluate(cos) * self.reflectance / cos.abs();
(s, r, 1.0 as Float, self.kind())
}
}
#[derive(Copy, Clone, Debug)]
pub struct SpecularTBxdf {
pub transmittance: RGBSpectrumf,
pub fresnel: Dielectric,
}
impl SpecularTBxdf {
pub fn new(transmittance: RGBSpectrumf, eta_a: Float, eta_b: Float) -> SpecularTBxdf {
SpecularTBxdf{
transmittance: transmittance,
fresnel: Dielectric::new(eta_a, eta_b),
}
}
}
impl Bxdf for SpecularTBxdf {
#[inline]
fn kind(&self) -> BxdfType {
BXDF_TRANSMISSION | BXDF_SPECULAR
}
#[inline]
fn evaluate(&self, _wo: Vector3f, _wi: Vector3f) -> RGBSpectrumf {
RGBSpectrumf::black()
}
#[inline]
fn evaluate_sampled(&self, wo: Vector3f, _sample: Point2f) -> (RGBSpectrumf, Vector3f, Float, BxdfType) {
let r = Vector3f::new(-wo.x, -wo.y, wo.z);
let cos = normal::cos_theta(r);
let t = RGBSpectrumf::grey_scale(1.0 as Float) - self.fresnel.evaluate(cos);
(t*self.transmittance/cos.abs(), r, 1.0 as Float, self.kind())
}
#[inline]
fn rho_hh(&self, _samples0: &[Point2f], _samples1: &[Point2f]) -> RGBSpectrumf {
unimplemented!();
}
}