131 lines
3.8 KiB
Rust
131 lines
3.8 KiB
Rust
use crate::globals::get_options;
|
|
use shared::bxdfs::DiffuseBxDF;
|
|
use shared::core::bsdf::BSDF;
|
|
use shared::core::bssrdf::BSSRDF;
|
|
use shared::core::bxdf::BxDF;
|
|
use shared::core::camera::Camera;
|
|
use shared::core::geometry::Ray;
|
|
use shared::core::interaction::{MediumInteraction, SimpleInteraction, SurfaceInteraction};
|
|
use shared::core::material::{Material, MaterialEvalContext, MaterialTrait};
|
|
use shared::core::sampler::{Sampler, SamplerTrait};
|
|
use shared::core::texture::UniversalTextureEvaluator;
|
|
use shared::spectra::SampledWavelengths;
|
|
use shared::Ptr;
|
|
|
|
pub trait InteractionGetter {
|
|
fn get_bsdf(
|
|
&mut self,
|
|
r: &Ray,
|
|
lambda: &SampledWavelengths,
|
|
camera: &Camera,
|
|
sampler: &mut Sampler,
|
|
) -> Option<BSDF>;
|
|
|
|
fn get_bssrdf(
|
|
&self,
|
|
_ray: &Ray,
|
|
lambda: &SampledWavelengths,
|
|
_camera: &Camera,
|
|
) -> Option<BSSRDF>;
|
|
}
|
|
|
|
impl InteractionGetter for SurfaceInteraction {
|
|
fn get_bsdf(
|
|
&mut self,
|
|
r: &Ray,
|
|
lambda: &SampledWavelengths,
|
|
camera: &Camera,
|
|
sampler: &mut Sampler,
|
|
) -> Option<BSDF> {
|
|
self.compute_differentials(r, camera, sampler.samples_per_pixel());
|
|
let material = {
|
|
let Some(mut active_mat) = self.material.get() else {
|
|
return None;
|
|
};
|
|
let tex_eval = UniversalTextureEvaluator;
|
|
while let Material::Mix(mix) = active_mat {
|
|
let ctx = MaterialEvalContext::from(&*self);
|
|
active_mat = mix.choose_material(&tex_eval, &ctx)?;
|
|
}
|
|
*active_mat
|
|
};
|
|
let ctx = MaterialEvalContext::from(&*self);
|
|
let tex_eval = UniversalTextureEvaluator;
|
|
let displacement = material.get_displacement();
|
|
let normal_map = material
|
|
.get_normal_map()
|
|
.map(Ptr::from)
|
|
.unwrap_or(Ptr::null());
|
|
if !displacement.is_null() || !normal_map.is_null() {
|
|
self.compute_bump_geom(&tex_eval, displacement, normal_map);
|
|
}
|
|
let mut bsdf = material.get_bsdf(&tex_eval, &ctx, lambda);
|
|
if get_options().force_diffuse {
|
|
let rho = bsdf.rho_wo(self.common.wo, &[sampler.get1d()], &[sampler.get2d()]);
|
|
let diff_bxdf = BxDF::Diffuse(DiffuseBxDF::new(rho));
|
|
bsdf = BSDF::new(self.shading.n, self.shading.dpdu, diff_bxdf);
|
|
}
|
|
Some(bsdf)
|
|
}
|
|
|
|
fn get_bssrdf(
|
|
&self,
|
|
_ray: &Ray,
|
|
lambda: &SampledWavelengths,
|
|
_camera: &Camera,
|
|
) -> Option<BSSRDF> {
|
|
let Some(mut active_mat) = self.material.get() else {
|
|
return None;
|
|
};
|
|
let tex_eval = UniversalTextureEvaluator;
|
|
while let Material::Mix(mix) = active_mat {
|
|
let ctx = MaterialEvalContext::from(self);
|
|
active_mat = mix.choose_material(&tex_eval, &ctx)?;
|
|
}
|
|
let material = *active_mat;
|
|
let ctx = MaterialEvalContext::from(self);
|
|
material.get_bssrdf(&tex_eval, &ctx, lambda)
|
|
}
|
|
}
|
|
|
|
impl InteractionGetter for MediumInteraction {
|
|
fn get_bsdf(
|
|
&mut self,
|
|
_r: &Ray,
|
|
_lambda: &SampledWavelengths,
|
|
_camera: &Camera,
|
|
_sampler: &mut Sampler,
|
|
) -> Option<BSDF> {
|
|
None
|
|
}
|
|
|
|
fn get_bssrdf(
|
|
&self,
|
|
_ray: &Ray,
|
|
_lambda: &SampledWavelengths,
|
|
_camera: &Camera,
|
|
) -> Option<BSSRDF> {
|
|
None
|
|
}
|
|
}
|
|
|
|
impl InteractionGetter for SimpleInteraction {
|
|
fn get_bsdf(
|
|
&mut self,
|
|
_r: &Ray,
|
|
_lambda: &SampledWavelengths,
|
|
_camera: &Camera,
|
|
_sampler: &mut Sampler,
|
|
) -> Option<BSDF> {
|
|
None
|
|
}
|
|
|
|
fn get_bssrdf(
|
|
&self,
|
|
_ray: &Ray,
|
|
_lambda: &SampledWavelengths,
|
|
_camera: &Camera,
|
|
) -> Option<BSSRDF> {
|
|
None
|
|
}
|
|
}
|