Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 27 additions & 43 deletions 13_MaterialCompilerTest/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

#include "nbl/examples/examples.hpp"

//! Temporary, for faster iteration outside of PCH
#include "nbl/asset/material_compiler3/CFrontendIR.h"


using namespace nbl;
Expand Down Expand Up @@ -399,36 +397,27 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
const auto fresnelH = forest->createNamedFresnel("ThF4");
const auto* fresnel = forestPool.deref(fresnelH);

const auto brdfH = forestPool.emplace<CFrontendIR::CMul>();
const auto ctH = forestPool.emplace<CFrontendIR::CCookTorrance>();
{
auto* mul = forestPool.deref(brdfH);
const auto ctH = forestPool.emplace<CFrontendIR::CCookTorrance>();
{
auto* ct = forestPool.deref(ctH);
ct->ndParams.getRougness()[0].scale = ct->ndParams.getRougness()[1].scale = 0.1f;
// ignored for BRDFs, needed for BTDFs
ct->orientedRealEta = fresnel->orientedRealEta;
}
mul->lhs = ctH;
mul->rhs = fresnelH;
auto* ct = forestPool.deref(ctH);
ct->ndParams.getRougness()[0].scale = ct->ndParams.getRougness()[1].scale = 0.1f;
// ignored for BRDFs, needed for BTDFs
ct->orientedRealEta = fresnel->orientedRealEta;
layer->brdfTop = forest->createMul(ctH,fresnelH);
}
layer->brdfTop = brdfH;
layer->brdfBottom = brdfH;

const auto btdfH = forestPool.emplace<CFrontendIR::CMul>();
// the BTDF
{
auto* mul = forestPool.deref(btdfH);
const auto thinInfiniteScatterH = forestPool.emplace<CFrontendIR::CThinInfiniteScatterCorrection>();
{
auto* thinInfiniteScatter = forestPool.deref(thinInfiniteScatterH);
thinInfiniteScatter->reflectanceTop = fresnelH;
thinInfiniteScatter->reflectanceBottom = fresnelH;
// without extinction
}
mul->lhs = forestPool.emplace<CFrontendIR::CDeltaTransmission>();
mul->rhs = thinInfiniteScatterH;
layer->btdf = forest->createMul(forestPool.emplace<CFrontendIR::CDeltaTransmission>(),thinInfiniteScatterH);
}
layer->btdf = btdfH;
// the interface on top as Air->ThF4, we need interface on bottom to be ThF4->Air so reciprocate te Eta
layer->brdfBottom = forest->createMul(forest->reciprocate(ctH)._const_cast(),fresnelH);

{
auto* imagEta = forestPool.deref(fresnel->orientedImagEta);
Expand All @@ -443,7 +432,7 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
ASSERT_VALUE(forest->addMaterial(layerH,logger),true,"ThinDielectric");
}

// compled materials with coatings with IOR 1.5
// complex materials with coatings with IOR 1.5
{
// make the nodes everyone shares
const auto roughDiffuseH = forestPool.emplace<CFrontendIR::CMul>();
Expand Down Expand Up @@ -474,20 +463,16 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
fresnel->orientedRealEta = forestPool.emplace<CFrontendIR::CSpectralVariable>(std::move(params));
}
// the delta layering should optimize out nicely due to the sampling property
const auto transH = forestPool.emplace<CFrontendIR::CMul>();
{
auto* mul = forestPool.deref(transH);
mul->lhs = forestPool.emplace<CFrontendIR::CDeltaTransmission>();
mul->rhs = fresnelH;
}
const auto transH = forest->createMul(forestPool.emplace<CFrontendIR::CDeltaTransmission>(),fresnelH);
// can't attach a copy of the top layer because we'll have a cycle, also the BRDF needs to be on the other side
const auto bottomH = forestPool.emplace<CFrontendIR::CLayer>();
{
auto* bottomLayer = forestPool.deref(bottomH);
bottomLayer->debugInfo = forestPool.emplace<CNodePool::CDebugInfo>("Rough Coating Copy");
// no brdf on the top of last layer, kill multiscattering
bottomLayer->btdf = transH;
bottomLayer->brdfBottom = dielectricH;
// need the interface to be Air on the bottom, not Glass
bottomLayer->brdfBottom = forest->reciprocate(dielectricH)._const_cast();
}

// twosided rough plastic
Expand All @@ -501,19 +486,19 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
// no brdf on the bottom of first layer, kill multiscattering

const auto diffuseH = forestPool.emplace<CFrontendIR::CLayer>();
auto* midLayer = forestPool.deref(diffuseH);
topLayer->coated = diffuseH;
{
auto* midLayer = forestPool.deref(diffuseH);
midLayer->brdfTop = roughDiffuseH;
// no transmission in the mid-layer, the backend needs to decompose into separate front/back materials
// no transmission in the mid-layer, so the backend needs to decompose into separate front/back materials
midLayer->brdfBottom = roughDiffuseH;
midLayer->coated = bottomH;
}
topLayer->coated = diffuseH;

ASSERT_VALUE(forest->addMaterial(rootH,logger),true,"Twosided Rough Plastic");
}

// Diffuse transmitter normalized to whoel sphere
// Diffuse transmitter normalized to whole sphere
const auto roughDiffTransH = forestPool.emplace<CFrontendIR::CMul>();
{
// normalize the Oren Nayar over the full sphere
Expand Down Expand Up @@ -543,7 +528,7 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
midLayer->btdf = roughDiffTransH;
midLayer->brdfBottom = roughDiffTransH;

// we could even have a BSDF with a different Fresnel and Roughness on the bottom layer!
// we could even have a BSDF with a different Roughness on the bottom layer!
midLayer->coated = bottomH;
}
topLayer->coated = midH;
Expand All @@ -556,22 +541,27 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
const auto rootH = forestPool.emplace<CFrontendIR::CLayer>();
auto* topLayer = forestPool.deref(rootH);
topLayer->debugInfo = forestPool.emplace<CNodePool::CDebugInfo>("Coated Diffuse Extinction Transmitter");

// TODO: triple check this example Material
// we have a choice of where to stick the Beer Absorption:
// - on the BTDF of the outside layer, means that it will be applied to the transmission so twice according to VdotN and LdotN
// (but delta transmission makes special weight nodes behave in a special and only once because `L=-V` is forced in a single scattering)
// - inner layer BRDF or BTDF but thats intractable for most compiler backends because the `L` and `V` in the internal layers are not trivially known
// unless the previous layers are delta distributions (in which case we can equivalently hoist beer to the previous layer).
const auto beerH = forestPool.emplace<CFrontendIR::CBeer>();
auto* beer = forestPool.deref(beerH);
{
auto* beer = forestPool.deref(beerH);
spectral_var_t::SCreationParams<3> params = {};
params.getSemantics() = spectral_var_t::Semantics::Fixed3_SRGB;
params.knots.params[0].scale = 0.3f;
params.knots.params[1].scale = 0.9f;
params.knots.params[2].scale = 0.7f;
beer->perpTransmittance = forestPool.emplace<spectral_var_t>(std::move(params));
}
{
spectral_var_t::SCreationParams<1> params = {};
params.knots.params[0].scale = 1.f;
beer->thickness = forestPool.emplace<spectral_var_t>(std::move(params));
}

topLayer->brdfTop = dielectricH;
// simplest/recommended
Expand All @@ -592,13 +582,7 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
midLayer->btdf = roughDiffTransH;
// making extra work for our canonicalizer
{
const auto roughAbsorbH = forestPool.emplace<CFrontendIR::CMul>();
auto* transAbsorb = forestPool.deref(roughAbsorbH);
transAbsorb->lhs = roughDiffTransH;
{
transAbsorb->rhs = beerH;
}
midLayer->brdfBottom = roughAbsorbH;
midLayer->brdfBottom = forest->createMul(roughDiffTransH,beerH);
}

// we could even have a BSDF with a different Fresnel and Roughness on the bottom layer!
Expand Down
5 changes: 5 additions & 0 deletions 31_HLSLPathTracer/app_resources/hlsl/example_common.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ struct Ray

// mutable
scalar_type intersectionT;
uint16_t depth;

payload_type payload;
using spectral_type = typename payload_type::spectral_type;
Expand Down Expand Up @@ -132,6 +133,7 @@ struct Ray

void setT(scalar_type t) { intersectionT = t; }
scalar_type getT() NBL_CONST_MEMBER_FUNC { return intersectionT; }
void setDepth(uint16_t d) { depth = d; }

spectral_type getPayloadThroughput() NBL_CONST_MEMBER_FUNC { return payload.throughput; }
};
Expand All @@ -153,6 +155,7 @@ struct Ray<Payload, PPM_APPROX_PROJECTED_SOLID_ANGLE>

// mutable
scalar_type intersectionT;
uint16_t depth;

payload_type payload;
using spectral_type = typename payload_type::spectral_type;
Expand Down Expand Up @@ -201,6 +204,7 @@ struct Ray<Payload, PPM_APPROX_PROJECTED_SOLID_ANGLE>

void setT(scalar_type t) { intersectionT = t; }
scalar_type getT() NBL_CONST_MEMBER_FUNC { return intersectionT; }
void setDepth(uint16_t d) { depth = d; }

vector3_type getPayloadThroughput() NBL_CONST_MEMBER_FUNC { return payload.throughput; }
};
Expand Down Expand Up @@ -700,6 +704,7 @@ struct PTIsoConfiguration<LS,Interaction,Spectrum NBL_PARTIAL_REQ_BOT(CONF_ISO)
using sample_type = LS;
using spectral_type = Spectrum;
using quotient_pdf_type = sampling::quotient_and_pdf<spectral_type, scalar_type>;
using value_weight_type = sampling::value_and_weight<spectral_type, scalar_type>;
};

template<class LS, class Interaction, class MicrofacetCache, class Spectrum NBL_STRUCT_CONSTRAINABLE>
Expand Down
36 changes: 21 additions & 15 deletions 31_HLSLPathTracer/app_resources/hlsl/material_system.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct MaterialSystem
using sample_type = typename DiffuseBxDF::sample_type;
using ray_dir_info_type = typename sample_type::ray_dir_info_type;
using quotient_pdf_type = typename DiffuseBxDF::quotient_pdf_type;
using value_weight_type = typename DiffuseBxDF::value_weight_type;
using anisotropic_interaction_type = typename DiffuseBxDF::anisotropic_interaction_type;
using isotropic_interaction_type = typename anisotropic_interaction_type::isotropic_interaction_type;
using anisocache_type = typename ConductorBxDF::anisocache_type;
Expand Down Expand Up @@ -133,34 +134,37 @@ struct MaterialSystem
}
}

measure_type eval(material_id_type matID, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction)
value_weight_type evalAndWeight(material_id_type matID, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction)
{
cache_type _cache = getCacheFromSampleInteraction(matID, _sample, interaction);
MaterialType matType = (MaterialType)bxdfs[matID.id].materialType;
switch(matType)
{
case MaterialType::DIFFUSE:
{
return bxdfs[matID.id].albedo * _cache.diffuseBxDF.eval(_sample, interaction.isotropic);
typename diffuse_op_type::isocache_type dummycache;
value_weight_type ret = _cache.diffuseBxDF.evalAndWeight(_sample, interaction.isotropic, dummycache);
ret._value *= bxdfs[matID.id].albedo;
return ret;
}
case MaterialType::CONDUCTOR:
{
return _cache.conductorBxDF.eval(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.conductorBxDF.evalAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::DIELECTRIC:
{
return _cache.dielectricBxDF.eval(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.dielectricBxDF.evalAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::IRIDESCENT_CONDUCTOR:
{
return _cache.iridescentConductorBxDF.eval(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.iridescentConductorBxDF.evalAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::IRIDESCENT_DIELECTRIC:
{
return _cache.iridescentDielectricBxDF.eval(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.iridescentDielectricBxDF.evalAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
default:
return hlsl::promote<measure_type>(0.0);
return value_weight_type::create(0.0, 0.0);
}
}

Expand All @@ -172,7 +176,8 @@ struct MaterialSystem
{
case MaterialType::DIFFUSE:
{
return _cache.diffuseBxDF.generate(interaction, u.xy);
typename diffuse_op_type::isocache_type dummycache;
return _cache.diffuseBxDF.generate(interaction, u.xy, dummycache);
}
case MaterialType::CONDUCTOR:
{
Expand Down Expand Up @@ -230,7 +235,7 @@ struct MaterialSystem
}
}

quotient_pdf_type quotient_and_pdf(material_id_type matID, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(cache_type) _cache)
quotient_pdf_type quotientAndWeight(material_id_type matID, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(cache_type) _cache)
{
const float minimumProjVectorLen = 0.00000001; // TODO: still need this check?
if (interaction.getNdotV(bxdf::BxDFClampMode::BCM_ABS) > minimumProjVectorLen && _sample.getNdotL(bxdf::BxDFClampMode::BCM_ABS) > minimumProjVectorLen)
Expand All @@ -240,31 +245,32 @@ struct MaterialSystem
{
case MaterialType::DIFFUSE:
{
quotient_pdf_type ret = _cache.diffuseBxDF.quotient_and_pdf(_sample, interaction.isotropic);
typename diffuse_op_type::isocache_type dummycache;
quotient_pdf_type ret = _cache.diffuseBxDF.quotientAndWeight(_sample, interaction.isotropic, dummycache);
ret._quotient *= bxdfs[matID.id].albedo;
return ret;
}
case MaterialType::CONDUCTOR:
{
return _cache.conductorBxDF.quotient_and_pdf(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.conductorBxDF.quotientAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::DIELECTRIC:
{
return _cache.dielectricBxDF.quotient_and_pdf(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.dielectricBxDF.quotientAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::IRIDESCENT_CONDUCTOR:
{
return _cache.iridescentConductorBxDF.quotient_and_pdf(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.iridescentConductorBxDF.quotientAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::IRIDESCENT_DIELECTRIC:
{
return _cache.iridescentDielectricBxDF.quotient_and_pdf(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.iridescentDielectricBxDF.quotientAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
default:
break;
}
}
return quotient_pdf_type::create(hlsl::promote<measure_type>(0.0), 0.0);
return quotient_pdf_type::create(0.0, 0.0);
}

bool hasEmission(material_id_type matID)
Expand Down
Loading