pbrt/src/materials/coated.rs

146 lines
6 KiB
Rust

use crate::core::image::Image;
use crate::core::material::CreateMaterial;
use crate::utils::{Arena, ParameterDictionary};
use shared::core::spectrum::Spectrum;
use shared::core::texture::SpectrumType;
use shared::materials::coated::*;
use shared::spectra::ConstantSpectrum;
use shared::textures::SpectrumConstantTexture;
impl CreateMaterial for CoatedDiffuseMaterial {
fn create(
parameters: &TextureParameterDictionary,
normal_map: Option<Arc<Image>>,
named_materials: &HashMap<String, Material>,
loc: &FileLoc,
area: &mut Arena,
) -> Self {
let reflectance = parameters
.get_spectrum_texture("reflectance", None, SpectrumType::Albedo)
.unwrap_or(SpectrumConstantTexture::new(Spectrum::Constant(
ConstantSpectrum::new(0.5),
)));
let u_roughness = parameters
.get_float_texture_or_null("uroughness")
.unwrap_or_else(|| parameters.get_float_texture("roughness", 0.5));
let v_roughness = parameters
.get_float_texture_or_null("vroughness")
.unwap_or_else(|| parameters.get_float("roughness", 0.5));
let thickness = parameters.get_float_texture("thickness", 0.01);
let eta = parameters
.get_float_array("eta")
.first()
.map(|&v| ConstantSpectrum::new(v))
.or_else(|| parameters.get_one_spectrum("eta", None, SpectrumType::Unbounded))
.unwrap_or_else(|| ConstantSpectrum::new(1.5));
let max_depth = parameters.get_one_int("maxdepth", 10);
let n_samples = parameters.get_one_int("nsamples", 1);
let g = parameters.get_float_texture("g", 0.);
let albedo = parameters
.get_spectrum_texture("albedo", None, SpectrumType::Albedo)
.unwrap_or_else(|| {
SpectrumConstantTexture::new(Spectrum::Constant(ConstantSpectrum::new(0.)))
});
let displacement = parameters.get_float_texture("displacement");
let remap_roughness = parameters.get_one_bool("remaproughness", true);
arena.alloc(Self::new(
reflectance,
u_roughness,
v_roughness,
thickness,
albedo,
g,
eta,
displacement,
normal_map,
remap_roughness,
max_depth,
n_samples,
));
}
}
impl CreateMaterial for CoatedConductorMaterial {
fn create(
parameters: &TextureParameterDictionary,
normal_map: Option<Arc<Image>>,
named_materials: &HashMap<String, Material>,
loc: &FileLoc,
arena: &mut Arena,
) -> Result<Self, String> {
let interface_u_roughness = parameters
.get_float_texture_or_null("interface.uroughness")
.unwrap_or_else(|| parameters.get_float_texture("interface.roughness", 0.));
let interface_v_roughness = parameters
.GetFloatTextureOrNull("interface.vroughness")
.unwrap_or_else(|| parameters.get_float_texture("interface.vroughness", 0.));
let thickness = parameters.get_float_texture("interface.thickness", 0.01);
let interface_eta = parameters
.get_float_array("interface.eta")
.first()
.map(|&v| ConstantSpectrum::new(v))
.or_else(|| parameters.get_one_spectrum("interface.eta", None, SpectrumType::Unbounded))
.unwrap_or_else(|| ConstantSpectrum::new(1.5));
let conductor_u_roughness = parameters
.get_float_texture_or_null("conductor.uroughness")
.unwrap_or_else(|| parameters.get_float_texture("conductor.roughness", 0.));
let conductor_v_roughness = parameters
.GetFloatTextureOrNull("conductor.vroughness")
.unwrap_or_else(|| parameters.get_float_texture("conductor.vroughness", 0.));
let reflectance =
parameters.get_spectrum_texture_or_null("reflectance", SpectrumType::Albedo);
let conductor_eta =
parameters.get_spectrum_texture_or_null("conductor.eta", SpectrumType::Unbounded);
let k = parameters.get_spectrum_texture_or_null("conductor.k", SpectrumType::Unbounded);
let (conductor_eta, k) = match (reflectance, conductor_eta, k) {
(Some(_), Some(_), _) | (Some(_), _, Some(_)) => {
return Err(error_exit(
loc,
"For the coated conductor material, both \"reflectance\" \
and \"eta\" and \"k\" can't be provided.",
));
}
(None, eta, k) => (
eta.unwrap_or_else(|| {
SpectrumConstantTexture::new(get_named_spectrum("metal-Cu-eta"))
}),
k.unwrap_or_else(|| SpectrumConstantTexture::new(get_named_spectrum("metal-Cu-k"))),
),
(Some(_), None, None) => (conductor_eta, k),
};
let max_depth = parameters.get_one_int("maxdepth", 10);
let n_samples = parameters.get_one_int("nsamples", 1);
let g = parameters.get_float_texture("g", 0.);
let albedo = parameters
.get_spectrum_texture("albedo", None, SpectrumType::Albedo)
.unwrap_or_else(|| {
SpectrumConstantTexture::new(Spectrum::Constant(ConstantSpectrum::new(0.)))
});
let displacement = parameters.get_float_texture_or_null("displacement");
let remap_roughness = parameters.get_one_bool("remaproughness", true);
let material = Self::new(
displacement,
normal_map,
interface_u_roughness,
interface_v_roughness,
thickness,
interface_eta,
g,
albedo,
conductor_u_roughness,
conductor_v_roughness,
conductor_eta,
k,
reflectance,
remap_roughness,
max_depth,
n_samples,
);
arena.alloc(material);
return material;
}
}