Skip to content

Commit 708f753

Browse files
leaf node parsing almost done
1 parent 01d0c2f commit 708f753

4 files changed

Lines changed: 154 additions & 70 deletions

File tree

include/nbl/asset/material_compiler3/CFrontendIR.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ class CFrontendIR final : public CNodePool
574574
protected:
575575
inline typed_pointer_type<IExprNode> getChildHandle_impl(const uint8_t ix) const override {return ix ? orientedImagEta:orientedRealEta;}
576576
NBL_API2 bool invalid(const SInvalidCheckArgs& args) const override;
577-
inline std::string_view getChildName_impl(const uint8_t ix) const override {return ix ? "Real":"Imaginary";}
577+
inline std::string_view getChildName_impl(const uint8_t ix) const override {return ix ? "Imaginary":"Real";}
578578
NBL_API2 void printDot(std::ostringstream& sstr, const core::string& selfID) const override;
579579
};
580580
// Compute Inifinite Scatter and extinction between two parallel infinite planes.

include/nbl/ext/MitsubaLoader/SContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ struct SContext final
150150
enum class ECommonDebug : uint16_t
151151
{
152152
Albedo,
153+
MitsubaExtraFactor,
153154
Count
154155
};
155156
frontend_ir_t::obj_pool_type::typed_pointer_type<const frontend_ir_t::CDebugInfo> commonDebugNames[uint16_t(ECommonDebug::Count)];

src/nbl/ext/MitsubaLoader/CMitsubaLoader.cpp

Lines changed: 151 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ bool CMitsubaLoader::isALoadableFileFormat(system::IFile* _file, const system::l
201201

202202

203203
// TODO: make configurable
204-
constexpr bool PrintMaterialDot3 = false;
205-
system::path DebugDir("/tmp");
204+
constexpr bool PrintMaterialDot3 = true;
205+
system::path DebugDir("D:\\work\\Nabla-master\\examples_tests\\15_MitsubaLoader\\bin");
206206
//
207207
void SContext::writeDot3File(system::ISystem* system, const system::path& filepath, frontend_ir_t::SDotPrinter& printer)
208208
{
@@ -497,6 +497,9 @@ void getParameter(const std::span<parameter_t,3> out, const CElementTexture::Spe
497497
else
498498
switch (src.value.type)
499499
{
500+
case SPropertyElementData::Type::FLOAT:
501+
getParameter({out.data(),out.size()},src.value.fvalue);
502+
break;
500503
case SPropertyElementData::Type::SRGB: [[fallthrough]]; // already linearized when parsed!
501504
case SPropertyElementData::Type::RGB:
502505
getParameter<3>(out,src.value.vvalue.xyz);
@@ -525,11 +528,23 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
525528
// this is also our top coating layer
526529
auto rootH = frontPool.emplace<frontend_ir_t::CLayer>();
527530

528-
auto createMistubaLeaf = [&]()->frontend_ir_t::typed_pointer_type<frontend_ir_t::IExprNode>
531+
struct SLeaf
532+
{
533+
frontend_ir_t::typed_pointer_type<frontend_ir_t::IExprNode> top = {};
534+
frontend_ir_t::typed_pointer_type<frontend_ir_t::IExprNode> trans = {};
535+
};
536+
auto createMistubaLeaf = [&](const CElementBSDF* _bsdf/*TODO: debug source information*/)->SLeaf
529537
{
530-
switch (bsdf->type)
538+
using ndf_e = frontend_ir_t::CCookTorrance::NDF;
539+
constexpr ndf_e ndfMap[4] = {
540+
ndf_e::Beckmann,
541+
ndf_e::GGX,
542+
ndf_e::Beckmann, // Phong can be mapped to Beckmann
543+
ndf_e::Beckmann // Ahskhmin is Ani Beckmann last I remember
544+
};
545+
switch (_bsdf->type)
531546
{
532-
case CElementBSDF::DIFFUSE:
547+
case CElementBSDF::DIFFUSE: [[fallthrough]];
533548
case CElementBSDF::ROUGHDIFFUSE:
534549
{
535550
const auto roughDiffuseH = frontPool.emplace<frontend_ir_t::CMul>();
@@ -539,10 +554,10 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
539554
const auto orenNayarH = frontPool.emplace<frontend_ir_t::COrenNayar>();
540555
auto* orenNayar = frontPool.deref(orenNayarH);
541556
auto roughness = orenNayar->ndParams.getRougness();
542-
if (bsdf->type==CElementBSDF::ROUGHDIFFUSE)
557+
if (_bsdf->type==CElementBSDF::ROUGHDIFFUSE)
543558
{
544559
// we only support isotropic Oren-Nayar
545-
getParameter(roughness,bsdf->diffuse.alpha);
560+
getParameter(roughness,_bsdf->diffuse.alpha);
546561
}
547562
else
548563
roughness[0].scale = roughness[1].scale = 0.f;
@@ -551,13 +566,120 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
551566
{
552567
spectral_var_t::SCreationParams<3> params = {};
553568
params.getSemantics() = spectral_var_t::Semantics::Fixed3_SRGB;
554-
getParameter(params.knots.params,bsdf->diffuse.reflectance);
555-
const auto albedoH = frontPool.emplace<frontend_ir_t::CSpectralVariable>(std::move(params));
569+
getParameter(params.knots.params,_bsdf->diffuse.reflectance);
570+
const auto albedoH = frontPool.emplace<spectral_var_t>(std::move(params));
556571
frontPool.deref(albedoH)->debugInfo = commonDebugNames[uint16_t(ECommonDebug::Albedo)]._const_cast();
557572
mul->rhs = albedoH;
558573
}
559574
}
560-
return roughDiffuseH;
575+
return {.top=roughDiffuseH};
576+
}
577+
case CElementBSDF::DIELECTRIC: [[fallthrough]];
578+
case CElementBSDF::THINDIELECTRIC: [[fallthrough]];
579+
case CElementBSDF::ROUGHDIELECTRIC: [[fallthrough]];
580+
case CElementBSDF::CONDUCTOR: [[fallthrough]];
581+
case CElementBSDF::ROUGHCONDUCTOR:
582+
{
583+
const auto handle = frontPool.emplace<frontend_ir_t::CMul>();
584+
frontend_ir_t::typed_pointer_type<frontend_ir_t::IExprNode> trans = {};
585+
{
586+
const bool isConductor = _bsdf->type==CElementBSDF::CONDUCTOR || _bsdf->type==CElementBSDF::ROUGHCONDUCTOR;
587+
// beautiful thing we can reuse the same nodes for a transmission function without touching Etas or anything!
588+
if (!isConductor)
589+
trans = handle;
590+
//
591+
auto* mul = frontPool.deref(handle);
592+
const auto ctH = frontPool.emplace<frontend_ir_t::CCookTorrance>();
593+
auto* const ct = frontPool.deref(ctH);
594+
{
595+
auto roughness = ct->ndParams.getRougness();
596+
if (_bsdf->type==CElementBSDF::ROUGHCONDUCTOR)
597+
{
598+
const CElementBSDF::RoughSpecularBase* rough = &_bsdf->dielectric;
599+
if (isConductor)
600+
rough = &_bsdf->conductor;
601+
// ct->orientedRealEta gets set in the fresnel part
602+
ct->ndf = ndfMap[rough->distribution];
603+
getParameter(roughness,rough->alphaU);
604+
if (rough->alphaV.texture || !hlsl::isnan(rough->alphaV.value))
605+
getParameter(roughness,rough->alphaU);
606+
else
607+
roughness[1] = roughness[0];
608+
}
609+
else
610+
roughness[0].scale = roughness[1].scale = 0.f;
611+
mul->lhs = ctH;
612+
}
613+
// Now the fresnels
614+
// do the artificial Mitsuba factor
615+
{
616+
const auto reflectanceMulH = frontPool.emplace<frontend_ir_t::CMul>();
617+
{
618+
auto* const reflectanceMul = frontPool.deref(reflectanceMulH);
619+
{
620+
const auto fresnelH = frontPool.emplace<frontend_ir_t::CFresnel>();
621+
auto* const fresnel = frontPool.deref(fresnelH);
622+
if (isConductor)
623+
{
624+
const float extEta = _bsdf->conductor.extEta;
625+
{
626+
spectral_var_t::SCreationParams<3> params = {};
627+
params.getSemantics() = spectral_var_t::Semantics::Fixed3_SRGB;
628+
const hlsl::float32_t3 eta = _bsdf->conductor.eta.vvalue.xyz;
629+
getParameter<3>(params.knots.params,eta/extEta);
630+
fresnel->orientedRealEta = frontPool.emplace<spectral_var_t>(std::move(params));
631+
}
632+
{
633+
spectral_var_t::SCreationParams<3> params = {};
634+
params.getSemantics() = spectral_var_t::Semantics::Fixed3_SRGB;
635+
const hlsl::float32_t3 k = _bsdf->conductor.k.vvalue.xyz;
636+
getParameter<3>(params.knots.params,k/extEta);
637+
fresnel->orientedImagEta = frontPool.emplace<spectral_var_t>(std::move(params));
638+
}
639+
}
640+
else
641+
{
642+
spectral_var_t::SCreationParams<1> params = {};
643+
params.knots.params[0].scale = _bsdf->dielectric.intIOR/_bsdf->dielectric.extIOR;
644+
ct->orientedRealEta = fresnel->orientedRealEta = frontPool.emplace<spectral_var_t>(std::move(params));
645+
}
646+
reflectanceMul->lhs = fresnelH;
647+
// make the trans node refraction-less for thin dielectric and apply thin scattering correction to the transmissive fresnel
648+
if (_bsdf->type==CElementBSDF::THINDIELECTRIC)
649+
{
650+
const auto btdfH = frontPool.emplace<frontend_ir_t::CMul>();
651+
{
652+
auto* mul = frontPool.deref(btdfH);
653+
// apply energy conserving correction
654+
const auto thinInfiniteScatterH = frontPool.emplace<frontend_ir_t::CThinInfiniteScatterCorrection>();
655+
{
656+
auto* thinInfiniteScatter = frontPool.deref(thinInfiniteScatterH);
657+
thinInfiniteScatter->reflectanceTop = fresnelH;
658+
thinInfiniteScatter->reflectanceBottom = fresnelH;
659+
// TODO: extinction
660+
}
661+
mul->lhs = frontPool.emplace<frontend_ir_t::CDeltaTransmission>(); // TODO: commonalize
662+
mul->rhs = thinInfiniteScatterH;
663+
}
664+
trans = btdfH;
665+
}
666+
}
667+
{
668+
spectral_var_t::SCreationParams<3> params = {};
669+
params.getSemantics() = spectral_var_t::Semantics::Fixed3_SRGB;
670+
if (isConductor)
671+
getParameter(params.knots.params,_bsdf->conductor.specularReflectance);
672+
else // we'll do the specularTransmittance on the btdf stack element when cloning
673+
getParameter(params.knots.params,_bsdf->dielectric.specularReflectance);
674+
const auto artificialReflectanceH = frontPool.emplace<spectral_var_t>(std::move(params));
675+
frontPool.deref(artificialReflectanceH)->debugInfo = commonDebugNames[uint16_t(ECommonDebug::MitsubaExtraFactor)]._const_cast();
676+
reflectanceMul->rhs = artificialReflectanceH;
677+
}
678+
}
679+
mul->rhs = reflectanceMulH;
680+
}
681+
}
682+
return {.top=handle,.trans=trans};
561683
}
562684
default:
563685
assert(false); // we shouldn't get this case here
@@ -568,7 +690,24 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
568690
// Post-order Depth First Traversal (create children first, then create parent)
569691
if (bsdf->isMeta()) // TODO: temporary
570692
return {};
571-
frontPool.deref(rootH)->brdfTop = createMistubaLeaf();
693+
auto* const layer = frontPool.deref(rootH);
694+
{
695+
const SLeaf leaf = createMistubaLeaf(bsdf);
696+
layer->brdfTop = leaf.top;
697+
layer->btdf = leaf.trans;
698+
}
699+
// handle BTDF and bottom BRDF layer
700+
switch (bsdf->type)
701+
{
702+
case CElementBSDF::DIELECTRIC: [[fallthrough]];
703+
case CElementBSDF::THINDIELECTRIC: [[fallthrough]];
704+
case CElementBSDF::ROUGHDIELECTRIC:
705+
// material compiler is designed so that we don't need to reciprocate the BRDFs as we go through layers as long as observer is still on the same side
706+
layer->brdfBottom = layer->brdfTop;
707+
break;
708+
default:
709+
break;
710+
}
572711
#if 0
573712
core::stack<const CElementBSDF*> stack;
574713
stack.push(bsdf);
@@ -887,6 +1026,7 @@ SContext::SContext(
8871026
{
8881027
#define ADD_DEBUG_NODE(NAME) commonDebugNames[uint16_t(ECommonDebug::NAME)] = frontPool.emplace<frontend_ir_t::CDebugInfo>(#NAME)
8891028
ADD_DEBUG_NODE(Albedo);
1029+
ADD_DEBUG_NODE(MitsubaExtraFactor);
8901030
#undef ADD_DEBUG_NODE
8911031
}
8921032
}

src/nbl/ext/MitsubaLoader/CMitsubaMaterialCompilerFrontend.cpp

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,6 @@ CMitsubaMaterialCompilerFrontend::tex_ass_type CMitsubaMaterialCompilerFrontend:
295295
using namespace material_compiler;
296296

297297

298-
constexpr IR::CMicrofacetSpecularBSDFNode::E_NDF ndfMap[4]{
299-
IR::CMicrofacetSpecularBSDFNode::ENDF_BECKMANN,
300-
IR::CMicrofacetSpecularBSDFNode::ENDF_GGX,
301-
IR::CMicrofacetSpecularBSDFNode::ENDF_PHONG,
302-
IR::CMicrofacetSpecularBSDFNode::ENDF_ASHIKHMIN_SHIRLEY
303-
};
304298

305299
const auto type = _bsdf->type;
306300
IRNode* ir_node = nullptr;
@@ -318,30 +312,6 @@ CMitsubaMaterialCompilerFrontend::tex_ass_type CMitsubaMaterialCompilerFrontend:
318312

319313

320314

321-
case CElementBSDF::CONDUCTOR:
322-
case CElementBSDF::ROUGHCONDUCTOR:
323-
{
324-
ir_node = ir->allocNode<IR::CMicrofacetSpecularBSDFNode>();
325-
auto* node = static_cast<IR::CMicrofacetSpecularBSDFNode*>(ir_node);
326-
node->shadowing = IR::CMicrofacetSpecularBSDFNode::EST_SMITH;
327-
const float extEta = _bsdf->conductor.extEta;
328-
node->eta = _bsdf->conductor.eta.vvalue/extEta;
329-
node->etaK = _bsdf->conductor.k.vvalue/extEta;
330-
331-
if (type == CElementBSDF::ROUGHCONDUCTOR)
332-
{
333-
node->ndf = ndfMap[_bsdf->conductor.distribution];
334-
getFloatOrTexture(_bsdf->conductor.alphaU, node->alpha_u);
335-
if (node->ndf == IR::CMicrofacetSpecularBSDFNode::ENDF_ASHIKHMIN_SHIRLEY)
336-
getFloatOrTexture(_bsdf->conductor.alphaV, node->alpha_v);
337-
else
338-
node->alpha_v = node->alpha_u;
339-
}
340-
else
341-
{
342-
node->setSmooth();
343-
}
344-
}
345315
break;
346316
case CElementBSDF::DIFFUSE_TRANSMITTER:
347317
{
@@ -384,37 +354,10 @@ CMitsubaMaterialCompilerFrontend::tex_ass_type CMitsubaMaterialCompilerFrontend:
384354
node_diffuse->eta = coat->eta;
385355
}
386356
break;
387-
case CElementBSDF::DIELECTRIC:
388-
case CElementBSDF::THINDIELECTRIC:
389-
case CElementBSDF::ROUGHDIELECTRIC:
390-
{
391-
auto* dielectric = ir->allocNode<IR::CMicrofacetDielectricBSDFNode>();
392-
ir_node = dielectric;
393357

394-
const float eta = _bsdf->dielectric.intIOR/_bsdf->dielectric.extIOR;
395-
_NBL_DEBUG_BREAK_IF(eta==1.f);
396-
if (eta == 1.f)
397-
_logger.log("WARNING: Dielectric with IoR=1.0!", system::ILogger::E_LOG_LEVEL::ELL_ERROR);
398358

399-
dielectric->shadowing = IR::CMicrofacetSpecularBSDFNode::EST_SMITH;
400-
dielectric->eta = IR::INode::color_t(eta);
401-
if (type == CElementBSDF::ROUGHDIELECTRIC)
402-
{
403-
dielectric->ndf = ndfMap[_bsdf->dielectric.distribution];
404-
getFloatOrTexture(_bsdf->dielectric.alphaU, dielectric->alpha_u);
405-
if (dielectric->ndf == IR::CMicrofacetSpecularBSDFNode::ENDF_ASHIKHMIN_SHIRLEY)
406-
getFloatOrTexture(_bsdf->dielectric.alphaV, dielectric->alpha_v);
407-
else
408-
dielectric->alpha_v = dielectric->alpha_u;
409-
}
410-
else
411-
{
412-
dielectric->setSmooth();
413-
}
414359

415-
dielectric->thin = (type == CElementBSDF::THINDIELECTRIC);
416-
}
417-
break;
360+
418361
case CElementBSDF::BUMPMAP:
419362
{
420363
ir_node = ir->allocNode<IR::CGeomModifierNode>(IR::CGeomModifierNode::ET_DERIVATIVE);

0 commit comments

Comments
 (0)