rs_pbrt/materials/
mirror.rs

1//std
2use std::sync::Arc;
3// pbrt
4use crate::core::interaction::SurfaceInteraction;
5use crate::core::material::{Material, TransportMode};
6use crate::core::paramset::TextureParams;
7use crate::core::pbrt::{Float, Spectrum};
8use crate::core::reflection::{Bsdf, Bxdf, Fresnel, FresnelNoOp, SpecularReflection};
9use crate::core::texture::Texture;
10
11// see mirror.h
12
13/// A simple mirror, modeled with perfect specular reflection.
14pub struct MirrorMaterial {
15    pub kr: Arc<dyn Texture<Spectrum> + Sync + Send>, // default: 0.9
16    pub bump_map: Option<Arc<dyn Texture<Float> + Send + Sync>>,
17}
18
19impl MirrorMaterial {
20    pub fn new(
21        kr: Arc<dyn Texture<Spectrum> + Send + Sync>,
22        bump_map: Option<Arc<dyn Texture<Float> + Sync + Send>>,
23    ) -> Self {
24        MirrorMaterial { kr, bump_map }
25    }
26    pub fn create(mp: &mut TextureParams) -> Arc<Material> {
27        let kr = mp.get_spectrum_texture("Kr", Spectrum::new(0.9 as Float));
28        let bump_map = mp.get_float_texture_or_null("bumpmap");
29        Arc::new(Material::Mirror(Box::new(MirrorMaterial::new(
30            kr, bump_map,
31        ))))
32    }
33    // Material
34    pub fn compute_scattering_functions(
35        &self,
36        si: &mut SurfaceInteraction,
37        // arena: &mut Arena,
38        _mode: TransportMode,
39        _allow_multiple_lobes: bool,
40        _material: Option<Arc<Material>>,
41        scale_opt: Option<Spectrum>,
42    ) {
43        let mut use_scale: bool = false;
44        let mut sc: Spectrum = Spectrum::default();
45        if let Some(scale) = scale_opt {
46            use_scale = true;
47            sc = scale;
48        }
49        if let Some(ref bump) = self.bump_map {
50            Material::bump(bump, si);
51        }
52        let r: Spectrum = self
53            .kr
54            .evaluate(si)
55            .clamp(0.0 as Float, std::f32::INFINITY as Float);
56        si.bsdf = Some(Bsdf::new(si, 1.0));
57        if let Some(bsdf) = &mut si.bsdf {
58            let fresnel = Fresnel::NoOp(FresnelNoOp {});
59            if use_scale {
60                bsdf.add(Bxdf::SpecRefl(SpecularReflection::new(
61                    r,
62                    fresnel,
63                    Some(sc),
64                )));
65            } else {
66                bsdf.add(Bxdf::SpecRefl(SpecularReflection::new(r, fresnel, None)));
67            }
68        }
69    }
70}