1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use std::sync::Arc;
use crate::core::interaction::SurfaceInteraction;
use crate::core::material::{Material, TransportMode};
use crate::core::microfacet::{MicrofacetDistribution, TrowbridgeReitzDistribution};
use crate::core::paramset::TextureParams;
use crate::core::pbrt::{Float, Spectrum};
use crate::core::reflection::{
Bsdf, Bxdf, Fresnel, FresnelDielectric, LambertianReflection, MicrofacetReflection,
};
use crate::core::texture::Texture;
pub struct PlasticMaterial {
pub kd: Arc<dyn Texture<Spectrum> + Sync + Send>,
pub ks: Arc<dyn Texture<Spectrum> + Sync + Send>,
pub roughness: Arc<dyn Texture<Float> + Sync + Send>,
pub bump_map: Option<Arc<dyn Texture<Float> + Send + Sync>>,
pub remap_roughness: bool,
}
impl PlasticMaterial {
pub fn new(
kd: Arc<dyn Texture<Spectrum> + Send + Sync>,
ks: Arc<dyn Texture<Spectrum> + Send + Sync>,
roughness: Arc<dyn Texture<Float> + Sync + Send>,
bump_map: Option<Arc<dyn Texture<Float> + Sync + Send>>,
remap_roughness: bool,
) -> Self {
PlasticMaterial {
kd,
ks,
roughness,
bump_map,
remap_roughness,
}
}
pub fn create(mp: &mut TextureParams) -> Arc<Material> {
let kd = mp.get_spectrum_texture("Kd", Spectrum::new(0.25 as Float));
let ks = mp.get_spectrum_texture("Ks", Spectrum::new(0.25 as Float));
let roughness = mp.get_float_texture("roughness", 0.1 as Float);
let bump_map = mp.get_float_texture_or_null("bumpmap");
let remap_roughness: bool = mp.find_bool("remaproughness", true);
Arc::new(Material::Plastic(Box::new(PlasticMaterial::new(
kd,
ks,
roughness,
bump_map,
remap_roughness,
))))
}
pub fn compute_scattering_functions(
&self,
si: &mut SurfaceInteraction,
_mode: TransportMode,
_allow_multiple_lobes: bool,
_material: Option<Arc<Material>>,
scale_opt: Option<Spectrum>,
) {
let mut use_scale: bool = false;
let mut sc: Spectrum = Spectrum::default();
if let Some(scale) = scale_opt {
use_scale = true;
sc = scale;
}
if let Some(ref bump) = self.bump_map {
Material::bump(bump, si);
}
let kd: Spectrum = self
.kd
.evaluate(si)
.clamp(0.0 as Float, std::f32::INFINITY as Float);
let ks: Spectrum = self
.ks
.evaluate(si)
.clamp(0.0 as Float, std::f32::INFINITY as Float);
let mut rough: Float = self.roughness.evaluate(si);
si.bsdf = Some(Bsdf::new(si, 1.0));
if let Some(bsdf) = &mut si.bsdf {
if !kd.is_black() {
if use_scale {
bsdf.add(Bxdf::LambertianRefl(LambertianReflection::new(
kd,
Some(sc),
)));
} else {
bsdf.add(Bxdf::LambertianRefl(LambertianReflection::new(kd, None)));
}
}
if !ks.is_black() {
let fresnel = Fresnel::Dielectric(FresnelDielectric {
eta_i: 1.5 as Float,
eta_t: 1.0 as Float,
});
if self.remap_roughness {
rough = TrowbridgeReitzDistribution::roughness_to_alpha(rough);
}
let distrib = MicrofacetDistribution::TrowbridgeReitz(
TrowbridgeReitzDistribution::new(rough, rough, true),
);
if use_scale {
bsdf.add(Bxdf::MicrofacetRefl(MicrofacetReflection::new(
ks,
distrib,
fresnel,
Some(sc),
)));
} else {
bsdf.add(Bxdf::MicrofacetRefl(MicrofacetReflection::new(
ks, distrib, fresnel, None,
)));
}
}
}
}
}