From b241eb003bb5a0490c6f9b1d6aa9d4eac69b4e39 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 15 May 2026 15:03:09 +0700 Subject: [PATCH 1/7] fixed printing CEmitter profile duplicating node name --- src/nbl/asset/material_compiler3/CFrontendIR.cpp | 6 +++++- src/nbl/asset/material_compiler3/CTrueIR.cpp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/nbl/asset/material_compiler3/CFrontendIR.cpp b/src/nbl/asset/material_compiler3/CFrontendIR.cpp index 5af5f25e01..61e07e87da 100644 --- a/src/nbl/asset/material_compiler3/CFrontendIR.cpp +++ b/src/nbl/asset/material_compiler3/CFrontendIR.cpp @@ -524,7 +524,11 @@ void CFrontendIR::ISpectralVariableExpr::printDot(std::ostringstream& sstr, cons void CFrontendIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& selfID) const { if (profile) - profile.printDot(sstr,selfID); + { + const auto profileNodeID = selfID + "_profile"; + profile.printDot(sstr, profileNodeID); + sstr << "\n\t" << selfID << " -> " << profileNodeID << "[label=\"Profile\"]"; + } if (profile.view) { const auto transformNodeID = selfID+"_pTform"; diff --git a/src/nbl/asset/material_compiler3/CTrueIR.cpp b/src/nbl/asset/material_compiler3/CTrueIR.cpp index d6f05bd104..4a44aac09f 100644 --- a/src/nbl/asset/material_compiler3/CTrueIR.cpp +++ b/src/nbl/asset/material_compiler3/CTrueIR.cpp @@ -309,7 +309,11 @@ void CTrueIR::ISpectralVariableFactor::printDot(std::ostringstream& sstr, const void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& selfID) const { if (profile) - profile.printDot(sstr, selfID); + { + const auto profileNodeID = selfID + "_profile"; + profile.printDot(sstr, profileNodeID); + sstr << "\n\t" << selfID << " -> " << profileNodeID << "[label=\"Profile\"]"; + } if (profile.view) { const auto transformNodeID = selfID + "_pTform"; From 4fd970752b3b6b7f2b8f2c5eaf8849b89c0b544d Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 15 May 2026 16:12:41 +0700 Subject: [PATCH 2/7] INode getCapabilities method for getting metadata capabilities, use in rewriteSingleLayer to set metadata --- .../nbl/asset/material_compiler3/CTrueIR.h | 12 ++- src/nbl/asset/material_compiler3/CTrueIR.cpp | 76 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/include/nbl/asset/material_compiler3/CTrueIR.h b/include/nbl/asset/material_compiler3/CTrueIR.h index afc3a6604e..9a08f031cd 100644 --- a/include/nbl/asset/material_compiler3/CTrueIR.h +++ b/include/nbl/asset/material_compiler3/CTrueIR.h @@ -219,6 +219,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! }; virtual EFinalType getFinalType() const = 0; + virtual uint16_t getCapabilities() const = 0; + const auto& getHash() const {return hash;} // only call once the nodes underneath are linked up (because it doesn't call recursively), returning empty hash means error/invalid node @@ -862,6 +864,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CEmitter;} + uint16_t getCapabilities() const override final; + inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CEmitter);} @@ -937,6 +941,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CDeltaTransmission;} + uint16_t getCapabilities() const override final; + inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CDeltaTransmission);} @@ -971,6 +977,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! inline EFinalType getFinalType() const override {return EFinalType::COrenNayar;} + uint16_t getCapabilities() const override final; + inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(COrenNayar);} @@ -998,6 +1006,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CCookTorrance;} + uint16_t getCapabilities() const override final; + inline uint8_t getChildCount() const override final { return 1; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CCookTorrance);} @@ -1427,7 +1437,7 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! const CTrueIR* const src; CTrueIR* const dst; - const SMaterial::SMetadata* pMetadata; + SMaterial::SMetadata* pMetadata; }; struct SRewriteSession final { diff --git a/src/nbl/asset/material_compiler3/CTrueIR.cpp b/src/nbl/asset/material_compiler3/CTrueIR.cpp index 4a44aac09f..acc2d08686 100644 --- a/src/nbl/asset/material_compiler3/CTrueIR.cpp +++ b/src/nbl/asset/material_compiler3/CTrueIR.cpp @@ -292,7 +292,62 @@ bool CTrueIR::SRewriteSession::rewriteSingleLayer(typed_pointer_typegetObjectPool(); + const auto& srcPool = args.src->getObjectPool(); + SMaterial::SMetadata metadata = {}; + + core::vector> stack; + stack.reserve(32); + stack.push_back(oriented); + // use a hashmap to not explore whole DAG + core::unordered_map, typed_pointer_type> substitutions; + while (!stack.empty()) + { + const auto entry = stack.back(); + const auto* const node = srcPool.deref(entry); + if (!node) + return false; + const auto childCount = node->getChildCount(); + if (auto& copyH = substitutions[entry]; !copyH) + { + for (uint8_t c = 0; c < childCount; c++) + { + const auto childH = node->getChildHandle(c); + if (auto child = srcPool.deref(childH); !child) + continue; + stack.push_back(childH); + } + + copyH = node->copy(args.dst); + if (!copyH) + return false; + } + else + { + auto* const copy = dstPool.deref(copyH); + for (uint8_t c = 0; c < childCount; c++) + { + const auto childH = node->getChildHandle(c); + if (!childH) + continue; + auto found = substitutions.find(childH); + assert(found != substitutions.end()); + copy->setChild(dstPool, c, found->second); + } + stack.pop_back(); + + if (node->getFinalType() == INode::EFinalType::CSpectralVariable) + { + const auto* factor = dynamic_cast(node); + metadata.usedUVSlots.set(factor->uvSlot(), true); + } + metadata.capabilities |= core::bitflag(node->getCapabilities()); + } + } + // TODO: combine layer meta with `retval.metadata` + args.pMetadata->usedUVSlots = metadata.usedUVSlots; + args.pMetadata->capabilities |= metadata.capabilities; // TODO: deduplicate, collect metadata and insert into current IR @@ -306,6 +361,11 @@ void CTrueIR::ISpectralVariableFactor::printDot(std::ostringstream& sstr, const printDotParameterSet(*pWonky(), getKnotCount(), sstr, selfID, {}); } +uint16_t CTrueIR::CEmitter::getCapabilities() const +{ + return static_cast(SMaterial::SMetadata::ECapabilityBits::NonSpatiallyVaryingEmissive | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); +} + void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& selfID) const { if (profile) @@ -325,11 +385,27 @@ void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& s } } +uint16_t CTrueIR::CDeltaTransmission::getCapabilities() const +{ + return static_cast(SMaterial::SMetadata::ECapabilityBits::DeltaTransmissive | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); +} + +uint16_t CTrueIR::COrenNayar::getCapabilities() const +{ + return static_cast(SMaterial::SMetadata::ECapabilityBits::OrenNayar | SMaterial::SMetadata::ECapabilityBits::NonDelta | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); +} + void CTrueIR::COrenNayar::printDot(std::ostringstream& sstr, const core::string& selfID) const { ndfParams.printDot(sstr, selfID); } +uint16_t CTrueIR::CCookTorrance::getCapabilities() const +{ + // TODO: could be either beckmann or ggx, also anisotropic? maybe get from ndf params? + return static_cast(SMaterial::SMetadata::ECapabilityBits::GGX | SMaterial::SMetadata::ECapabilityBits::NonDelta | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); +} + void CTrueIR::CCookTorrance::printDot(std::ostringstream& sstr, const core::string& selfID) const { ndfParams.printDot(sstr, selfID); From dd3983fb32632d553d2ae4ae07a062e2cea3a957 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 15 May 2026 16:39:45 +0700 Subject: [PATCH 3/7] Revert "INode getCapabilities method for getting metadata capabilities, use in rewriteSingleLayer to set metadata" This reverts commit 4fd970752b3b6b7f2b8f2c5eaf8849b89c0b544d. --- .../nbl/asset/material_compiler3/CTrueIR.h | 12 +-- src/nbl/asset/material_compiler3/CTrueIR.cpp | 76 ------------------- 2 files changed, 1 insertion(+), 87 deletions(-) diff --git a/include/nbl/asset/material_compiler3/CTrueIR.h b/include/nbl/asset/material_compiler3/CTrueIR.h index 9a08f031cd..afc3a6604e 100644 --- a/include/nbl/asset/material_compiler3/CTrueIR.h +++ b/include/nbl/asset/material_compiler3/CTrueIR.h @@ -219,8 +219,6 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! }; virtual EFinalType getFinalType() const = 0; - virtual uint16_t getCapabilities() const = 0; - const auto& getHash() const {return hash;} // only call once the nodes underneath are linked up (because it doesn't call recursively), returning empty hash means error/invalid node @@ -864,8 +862,6 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CEmitter;} - uint16_t getCapabilities() const override final; - inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CEmitter);} @@ -941,8 +937,6 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CDeltaTransmission;} - uint16_t getCapabilities() const override final; - inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CDeltaTransmission);} @@ -977,8 +971,6 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! inline EFinalType getFinalType() const override {return EFinalType::COrenNayar;} - uint16_t getCapabilities() const override final; - inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(COrenNayar);} @@ -1006,8 +998,6 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CCookTorrance;} - uint16_t getCapabilities() const override final; - inline uint8_t getChildCount() const override final { return 1; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CCookTorrance);} @@ -1437,7 +1427,7 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! const CTrueIR* const src; CTrueIR* const dst; - SMaterial::SMetadata* pMetadata; + const SMaterial::SMetadata* pMetadata; }; struct SRewriteSession final { diff --git a/src/nbl/asset/material_compiler3/CTrueIR.cpp b/src/nbl/asset/material_compiler3/CTrueIR.cpp index acc2d08686..4a44aac09f 100644 --- a/src/nbl/asset/material_compiler3/CTrueIR.cpp +++ b/src/nbl/asset/material_compiler3/CTrueIR.cpp @@ -292,62 +292,7 @@ bool CTrueIR::SRewriteSession::rewriteSingleLayer(typed_pointer_typegetObjectPool(); - const auto& srcPool = args.src->getObjectPool(); - SMaterial::SMetadata metadata = {}; - - core::vector> stack; - stack.reserve(32); - stack.push_back(oriented); - // use a hashmap to not explore whole DAG - core::unordered_map, typed_pointer_type> substitutions; - while (!stack.empty()) - { - const auto entry = stack.back(); - const auto* const node = srcPool.deref(entry); - if (!node) - return false; - const auto childCount = node->getChildCount(); - if (auto& copyH = substitutions[entry]; !copyH) - { - for (uint8_t c = 0; c < childCount; c++) - { - const auto childH = node->getChildHandle(c); - if (auto child = srcPool.deref(childH); !child) - continue; - stack.push_back(childH); - } - - copyH = node->copy(args.dst); - if (!copyH) - return false; - } - else - { - auto* const copy = dstPool.deref(copyH); - for (uint8_t c = 0; c < childCount; c++) - { - const auto childH = node->getChildHandle(c); - if (!childH) - continue; - auto found = substitutions.find(childH); - assert(found != substitutions.end()); - copy->setChild(dstPool, c, found->second); - } - stack.pop_back(); - - if (node->getFinalType() == INode::EFinalType::CSpectralVariable) - { - const auto* factor = dynamic_cast(node); - metadata.usedUVSlots.set(factor->uvSlot(), true); - } - metadata.capabilities |= core::bitflag(node->getCapabilities()); - } - } - // TODO: combine layer meta with `retval.metadata` - args.pMetadata->usedUVSlots = metadata.usedUVSlots; - args.pMetadata->capabilities |= metadata.capabilities; // TODO: deduplicate, collect metadata and insert into current IR @@ -361,11 +306,6 @@ void CTrueIR::ISpectralVariableFactor::printDot(std::ostringstream& sstr, const printDotParameterSet(*pWonky(), getKnotCount(), sstr, selfID, {}); } -uint16_t CTrueIR::CEmitter::getCapabilities() const -{ - return static_cast(SMaterial::SMetadata::ECapabilityBits::NonSpatiallyVaryingEmissive | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); -} - void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& selfID) const { if (profile) @@ -385,27 +325,11 @@ void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& s } } -uint16_t CTrueIR::CDeltaTransmission::getCapabilities() const -{ - return static_cast(SMaterial::SMetadata::ECapabilityBits::DeltaTransmissive | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); -} - -uint16_t CTrueIR::COrenNayar::getCapabilities() const -{ - return static_cast(SMaterial::SMetadata::ECapabilityBits::OrenNayar | SMaterial::SMetadata::ECapabilityBits::NonDelta | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); -} - void CTrueIR::COrenNayar::printDot(std::ostringstream& sstr, const core::string& selfID) const { ndfParams.printDot(sstr, selfID); } -uint16_t CTrueIR::CCookTorrance::getCapabilities() const -{ - // TODO: could be either beckmann or ggx, also anisotropic? maybe get from ndf params? - return static_cast(SMaterial::SMetadata::ECapabilityBits::GGX | SMaterial::SMetadata::ECapabilityBits::NonDelta | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); -} - void CTrueIR::CCookTorrance::printDot(std::ostringstream& sstr, const core::string& selfID) const { ndfParams.printDot(sstr, selfID); From 7db70f316a39bc1f73732e4b52cdabe1fc1a73cf Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 15 May 2026 16:40:27 +0700 Subject: [PATCH 4/7] Revert "fixed printing CEmitter profile duplicating node name" This reverts commit b241eb003bb5a0490c6f9b1d6aa9d4eac69b4e39. --- src/nbl/asset/material_compiler3/CFrontendIR.cpp | 6 +----- src/nbl/asset/material_compiler3/CTrueIR.cpp | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/nbl/asset/material_compiler3/CFrontendIR.cpp b/src/nbl/asset/material_compiler3/CFrontendIR.cpp index 61e07e87da..5af5f25e01 100644 --- a/src/nbl/asset/material_compiler3/CFrontendIR.cpp +++ b/src/nbl/asset/material_compiler3/CFrontendIR.cpp @@ -524,11 +524,7 @@ void CFrontendIR::ISpectralVariableExpr::printDot(std::ostringstream& sstr, cons void CFrontendIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& selfID) const { if (profile) - { - const auto profileNodeID = selfID + "_profile"; - profile.printDot(sstr, profileNodeID); - sstr << "\n\t" << selfID << " -> " << profileNodeID << "[label=\"Profile\"]"; - } + profile.printDot(sstr,selfID); if (profile.view) { const auto transformNodeID = selfID+"_pTform"; diff --git a/src/nbl/asset/material_compiler3/CTrueIR.cpp b/src/nbl/asset/material_compiler3/CTrueIR.cpp index 4a44aac09f..d6f05bd104 100644 --- a/src/nbl/asset/material_compiler3/CTrueIR.cpp +++ b/src/nbl/asset/material_compiler3/CTrueIR.cpp @@ -309,11 +309,7 @@ void CTrueIR::ISpectralVariableFactor::printDot(std::ostringstream& sstr, const void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& selfID) const { if (profile) - { - const auto profileNodeID = selfID + "_profile"; - profile.printDot(sstr, profileNodeID); - sstr << "\n\t" << selfID << " -> " << profileNodeID << "[label=\"Profile\"]"; - } + profile.printDot(sstr, selfID); if (profile.view) { const auto transformNodeID = selfID + "_pTform"; From c942470fc988194b90084dba248b73575d08972c Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 15 May 2026 16:12:41 +0700 Subject: [PATCH 5/7] INode getCapabilities method for getting metadata capabilities, use in rewriteSingleLayer to set metadata --- .../nbl/asset/material_compiler3/CTrueIR.h | 12 ++- src/nbl/asset/material_compiler3/CTrueIR.cpp | 76 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/include/nbl/asset/material_compiler3/CTrueIR.h b/include/nbl/asset/material_compiler3/CTrueIR.h index afc3a6604e..9a08f031cd 100644 --- a/include/nbl/asset/material_compiler3/CTrueIR.h +++ b/include/nbl/asset/material_compiler3/CTrueIR.h @@ -219,6 +219,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! }; virtual EFinalType getFinalType() const = 0; + virtual uint16_t getCapabilities() const = 0; + const auto& getHash() const {return hash;} // only call once the nodes underneath are linked up (because it doesn't call recursively), returning empty hash means error/invalid node @@ -862,6 +864,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CEmitter;} + uint16_t getCapabilities() const override final; + inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CEmitter);} @@ -937,6 +941,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CDeltaTransmission;} + uint16_t getCapabilities() const override final; + inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CDeltaTransmission);} @@ -971,6 +977,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! inline EFinalType getFinalType() const override {return EFinalType::COrenNayar;} + uint16_t getCapabilities() const override final; + inline uint8_t getChildCount() const override final { return 0; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(COrenNayar);} @@ -998,6 +1006,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! public: inline EFinalType getFinalType() const override {return EFinalType::CCookTorrance;} + uint16_t getCapabilities() const override final; + inline uint8_t getChildCount() const override final { return 1; } inline const std::string_view getTypeName() const override {return TYPE_NAME_STR(CCookTorrance);} @@ -1427,7 +1437,7 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! const CTrueIR* const src; CTrueIR* const dst; - const SMaterial::SMetadata* pMetadata; + SMaterial::SMetadata* pMetadata; }; struct SRewriteSession final { diff --git a/src/nbl/asset/material_compiler3/CTrueIR.cpp b/src/nbl/asset/material_compiler3/CTrueIR.cpp index d6f05bd104..b424af5e71 100644 --- a/src/nbl/asset/material_compiler3/CTrueIR.cpp +++ b/src/nbl/asset/material_compiler3/CTrueIR.cpp @@ -292,7 +292,62 @@ bool CTrueIR::SRewriteSession::rewriteSingleLayer(typed_pointer_typegetObjectPool(); + const auto& srcPool = args.src->getObjectPool(); + SMaterial::SMetadata metadata = {}; + + core::vector> stack; + stack.reserve(32); + stack.push_back(oriented); + // use a hashmap to not explore whole DAG + core::unordered_map, typed_pointer_type> substitutions; + while (!stack.empty()) + { + const auto entry = stack.back(); + const auto* const node = srcPool.deref(entry); + if (!node) + return false; + const auto childCount = node->getChildCount(); + if (auto& copyH = substitutions[entry]; !copyH) + { + for (uint8_t c = 0; c < childCount; c++) + { + const auto childH = node->getChildHandle(c); + if (auto child = srcPool.deref(childH); !child) + continue; + stack.push_back(childH); + } + + copyH = node->copy(args.dst); + if (!copyH) + return false; + } + else + { + auto* const copy = dstPool.deref(copyH); + for (uint8_t c = 0; c < childCount; c++) + { + const auto childH = node->getChildHandle(c); + if (!childH) + continue; + auto found = substitutions.find(childH); + assert(found != substitutions.end()); + copy->setChild(dstPool, c, found->second); + } + stack.pop_back(); + + if (node->getFinalType() == INode::EFinalType::CSpectralVariable) + { + const auto* factor = dynamic_cast(node); + metadata.usedUVSlots.set(factor->uvSlot(), true); + } + metadata.capabilities |= core::bitflag(node->getCapabilities()); + } + } + // TODO: combine layer meta with `retval.metadata` + args.pMetadata->usedUVSlots = metadata.usedUVSlots; + args.pMetadata->capabilities |= metadata.capabilities; // TODO: deduplicate, collect metadata and insert into current IR @@ -306,6 +361,11 @@ void CTrueIR::ISpectralVariableFactor::printDot(std::ostringstream& sstr, const printDotParameterSet(*pWonky(), getKnotCount(), sstr, selfID, {}); } +uint16_t CTrueIR::CEmitter::getCapabilities() const +{ + return static_cast(SMaterial::SMetadata::ECapabilityBits::NonSpatiallyVaryingEmissive | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); +} + void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& selfID) const { if (profile) @@ -321,11 +381,27 @@ void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& s } } +uint16_t CTrueIR::CDeltaTransmission::getCapabilities() const +{ + return static_cast(SMaterial::SMetadata::ECapabilityBits::DeltaTransmissive | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); +} + +uint16_t CTrueIR::COrenNayar::getCapabilities() const +{ + return static_cast(SMaterial::SMetadata::ECapabilityBits::OrenNayar | SMaterial::SMetadata::ECapabilityBits::NonDelta | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); +} + void CTrueIR::COrenNayar::printDot(std::ostringstream& sstr, const core::string& selfID) const { ndfParams.printDot(sstr, selfID); } +uint16_t CTrueIR::CCookTorrance::getCapabilities() const +{ + // TODO: could be either beckmann or ggx, also anisotropic? maybe get from ndf params? + return static_cast(SMaterial::SMetadata::ECapabilityBits::GGX | SMaterial::SMetadata::ECapabilityBits::NonDelta | SMaterial::SMetadata::ECapabilityBits::NotBlackhole); +} + void CTrueIR::CCookTorrance::printDot(std::ostringstream& sstr, const core::string& selfID) const { ndfParams.printDot(sstr, selfID); From fa59ef96afbcfe7de7c6d7394e9ab4408161ab9c Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 18 May 2026 16:17:28 +0700 Subject: [PATCH 6/7] getCapabilities should not be abstract method --- include/nbl/asset/material_compiler3/CTrueIR.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nbl/asset/material_compiler3/CTrueIR.h b/include/nbl/asset/material_compiler3/CTrueIR.h index 9a08f031cd..dff476af9d 100644 --- a/include/nbl/asset/material_compiler3/CTrueIR.h +++ b/include/nbl/asset/material_compiler3/CTrueIR.h @@ -219,7 +219,7 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! }; virtual EFinalType getFinalType() const = 0; - virtual uint16_t getCapabilities() const = 0; + virtual uint16_t getCapabilities() const { return 0; }; const auto& getHash() const {return hash;} From 07536ad010a87a8cd8930a43ef40e8c4e49f315e Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 21 May 2026 14:46:32 +0700 Subject: [PATCH 7/7] re-add missing function defs after merge --- include/nbl/asset/material_compiler3/CTrueIR.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/nbl/asset/material_compiler3/CTrueIR.h b/include/nbl/asset/material_compiler3/CTrueIR.h index 61c79d7322..ce71a419f7 100644 --- a/include/nbl/asset/material_compiler3/CTrueIR.h +++ b/include/nbl/asset/material_compiler3/CTrueIR.h @@ -1004,6 +1004,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! inline COrenNayar() = default; + NBL_API2 void printDot(std::ostringstream& sstr, const core::string& selfID) const override final; + protected: COPY_DEFAULT_IMPL }; @@ -1045,6 +1047,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset! inline CCookTorrance() = default; + NBL_API2 void printDot(std::ostringstream& sstr, const core::string& selfID) const override final; + // inline bool isEtaReciprocal() const {return ndfParams.params[2].padding[0];} inline void setEtaReciprocal(const bool value) {ndfParams.params[2].padding[0] = value;}