Finishing material creators
This commit is contained in:
parent
6e23698e2d
commit
28bb963268
9 changed files with 263 additions and 48 deletions
|
|
@ -5,7 +5,7 @@ use crate::core::interaction::{InteractionBase, ShadingGeom, SurfaceInteraction}
|
||||||
use crate::core::shape::Shape;
|
use crate::core::shape::Shape;
|
||||||
use crate::core::{LightIdx, MaterialIdx};
|
use crate::core::{LightIdx, MaterialIdx};
|
||||||
use crate::spectra::{N_SPECTRUM_SAMPLES, SampledSpectrum};
|
use crate::spectra::{N_SPECTRUM_SAMPLES, SampledSpectrum};
|
||||||
use crate::utils::math::{catmull_rom_weights, square};
|
use crate::utils::math::{catmull_rom_weights, invert_catmull_rom, square};
|
||||||
use crate::utils::sampling::sample_catmull_rom_2d;
|
use crate::utils::sampling::sample_catmull_rom_2d;
|
||||||
use crate::{Float, GVec, PI, Ptr, gvec_with_capacity};
|
use crate::{Float, GVec, PI, Ptr, gvec_with_capacity};
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
|
|
@ -147,6 +147,22 @@ impl BSSRDFTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn subsurface_from_diffuse(
|
||||||
|
t: &BSSRDFTable,
|
||||||
|
rho_eff: &SampledSpectrum,
|
||||||
|
mfp: &SampledSpectrum,
|
||||||
|
) -> (SampledSpectrum, SampledSpectrum) {
|
||||||
|
// (sigma_a, sigma_s)
|
||||||
|
let mut sigma_a = SampledSpectrum::zero();
|
||||||
|
let mut sigma_s = SampledSpectrum::zero();
|
||||||
|
for c in 0..N_SPECTRUM_SAMPLES {
|
||||||
|
let rho = invert_catmull_rom(&t.rho_samples, &t.rho_eff, rho_eff[c]);
|
||||||
|
sigma_s[c] = rho / mfp[c];
|
||||||
|
sigma_a[c] = (1. - rho) / mfp[c];
|
||||||
|
}
|
||||||
|
(sigma_a, sigma_s)
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone, Default, Debug)]
|
#[derive(Copy, Clone, Default, Debug)]
|
||||||
pub struct BSSRDFProbeSegment {
|
pub struct BSSRDFProbeSegment {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,15 @@ pub enum Spectrum {
|
||||||
RGBUnbounded(RGBUnboundedSpectrum),
|
RGBUnbounded(RGBUnboundedSpectrum),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `enum_dispatch` already generates `From<Variant> for Spectrum`, so wrapping a
|
||||||
|
/// `ConstantSpectrum` etc. is `.into()`. Only the plain-`Float` hop is missing,
|
||||||
|
/// and it is the one written most often at default-value sites.
|
||||||
|
impl From<Float> for Spectrum {
|
||||||
|
fn from(c: Float) -> Self {
|
||||||
|
Spectrum::Constant(ConstantSpectrum::new(c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: SpectrumTrait> SpectrumTrait for Ptr<T> {
|
impl<T: SpectrumTrait> SpectrumTrait for Ptr<T> {
|
||||||
fn evaluate(&self, lambda: Float) -> Float {
|
fn evaluate(&self, lambda: Float) -> Float {
|
||||||
self.get().unwrap().evaluate(lambda)
|
self.get().unwrap().evaluate(lambda)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::bxdfs::{
|
||||||
MeasuredBxDF, MeasuredBxDFData,
|
MeasuredBxDF, MeasuredBxDFData,
|
||||||
};
|
};
|
||||||
use crate::core::bsdf::BSDF;
|
use crate::core::bsdf::BSDF;
|
||||||
use crate::core::bssrdf::{BSSRDF, BSSRDFTable};
|
use crate::core::bssrdf::{BSSRDF, BSSRDFTable, TabulatedBSSRDF, subsurface_from_diffuse};
|
||||||
use crate::core::bxdf::BxDF;
|
use crate::core::bxdf::BxDF;
|
||||||
use crate::core::image::Image;
|
use crate::core::image::Image;
|
||||||
use crate::core::material::{Material, MaterialEvalContext, MaterialTrait};
|
use crate::core::material::{Material, MaterialEvalContext, MaterialTrait};
|
||||||
|
|
@ -118,12 +118,30 @@ impl MaterialTrait for HairMaterial {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_evaluate_textures(&self, _tex_eval: &dyn TextureEvaluator) -> bool {
|
fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool {
|
||||||
todo!()
|
match self.hair_absorption {
|
||||||
|
HairAbsorption::SigmaA(t) | HairAbsorption::Color(t) => {
|
||||||
|
tex_eval.can_evaluate(&[self.eta, self.beta_m, self.beta_n, self.alpha], &[t])
|
||||||
|
}
|
||||||
|
HairAbsorption::Melanin {
|
||||||
|
eumelanin,
|
||||||
|
pheomelanin,
|
||||||
|
} => tex_eval.can_evaluate(
|
||||||
|
&[
|
||||||
|
self.eta,
|
||||||
|
self.beta_m,
|
||||||
|
self.beta_n,
|
||||||
|
self.alpha,
|
||||||
|
eumelanin,
|
||||||
|
pheomelanin,
|
||||||
|
],
|
||||||
|
&[],
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_normal_map(&self) -> Option<&Image> {
|
fn get_normal_map(&self) -> Option<&Image> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_displacement(&self) -> Ptr<FloatTexture> {
|
fn get_displacement(&self) -> Ptr<FloatTexture> {
|
||||||
|
|
@ -210,31 +228,78 @@ pub struct SubsurfaceMaterial {
|
||||||
impl MaterialTrait for SubsurfaceMaterial {
|
impl MaterialTrait for SubsurfaceMaterial {
|
||||||
fn get_bsdf<T: TextureEvaluator>(
|
fn get_bsdf<T: TextureEvaluator>(
|
||||||
&self,
|
&self,
|
||||||
_tex_eval: &T,
|
tex_eval: &T,
|
||||||
_ctx: &MaterialEvalContext,
|
ctx: &MaterialEvalContext,
|
||||||
_lambda: &mut SampledWavelengths,
|
_lambda: &mut SampledWavelengths,
|
||||||
) -> BSDF {
|
) -> BSDF {
|
||||||
todo!()
|
let mut u_rough = tex_eval.evaluate_float(&self.u_roughness, ctx);
|
||||||
}
|
let mut v_rough = tex_eval.evaluate_float(&self.v_roughness, ctx);
|
||||||
fn get_bssrdf<T>(
|
if self.remap_roughness {
|
||||||
&self,
|
u_rough = TrowbridgeReitzDistribution::roughness_to_alpha(u_rough);
|
||||||
_tex_eval: &T,
|
v_rough = TrowbridgeReitzDistribution::roughness_to_alpha(v_rough);
|
||||||
_ctx: &MaterialEvalContext,
|
|
||||||
_lambda: &SampledWavelengths,
|
|
||||||
) -> Option<BSSRDF> {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_evaluate_textures(&self, _tex_eval: &dyn TextureEvaluator) -> bool {
|
let distrib = TrowbridgeReitzDistribution::new(u_rough, v_rough);
|
||||||
todo!()
|
let bxdf = BxDF::Dielectric(DielectricBxDF::new(self.eta, distrib));
|
||||||
|
BSDF::new(ctx.ns, ctx.dpdus, bxdf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_bssrdf<T: TextureEvaluator>(
|
||||||
|
&self,
|
||||||
|
tex_eval: &T,
|
||||||
|
ctx: &MaterialEvalContext,
|
||||||
|
lambda: &SampledWavelengths,
|
||||||
|
) -> Option<BSSRDF> {
|
||||||
|
let (sig_a, sig_s) = match self.scattering {
|
||||||
|
SubsurfaceScattering::Coefficients { sigma_a, sigma_s } => {
|
||||||
|
let s_a = SampledSpectrum::clamp_zero(
|
||||||
|
&(self.scale * tex_eval.evaluate_spectrum(&sigma_a, ctx, lambda)),
|
||||||
|
);
|
||||||
|
let s_s = SampledSpectrum::clamp_zero(
|
||||||
|
&(self.scale * tex_eval.evaluate_spectrum(&sigma_s, ctx, lambda)),
|
||||||
|
);
|
||||||
|
(s_a, s_s)
|
||||||
|
}
|
||||||
|
SubsurfaceScattering::Reflectance { reflectance, mfp } => {
|
||||||
|
debug_assert!(!reflectance.is_null() && !mfp.is_null());
|
||||||
|
let mfree =
|
||||||
|
SampledSpectrum::clamp_zero(&tex_eval.evaluate_spectrum(&mfp, ctx, lambda));
|
||||||
|
let r = SampledSpectrum::clamp_zero(&tex_eval.evaluate_spectrum(
|
||||||
|
&reflectance,
|
||||||
|
ctx,
|
||||||
|
lambda,
|
||||||
|
));
|
||||||
|
subsurface_from_diffuse(&self.table, &r, &mfree)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(BSSRDF::Tabulated(TabulatedBSSRDF::new(
|
||||||
|
ctx.p,
|
||||||
|
ctx.wo,
|
||||||
|
ctx.ns,
|
||||||
|
self.eta,
|
||||||
|
&sig_a,
|
||||||
|
&sig_s,
|
||||||
|
&self.table,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool {
|
||||||
|
// Slight divergence from PBRT, we check against reflectance and mfp as well in reflectance
|
||||||
|
// mode. Test thoroughly, keep as is for now (20260902)
|
||||||
|
let spectra = match self.scattering {
|
||||||
|
SubsurfaceScattering::Coefficients { sigma_a, sigma_s } => [sigma_a, sigma_s],
|
||||||
|
SubsurfaceScattering::Reflectance { reflectance, mfp } => [reflectance, mfp],
|
||||||
|
};
|
||||||
|
tex_eval.can_evaluate(&[self.u_roughness, self.v_roughness], &spectra)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_normal_map(&self) -> Option<&Image> {
|
fn get_normal_map(&self) -> Option<&Image> {
|
||||||
todo!()
|
Some(&*self.normal_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_displacement(&self) -> Ptr<FloatTexture> {
|
fn get_displacement(&self) -> Ptr<FloatTexture> {
|
||||||
todo!()
|
self.displacement
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_subsurface_scattering(&self) -> bool {
|
fn has_subsurface_scattering(&self) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ pub struct ConductorMaterial {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConductorMaterial {
|
impl ConductorMaterial {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
normal_map: Ptr<Image>,
|
normal_map: Ptr<Image>,
|
||||||
reflectance: Ptr<SpectrumTexture>,
|
reflectance: Ptr<SpectrumTexture>,
|
||||||
|
|
@ -92,7 +93,7 @@ impl MaterialTrait for ConductorMaterial {
|
||||||
_ctx: &MaterialEvalContext,
|
_ctx: &MaterialEvalContext,
|
||||||
_lambda: &SampledWavelengths,
|
_lambda: &SampledWavelengths,
|
||||||
) -> Option<BSSRDF> {
|
) -> Option<BSSRDF> {
|
||||||
todo!()
|
None
|
||||||
}
|
}
|
||||||
fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool {
|
fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool {
|
||||||
tex_eval.can_evaluate(
|
tex_eval.can_evaluate(
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::core::color::{RGB, XYZ};
|
use crate::core::color::{RGB, XYZ};
|
||||||
use crate::core::geometry::{Lerp, MulAdd, Point, Point2f, Point2i, Vector, Vector3f, VectorLike};
|
use crate::core::geometry::{Lerp, MulAdd, Point, Point2f, Point2i, Vector, Vector3f, VectorLike};
|
||||||
use crate::core::pbrt::{Float, FloatBitOps, FloatBits, ONE_MINUS_EPSILON, PI, PI_OVER_4};
|
use crate::core::pbrt::{Float, FloatBitOps, FloatBits, ONE_MINUS_EPSILON, PI, PI_OVER_4};
|
||||||
use crate::utils::gpu_array_from_fn;
|
|
||||||
use crate::utils::hash::{hash_buffer, mix_bits};
|
use crate::utils::hash::{hash_buffer, mix_bits};
|
||||||
use crate::utils::sobol::{SOBOL_MATRICES_32, VDC_SOBOL_MATRICES, VDC_SOBOL_MATRICES_INV};
|
use crate::utils::sobol::{SOBOL_MATRICES_32, VDC_SOBOL_MATRICES, VDC_SOBOL_MATRICES_INV};
|
||||||
|
use crate::utils::{find_interval, gpu_array_from_fn};
|
||||||
use crate::{GVec, Ptr, gvec, gvec_with_capacity};
|
use crate::{GVec, Ptr, gvec, gvec_with_capacity};
|
||||||
use core::fmt::{self, Display, Write};
|
use core::fmt::{self, Display, Write};
|
||||||
use core::iter::{Product, Sum};
|
use core::iter::{Product, Sum};
|
||||||
|
|
@ -379,6 +379,61 @@ pub fn integrate_catmull_rom(nodes: &[Float], f: &[Float], cdf: &mut [Float]) ->
|
||||||
sum
|
sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn invert_catmull_rom(nodes: &[Float], f: &[Float], u: Float) -> Float {
|
||||||
|
// Stop when _u_ is out of bounds
|
||||||
|
if !(u > f[0]) {
|
||||||
|
return nodes[0];
|
||||||
|
} else if !(u < f[f.len() - 1]) {
|
||||||
|
return nodes[nodes.len() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map _u_ to a spline interval by inverting _f_
|
||||||
|
let i = find_interval(f.len() as u32, |j| f[j as usize] <= u) as usize;
|
||||||
|
|
||||||
|
// Look up $x_i$ and function values of spline segment _i_
|
||||||
|
let x0 = nodes[i];
|
||||||
|
let x1 = nodes[i + 1];
|
||||||
|
let f0 = f[i];
|
||||||
|
let f1 = f[i + 1];
|
||||||
|
let width = x1 - x0;
|
||||||
|
|
||||||
|
// Approximate derivatives using finite differences
|
||||||
|
let d0 = if i > 0 {
|
||||||
|
width * (f1 - f[i - 1]) / (x1 - nodes[i - 1])
|
||||||
|
} else {
|
||||||
|
f1 - f0
|
||||||
|
};
|
||||||
|
let d1 = if i + 2 < nodes.len() {
|
||||||
|
width * (f[i + 2] - f0) / (nodes[i + 2] - x0)
|
||||||
|
} else {
|
||||||
|
f1 - f0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invert the spline interpolant using Newton-Bisection
|
||||||
|
let eval = |t: Float| -> (Float, Float) {
|
||||||
|
// Compute powers of _t_
|
||||||
|
let t2 = t * t;
|
||||||
|
let t3 = t2 * t;
|
||||||
|
|
||||||
|
// Set _Fhat_ using Equation (\ref{eq:cubicspline-as-basisfunctions})
|
||||||
|
let f_cap_hat = (2. * t3 - 3. * t2 + 1.) * f0
|
||||||
|
+ (-2. * t3 + 3. * t2) * f1
|
||||||
|
+ (t3 - 2. * t2 + t) * d0
|
||||||
|
+ (t3 - t2) * d1;
|
||||||
|
|
||||||
|
// Set _fhat_ using Equation (\ref{eq:cubicspline-derivative})
|
||||||
|
let f_hat = (6. * t2 - 6. * t) * f0
|
||||||
|
+ (-6. * t2 + 6. * t) * f1
|
||||||
|
+ (3. * t2 - 4. * t + 1.) * d0
|
||||||
|
+ (3. * t2 - 2. * t) * d1;
|
||||||
|
|
||||||
|
return (f_cap_hat - u, f_hat);
|
||||||
|
};
|
||||||
|
|
||||||
|
let t = newton_bisection(0., 1., eval);
|
||||||
|
return x0 + t * width;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn catmull_rom_weights(nodes: &[Float], x: Float) -> Option<(u32, [Float; 4])> {
|
pub fn catmull_rom_weights(nodes: &[Float], x: Float) -> Option<(u32, [Float; 4])> {
|
||||||
if nodes.len() < 4 {
|
if nodes.len() < 4 {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use shared::Float;
|
||||||
use shared::core::color::ColorEncoding;
|
use shared::core::color::ColorEncoding;
|
||||||
use shared::core::geometry::Vector3f;
|
use shared::core::geometry::Vector3f;
|
||||||
use shared::core::image::WrapMode;
|
use shared::core::image::WrapMode;
|
||||||
|
use shared::core::spectrum::Spectrum;
|
||||||
use shared::core::texture::SpectrumType;
|
use shared::core::texture::SpectrumType;
|
||||||
use shared::core::texture::{
|
use shared::core::texture::{
|
||||||
CylindricalMapping, PlanarMapping, PointTransformMapping, SphericalMapping, TextureEvalContext,
|
CylindricalMapping, PlanarMapping, PointTransformMapping, SphericalMapping, TextureEvalContext,
|
||||||
|
|
@ -95,6 +96,21 @@ pub enum SpectrumTexture {
|
||||||
DirectionMix(SpectrumDirectionMixTexture),
|
DirectionMix(SpectrumDirectionMixTexture),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A bare `Spectrum` used as a texture is always a constant texture. Saves
|
||||||
|
/// writing `SpectrumTexture::Constant(SpectrumConstantTexture::new(s))` at every
|
||||||
|
/// default-value site.
|
||||||
|
impl From<Spectrum> for SpectrumTexture {
|
||||||
|
fn from(s: Spectrum) -> Self {
|
||||||
|
SpectrumTexture::Constant(SpectrumConstantTexture::new(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Float> for FloatTexture {
|
||||||
|
fn from(v: Float) -> Self {
|
||||||
|
FloatTexture::Constant(FloatConstantTexture::new(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait CreateSpectrumTexture {
|
pub trait CreateSpectrumTexture {
|
||||||
fn create(
|
fn create(
|
||||||
render_from_texture: Transform,
|
render_from_texture: Transform,
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ use crate::core::texture::SpectrumTexture;
|
||||||
use crate::globals::get_options;
|
use crate::globals::get_options;
|
||||||
use crate::spectra::data::get_named_spectrum;
|
use crate::spectra::data::get_named_spectrum;
|
||||||
use crate::utils::TextureParameterDictionary;
|
use crate::utils::TextureParameterDictionary;
|
||||||
use crate::{Arena, FileLoc, ArenaUpload};
|
use crate::{Arena, ArenaUpload, FileLoc};
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{Result, bail};
|
||||||
use shared::core::material::Material;
|
use shared::core::material::Material;
|
||||||
use shared::core::spectrum::Spectrum;
|
use shared::core::spectrum::Spectrum;
|
||||||
use shared::core::texture::SpectrumType;
|
use shared::core::texture::SpectrumType;
|
||||||
|
|
@ -36,12 +36,13 @@ impl CreateMaterial for CoatedDiffuseMaterial {
|
||||||
parameters.get_float_texture_with_fallback("vroughness", "roughness", 0.5)?;
|
parameters.get_float_texture_with_fallback("vroughness", "roughness", 0.5)?;
|
||||||
|
|
||||||
let thickness = parameters.get_float_texture("thickness", 0.01)?;
|
let thickness = parameters.get_float_texture("thickness", 0.01)?;
|
||||||
let eta = parameters
|
let eta = if let Some(&v) = parameters.get_float_array("eta")?.first() {
|
||||||
.get_float_array("eta")?
|
Spectrum::from(v)
|
||||||
.first()
|
} else {
|
||||||
.map(|&v| Spectrum::Constant(ConstantSpectrum::new(v)))
|
parameters
|
||||||
.or_else(|| parameters.get_one_spectrum("eta", None, SpectrumType::Unbounded))
|
.get_one_spectrum("eta", None, SpectrumType::Unbounded)
|
||||||
.unwrap_or_else(|| Spectrum::Constant(ConstantSpectrum::new(1.5)));
|
.unwrap_or_else(|| Spectrum::from(1.5))
|
||||||
|
};
|
||||||
|
|
||||||
let max_depth = parameters.get_one_int("maxdepth", 10)?;
|
let max_depth = parameters.get_one_int("maxdepth", 10)?;
|
||||||
let n_samples = parameters.get_one_int("nsamples", 1)?;
|
let n_samples = parameters.get_one_int("nsamples", 1)?;
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,14 @@ impl CreateMaterial for SubsurfaceMaterial {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fn brdf_data_from_filename(filename: String) -> Ptr<MeasuredBxDFData> {
|
||||||
|
// static std::map<std::string, MeasuredBxDFData *> loadedData;
|
||||||
|
// if (loadedData.find(filename) == loadedData.end())
|
||||||
|
// loadedData[filename] = MeasuredBxDFData::Create(filename, alloc);
|
||||||
|
// return loadedData[filename];
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
impl CreateMaterial for MeasuredMaterial {
|
impl CreateMaterial for MeasuredMaterial {
|
||||||
fn create(
|
fn create(
|
||||||
parameters: &TextureParameterDictionary,
|
parameters: &TextureParameterDictionary,
|
||||||
|
|
@ -305,12 +313,14 @@ impl CreateMaterial for MeasuredMaterial {
|
||||||
loc: &FileLoc,
|
loc: &FileLoc,
|
||||||
arena: &Arena,
|
arena: &Arena,
|
||||||
) -> Result<Material> {
|
) -> Result<Material> {
|
||||||
let filename = resolve_filename(parameters.get_one_string("filename", "")?);
|
// let filename = resolve_filename(parameters.get_one_string("filename", "")?);
|
||||||
let displacement = parameters.get_float_texture_or_null("displacement")?;
|
// let displacement = parameters.get_float_texture_or_null("displacement")?;
|
||||||
let brdf = MeasuredBxDF::brdf_data_from_file(filename);
|
// let brdf = MeasuredBxDF::brdf_data_from_file(filename);
|
||||||
let mat = MeasuredMaterial {
|
// let mat = MeasuredMaterial {
|
||||||
displacement: arena.upload(displacement),
|
// displacement: arena.upload(displacement),
|
||||||
normal_map: arena.upload(normal_map)
|
// normal_map: arena.upload(normal_map)
|
||||||
}
|
// brdf
|
||||||
|
// }
|
||||||
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,75 @@
|
||||||
use crate::Arena;
|
|
||||||
use crate::core::image::HostImage;
|
use crate::core::image::HostImage;
|
||||||
use crate::core::material::CreateMaterial;
|
use crate::core::material::CreateMaterial;
|
||||||
use crate::utils::{FileLoc, TextureParameterDictionary};
|
use crate::utils::{FileLoc, TextureParameterDictionary};
|
||||||
|
use crate::{Arena, ArenaUpload};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use shared::core::material::Material;
|
use shared::core::material::Material;
|
||||||
|
use shared::core::spectrum::Spectrum;
|
||||||
|
use shared::core::texture::SpectrumType;
|
||||||
use shared::materials::{DielectricMaterial, ThinDielectricMaterial};
|
use shared::materials::{DielectricMaterial, ThinDielectricMaterial};
|
||||||
|
use shared::spectra::ConstantSpectrum;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
impl CreateMaterial for DielectricMaterial {
|
impl CreateMaterial for DielectricMaterial {
|
||||||
fn create(
|
fn create(
|
||||||
_parameters: &TextureParameterDictionary,
|
parameters: &TextureParameterDictionary,
|
||||||
_normal_map: Option<Arc<HostImage>>,
|
normal_map: Option<Arc<HostImage>>,
|
||||||
_named_materials: &HashMap<String, Material>,
|
_named_materials: &HashMap<String, Material>,
|
||||||
_loc: &FileLoc,
|
loc: &FileLoc,
|
||||||
_arena: &Arena,
|
arena: &Arena,
|
||||||
) -> Result<Material> {
|
) -> Result<Material> {
|
||||||
todo!()
|
let eta = if let Some(&v) = parameters.get_float_array("eta")?.first() {
|
||||||
|
Spectrum::from(v)
|
||||||
|
} else {
|
||||||
|
parameters
|
||||||
|
.get_one_spectrum("eta", None, SpectrumType::Unbounded)
|
||||||
|
.unwrap_or_else(|| Spectrum::from(1.5))
|
||||||
|
};
|
||||||
|
|
||||||
|
let u_roughness =
|
||||||
|
parameters.get_float_texture_with_fallback("uroughness", "roughness", 0.)?;
|
||||||
|
let v_roughness =
|
||||||
|
parameters.get_float_texture_with_fallback("vroughness", "roughness", 0.)?;
|
||||||
|
let displacement = parameters.get_float_texture_or_null("displacement")?;
|
||||||
|
let remap_roughness = parameters.get_one_bool("remaproughness", true)?;
|
||||||
|
|
||||||
|
let mat = DielectricMaterial {
|
||||||
|
normal_map: arena.upload(normal_map),
|
||||||
|
displacement: arena.upload(displacement),
|
||||||
|
u_roughness: arena.upload(u_roughness),
|
||||||
|
v_roughness: arena.upload(v_roughness),
|
||||||
|
eta: arena.alloc(eta),
|
||||||
|
remap_roughness,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Material::Dielectric(mat))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CreateMaterial for ThinDielectricMaterial {
|
impl CreateMaterial for ThinDielectricMaterial {
|
||||||
fn create(
|
fn create(
|
||||||
_parameters: &TextureParameterDictionary,
|
parameters: &TextureParameterDictionary,
|
||||||
_normal_map: Option<Arc<HostImage>>,
|
normal_map: Option<Arc<HostImage>>,
|
||||||
_named_materials: &HashMap<String, Material>,
|
_named_materials: &HashMap<String, Material>,
|
||||||
_loc: &FileLoc,
|
loc: &FileLoc,
|
||||||
_arena: &Arena,
|
arena: &Arena,
|
||||||
) -> Result<Material> {
|
) -> Result<Material> {
|
||||||
todo!()
|
let eta = if let Some(&v) = parameters.get_float_array("eta")?.first() {
|
||||||
|
Spectrum::from(v)
|
||||||
|
} else {
|
||||||
|
parameters
|
||||||
|
.get_one_spectrum("eta", None, SpectrumType::Unbounded)
|
||||||
|
.unwrap_or_else(|| Spectrum::from(1.5))
|
||||||
|
};
|
||||||
|
|
||||||
|
let displacement = parameters.get_float_texture_or_null("displacement")?;
|
||||||
|
let mat = ThinDielectricMaterial {
|
||||||
|
displacement: arena.upload(displacement),
|
||||||
|
normal_map: arena.upload(normal_map),
|
||||||
|
eta: arena.alloc(eta),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Material::ThinDielectric(mat))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue