use geometry::prelude::*;
use texturing::*;
use aren_alloc::Allocator;
use std::sync::Arc;
pub trait Material: Sync + Send {
fn compute_scattering<'a>(
&self,
si: &mut SurfaceInteraction,
dxy: &DxyInfo,
alloc: &'a Allocator
) -> bsdf::Bsdf<'a>;
}
impl<T: Material + ?Sized> Material for Arc<T> {
#[inline]
fn compute_scattering<'a>(
&self,
si: &mut SurfaceInteraction,
dxy: &DxyInfo,
alloc: &'a Allocator
) -> bsdf::Bsdf<'a> {
<T as Material>::compute_scattering(
&*self, si, dxy, alloc
)
}
}
fn add_bumping<T: Texture<Texel=Float> + ?Sized>(
si: &mut SurfaceInteraction, dxy: &DxyInfo, bump: &T
) {
let mut sie = si.clone();
let du = {
let mut du = 0.5 as Float * (dxy.dudx.abs() + dxy.dudy.abs());
if du == 0.0 as Float { du = 0.0005 as Float; }
sie.basic.pos = si.basic.pos + du * si.shading_duv.dpdu;
sie.uv.x = si.uv.x + du;
sie.basic.norm = (si.shading_duv.dpdu.cross(si.shading_duv.dpdv) + du * si.duv.dndu).normalize();
du
};
let displacement_u = bump.evaluate(&sie, dxy);
let dv = {
let mut dv = 0.5 as Float * (dxy.dvdx.abs() + dxy.dvdy.abs());
if dv == 0.0 as Float { dv = 0.0005 as Float; }
sie.basic.pos = si.basic.pos + dv * si.shading_duv.dpdv;
sie.uv.y = si.uv.y + dv;
sie.basic.norm = (si.shading_duv.dpdu.cross(si.shading_duv.dpdv) + dv * si.duv.dndv).normalize();
dv
};
let displacement_v = bump.evaluate(&sie, dxy);
let displacement = bump.evaluate(si, dxy);
let dpdu = si.shading_duv.dpdu + (displacement_u - displacement) / du * si.shading_norm + displacement * si.shading_duv.dndu; let dpdv = si.shading_duv.dpdv + (displacement_v - displacement) / dv * si.shading_norm + displacement * si.shading_duv.dndv;
let duvinfo = DuvInfo{
dpdu: dpdu,
dpdv: dpdv,
dndu: si.shading_duv.dndu,
dndv: si.shading_duv.dndv,
};
si.set_shading(duvinfo, false);
}
pub mod bsdf;
pub mod matte;
pub mod plastic;
pub mod glass;
pub mod translucent;
pub mod prelude;