178 lines
7 KiB
Rust
178 lines
7 KiB
Rust
use crate::core::image::HostImage;
|
|
use crate::core::material::CreateMaterial;
|
|
use crate::core::texture::SpectrumTexture;
|
|
use crate::globals::get_options;
|
|
use crate::spectra::data::get_named_spectrum;
|
|
use crate::utils::TextureParameterDictionary;
|
|
use crate::{Arena, FileLoc, ArenaUpload};
|
|
use anyhow::{bail, Result};
|
|
use shared::core::material::Material;
|
|
use shared::core::spectrum::Spectrum;
|
|
use shared::core::texture::SpectrumType;
|
|
use shared::materials::coated::*;
|
|
use shared::spectra::ConstantSpectrum;
|
|
use shared::textures::SpectrumConstantTexture;
|
|
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
|
|
impl CreateMaterial for CoatedDiffuseMaterial {
|
|
fn create(
|
|
parameters: &TextureParameterDictionary,
|
|
normal_map: Option<Arc<HostImage>>,
|
|
_named_materials: &HashMap<String, Material>,
|
|
_loc: &FileLoc,
|
|
arena: &Arena,
|
|
) -> Result<Material> {
|
|
let reflectance = parameters
|
|
.get_spectrum_texture("reflectance", None, SpectrumType::Albedo)
|
|
.unwrap_or(Arc::new(SpectrumTexture::Constant(
|
|
SpectrumConstantTexture::new(Spectrum::Constant(ConstantSpectrum::new(0.5))),
|
|
)));
|
|
|
|
let u_roughness =
|
|
parameters.get_float_texture_with_fallback("uroughness", "roughness", 0.5)?;
|
|
|
|
let v_roughness =
|
|
parameters.get_float_texture_with_fallback("vroughness", "roughness", 0.5)?;
|
|
|
|
let thickness = parameters.get_float_texture("thickness", 0.01)?;
|
|
let eta = parameters
|
|
.get_float_array("eta")?
|
|
.first()
|
|
.map(|&v| Spectrum::Constant(ConstantSpectrum::new(v)))
|
|
.or_else(|| parameters.get_one_spectrum("eta", None, SpectrumType::Unbounded))
|
|
.unwrap_or_else(|| Spectrum::Constant(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(|| {
|
|
let default_spectrum = Spectrum::Constant(ConstantSpectrum::new(0.));
|
|
SpectrumTexture::Constant(SpectrumConstantTexture::new(default_spectrum)).into()
|
|
});
|
|
let displacement = parameters.get_float_texture("displacement", 0.)?;
|
|
let remap_roughness = parameters.get_one_bool("remaproughness", true)?;
|
|
|
|
let specific = CoatedDiffuseMaterial::new(
|
|
arena.upload(reflectance),
|
|
arena.upload(u_roughness),
|
|
arena.upload(v_roughness),
|
|
arena.upload(thickness),
|
|
arena.upload(albedo),
|
|
arena.upload(g),
|
|
arena.upload(displacement),
|
|
arena.alloc(eta),
|
|
arena.upload(normal_map),
|
|
remap_roughness,
|
|
max_depth as u32,
|
|
n_samples as u32,
|
|
get_options().seed,
|
|
);
|
|
|
|
Ok(Material::CoatedDiffuse(specific))
|
|
}
|
|
}
|
|
|
|
impl CreateMaterial for CoatedConductorMaterial {
|
|
fn create(
|
|
parameters: &TextureParameterDictionary,
|
|
normal_map: Option<Arc<HostImage>>,
|
|
_named_materials: &HashMap<String, Material>,
|
|
loc: &FileLoc,
|
|
arena: &Arena,
|
|
) -> Result<Material> {
|
|
let interface_u_roughness = parameters.get_float_texture_with_fallback(
|
|
"interface.uroughness",
|
|
"interface.roughness",
|
|
0.,
|
|
)?;
|
|
let interface_v_roughness = parameters.get_float_texture_with_fallback(
|
|
"interface.vroughness",
|
|
"interface.roughness",
|
|
0.,
|
|
)?;
|
|
|
|
let thickness = parameters.get_float_texture("interface.thickness", 0.01)?;
|
|
let interface_eta: Spectrum = parameters
|
|
.get_float_array("interface.eta")?
|
|
.first()
|
|
.map(|&v| Spectrum::Constant(ConstantSpectrum::new(v)))
|
|
.or_else(|| parameters.get_one_spectrum("interface.eta", None, SpectrumType::Unbounded))
|
|
.unwrap_or_else(|| Spectrum::Constant(ConstantSpectrum::new(1.5)));
|
|
|
|
let conductor_u_roughness = parameters.get_float_texture_with_fallback(
|
|
"conductor.uroughness",
|
|
"conductor.roughness",
|
|
0.,
|
|
)?;
|
|
|
|
let conductor_v_roughness = parameters.get_float_texture_with_fallback(
|
|
"conductor.vroughness",
|
|
"conductor.roughness",
|
|
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) = if reflectance.is_some() {
|
|
if conductor_eta.is_some() || k.is_some() {
|
|
bail!(
|
|
"{}: For the coated conductor material, both \"reflectance\" \
|
|
and \"eta\"/\"k\" cannot be provided simultaneously.",
|
|
loc
|
|
);
|
|
}
|
|
(None, None)
|
|
} else {
|
|
let eta = conductor_eta.unwrap_or_else(|| {
|
|
let s = get_named_spectrum("metal-Cu-eta").expect("Missing copper spectrum");
|
|
Arc::new(SpectrumTexture::Constant(SpectrumConstantTexture::new(s)))
|
|
});
|
|
let k = k.unwrap_or_else(|| {
|
|
let s = get_named_spectrum("metal-Cu-k").expect("Missing copper spectrum");
|
|
Arc::new(SpectrumTexture::Constant(SpectrumConstantTexture::new(s)))
|
|
});
|
|
(Some(eta), Some(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(|| {
|
|
let spectrum = Spectrum::Constant(ConstantSpectrum::new(0.));
|
|
SpectrumTexture::Constant(SpectrumConstantTexture::new(spectrum)).into()
|
|
});
|
|
let displacement = parameters.get_float_texture_or_null("displacement")?;
|
|
let remap_roughness = parameters.get_one_bool("remaproughness", true)?;
|
|
|
|
let material = Self::new(
|
|
arena.upload(displacement),
|
|
arena.upload(interface_u_roughness),
|
|
arena.upload(interface_v_roughness),
|
|
arena.upload(thickness),
|
|
arena.upload(g),
|
|
arena.upload(albedo),
|
|
arena.upload(conductor_u_roughness),
|
|
arena.upload(conductor_v_roughness),
|
|
arena.upload(conductor_eta),
|
|
arena.upload(k),
|
|
arena.upload(reflectance),
|
|
arena.upload(normal_map),
|
|
arena.alloc(interface_eta),
|
|
max_depth as u32,
|
|
n_samples as u32,
|
|
remap_roughness,
|
|
get_options().seed,
|
|
);
|
|
arena.alloc(material);
|
|
Ok(Material::CoatedConductor(material))
|
|
}
|
|
}
|