From e19d1bd2237693f8df6cd3b576b14ea797807d05 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Thu, 21 Jan 2021 14:36:03 -0800 Subject: [PATCH] Add support for specifying conductors via reflectance. -> assume k=1 then solve for eta that gives the specified spectrum at normal incidence. --- src/pbrt/materials.cpp | 78 ++++++++++++++++++++++++++++-------------- src/pbrt/materials.h | 41 +++++++++++++++------- 2 files changed, 82 insertions(+), 37 deletions(-) diff --git a/src/pbrt/materials.cpp b/src/pbrt/materials.cpp index f0d2f3a..fb64216 100644 --- a/src/pbrt/materials.cpp +++ b/src/pbrt/materials.cpp @@ -198,19 +198,33 @@ DiffuseMaterial *DiffuseMaterial::Create(const TextureParameterDictionary ¶m // ConductorMaterial Method Definitions std::string ConductorMaterial::ToString() const { - return StringPrintf( - "[ ConductorMaterial displacement: %s eta: %s k: %s uRoughness: %s " - "vRoughness: %s remapRoughness: %s]", - displacement, eta, k, uRoughness, vRoughness, remapRoughness); + return StringPrintf("[ ConductorMaterial displacement: %s eta: %s k: %s reflectance: " + "%s uRoughness: %s " + "vRoughness: %s remapRoughness: %s]", + displacement, eta, k, reflectance, uRoughness, vRoughness, + remapRoughness); } ConductorMaterial *ConductorMaterial::Create(const TextureParameterDictionary ¶meters, Image *normalMap, const FileLoc *loc, Allocator alloc) { - SpectrumTextureHandle eta = parameters.GetSpectrumTexture( - "eta", GetNamedSpectrum("metal-Cu-eta"), SpectrumType::Unbounded, alloc); - SpectrumTextureHandle k = parameters.GetSpectrumTexture( - "k", GetNamedSpectrum("metal-Cu-k"), SpectrumType::Unbounded, alloc); + SpectrumTextureHandle eta = + parameters.GetSpectrumTextureOrNull("eta", SpectrumType::Unbounded, alloc); + SpectrumTextureHandle k = + parameters.GetSpectrumTextureOrNull("k", SpectrumType::Unbounded, alloc); + SpectrumTextureHandle reflectance = + parameters.GetSpectrumTextureOrNull("reflectance", SpectrumType::Albedo, alloc); + + if (reflectance && (eta || k)) + ErrorExit(loc, "For the conductor material, both \"reflectance\" " + "and \"eta\" and \"k\" can't be provided."); + if (!reflectance) { + if (!eta) + eta = alloc.new_object( + GetNamedSpectrum("metal-Cu-eta")); + if (!k) + k = alloc.new_object(GetNamedSpectrum("metal-Cu-k")); + } FloatTextureHandle uRoughness = parameters.GetFloatTextureOrNull("uroughness", alloc); FloatTextureHandle vRoughness = parameters.GetFloatTextureOrNull("vroughness", alloc); @@ -223,8 +237,9 @@ ConductorMaterial *ConductorMaterial::Create(const TextureParameterDictionary &p parameters.GetFloatTextureOrNull("displacement", alloc); bool remapRoughness = parameters.GetOneBool("remaproughness", true); - return alloc.new_object(eta, k, uRoughness, vRoughness, - displacement, normalMap, remapRoughness); + return alloc.new_object(eta, k, reflectance, uRoughness, + vRoughness, displacement, normalMap, + remapRoughness); } // CoatedDiffuseMaterial Method Definitions @@ -277,14 +292,15 @@ CoatedDiffuseMaterial *CoatedDiffuseMaterial::Create( } std::string CoatedConductorMaterial::ToString() const { - return StringPrintf("[ CoatedConductorMaterial displacement: %f interfaceURoughness: " - "%f interfaceVRoughness: %f thickness: %f " - "interfaceEta: %f g: %s albedo: %s conductorURoughness: %s " - "conductorVRoughness: %s " - "conductorEta: %s k: %s remapRoughness: %s config: %s", - displacement, interfaceURoughness, interfaceVRoughness, thickness, - interfaceEta, g, albedo, conductorURoughness, conductorVRoughness, - conductorEta, k, remapRoughness, config); + return StringPrintf( + "[ CoatedConductorMaterial displacement: %f interfaceURoughness: %f " + "interfaceVRoughness: %f thickness: %f " + "interfaceEta: %f g: %s albedo: %s conductorURoughness: %s conductorVRoughness: " + "%s " + "conductorEta: %s k: %s conductorReflectance: %s remapRoughness: %s config: %s", + displacement, interfaceURoughness, interfaceVRoughness, thickness, interfaceEta, + g, albedo, conductorURoughness, conductorVRoughness, conductorEta, k, reflectance, + remapRoughness, config); } CoatedConductorMaterial *CoatedConductorMaterial::Create( @@ -317,11 +333,23 @@ CoatedConductorMaterial *CoatedConductorMaterial::Create( if (!conductorVRoughness) conductorVRoughness = parameters.GetFloatTexture("conductor.roughness", 0.f, alloc); - SpectrumTextureHandle conductorEta = - parameters.GetSpectrumTexture("conductor.eta", GetNamedSpectrum("metal-Cu-eta"), - SpectrumType::Unbounded, alloc); - SpectrumTextureHandle k = parameters.GetSpectrumTexture( - "conductor.k", GetNamedSpectrum("metal-Cu-k"), SpectrumType::Unbounded, alloc); + SpectrumTextureHandle conductorEta = parameters.GetSpectrumTextureOrNull( + "conductor.eta", SpectrumType::Unbounded, alloc); + SpectrumTextureHandle k = parameters.GetSpectrumTextureOrNull( + "conductor.k", SpectrumType::Unbounded, alloc); + SpectrumTextureHandle reflectance = + parameters.GetSpectrumTextureOrNull("reflectance", SpectrumType::Albedo, alloc); + + if (reflectance && (conductorEta || k)) + ErrorExit(loc, "For the coated conductor material, both \"reflectance\" " + "and \"eta\" and \"k\" can't be provided."); + if (!reflectance) { + if (!conductorEta) + conductorEta = alloc.new_object( + GetNamedSpectrum("metal-Cu-eta")); + if (!k) + k = alloc.new_object(GetNamedSpectrum("metal-Cu-k")); + } LayeredBxDFConfig config; config.maxDepth = parameters.GetOneInt("maxdepth", config.maxDepth); @@ -340,8 +368,8 @@ CoatedConductorMaterial *CoatedConductorMaterial::Create( return alloc.new_object( interfaceURoughness, interfaceVRoughness, thickness, interfaceEta, g, albedo, - conductorURoughness, conductorVRoughness, conductorEta, k, displacement, - normalMap, remapRoughness, config); + conductorURoughness, conductorVRoughness, conductorEta, k, reflectance, + displacement, normalMap, remapRoughness, config); } // SubsurfaceMaterial Method Definitions diff --git a/src/pbrt/materials.h b/src/pbrt/materials.h index 59d83a3..27cffe0 100644 --- a/src/pbrt/materials.h +++ b/src/pbrt/materials.h @@ -519,7 +519,7 @@ class ConductorMaterial { // ConductorMaterial Public Methods template PBRT_CPU_GPU bool CanEvaluateTextures(TextureEvaluator texEval) const { - return texEval.CanEvaluate({uRoughness, vRoughness}, {eta, k}); + return texEval.CanEvaluate({uRoughness, vRoughness}, {eta, k, reflectance}); } template @@ -531,22 +531,29 @@ class ConductorMaterial { uRough = TrowbridgeReitzDistribution::RoughnessToAlpha(uRough); vRough = TrowbridgeReitzDistribution::RoughnessToAlpha(vRough); } - SampledSpectrum etas = texEval(eta, ctx, lambda); - SampledSpectrum ks = texEval(k, ctx, lambda); - + SampledSpectrum etas, ks; + if (eta) { + etas = texEval(eta, ctx, lambda); + ks = texEval(k, ctx, lambda); + } else { + SampledSpectrum r = texEval(reflectance, ctx, lambda); + etas = SampledSpectrum(1.f); + ks = 2 * Sqrt(r) / Sqrt(ClampZero(SampledSpectrum(1) - r)); + } TrowbridgeReitzDistribution distrib(uRough, vRough); *bxdf = ConductorBxDF(distrib, etas, ks); return BSDF(ctx.wo, ctx.n, ctx.ns, ctx.dpdus, bxdf); } ConductorMaterial(SpectrumTextureHandle eta, SpectrumTextureHandle k, - FloatTextureHandle uRoughness, FloatTextureHandle vRoughness, - FloatTextureHandle displacement, Image *normalMap, - bool remapRoughness) + SpectrumTextureHandle reflectance, FloatTextureHandle uRoughness, + FloatTextureHandle vRoughness, FloatTextureHandle displacement, + Image *normalMap, bool remapRoughness) : displacement(displacement), normalMap(normalMap), eta(eta), k(k), + reflectance(reflectance), uRoughness(uRoughness), vRoughness(vRoughness), remapRoughness(remapRoughness) {} @@ -575,7 +582,7 @@ class ConductorMaterial { // ConductorMaterial Private Data FloatTextureHandle displacement; Image *normalMap; - SpectrumTextureHandle eta, k; + SpectrumTextureHandle eta, k, reflectance; FloatTextureHandle uRoughness, vRoughness; bool remapRoughness; }; @@ -679,6 +686,7 @@ class CoatedConductorMaterial { FloatTextureHandle conductorURoughness, FloatTextureHandle conductorVRoughness, SpectrumTextureHandle conductorEta, SpectrumTextureHandle k, + SpectrumTextureHandle reflectance, FloatTextureHandle displacement, Image *normalMap, bool remapRoughness, LayeredBxDFConfig config) : displacement(displacement), @@ -693,6 +701,7 @@ class CoatedConductorMaterial { conductorVRoughness(conductorVRoughness), conductorEta(conductorEta), k(k), + reflectance(reflectance), remapRoughness(remapRoughness), config(config) {} @@ -703,7 +712,7 @@ class CoatedConductorMaterial { return texEval.CanEvaluate( {interfaceURoughness, interfaceVRoughness, thickness, g, interfaceEta, conductorURoughness, conductorVRoughness}, - {conductorEta, k, albedo}); + {conductorEta, k, reflectance, albedo}); } template @@ -721,8 +730,16 @@ class CoatedConductorMaterial { Float thick = texEval(thickness, ctx); Float ieta = texEval(interfaceEta, ctx); - SampledSpectrum ce = texEval(conductorEta, ctx, lambda); - SampledSpectrum ck = texEval(k, ctx, lambda); + SampledSpectrum ce, ck; + if (conductorEta) { + ce = texEval(conductorEta, ctx, lambda); + ck = texEval(k, ctx, lambda); + } else { + SampledSpectrum r = texEval(reflectance, ctx, lambda); + ce = SampledSpectrum(1.f); + ck = 2 * Sqrt(r) / Sqrt(ClampZero(SampledSpectrum(1) - r)); + } + Float curough = texEval(conductorURoughness, ctx); Float cvrough = texEval(conductorVRoughness, ctx); if (remapRoughness) { @@ -766,7 +783,7 @@ class CoatedConductorMaterial { FloatTextureHandle g; SpectrumTextureHandle albedo; FloatTextureHandle conductorURoughness, conductorVRoughness; - SpectrumTextureHandle conductorEta, k; + SpectrumTextureHandle conductorEta, k, reflectance; bool remapRoughness; LayeredBxDFConfig config; }; -- GitLab