Skip to content
Closed
16 changes: 15 additions & 1 deletion include/nbl/asset/material_compiler3/CTrueIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ class CTrueIR : public CNodePool // TODO: turn into an asset!
};
virtual EFinalType getFinalType() const = 0;

virtual uint16_t getCapabilities() const { return 0; };
Comment thread
devshgraphicsprogramming marked this conversation as resolved.

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
Expand Down Expand Up @@ -876,6 +878,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);}
Expand Down Expand Up @@ -951,6 +955,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);}
Expand Down Expand Up @@ -990,12 +996,16 @@ 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);}

inline COrenNayar() = default;

NBL_API2 void printDot(std::ostringstream& sstr, const core::string& selfID) const override final;

protected:
COPY_DEFAULT_IMPL
};
Expand All @@ -1019,6 +1029,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);}
Expand All @@ -1035,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;}
Expand Down Expand Up @@ -1488,7 +1502,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
{
Expand Down
86 changes: 86 additions & 0 deletions src/nbl/asset/material_compiler3/CTrueIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,62 @@ bool CTrueIR::SRewriteSession::rewriteSingleLayer(typed_pointer_type<const COrie
// observations:
// - Any V-dependent factors cannot be commonalized across layers, most of the CSE has to be done within a layer

auto& dstPool = args.dst->getObjectPool();
const auto& srcPool = args.src->getObjectPool();
SMaterial::SMetadata metadata = {};

core::vector<typed_pointer_type<const INode>> stack;
stack.reserve(32);
stack.push_back(oriented);
// use a hashmap to not explore whole DAG
core::unordered_map<typed_pointer_type<const INode>, typed_pointer_type<INode>> 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<const CSpectralVariableFactor*>(node);
metadata.usedUVSlots.set(factor->uvSlot(), true);
}
metadata.capabilities |= core::bitflag<SMaterial::SMetadata::ECapabilityBits>(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

Expand All @@ -310,6 +365,11 @@ void CTrueIR::ISpectralVariableFactor::printDot(std::ostringstream& sstr, const
printDotParameterSet(*pWonky(), getKnotCount(), sstr, selfID, {});
}

uint16_t CTrueIR::CEmitter::getCapabilities() const
{
return static_cast<uint16_t>(SMaterial::SMetadata::ECapabilityBits::NonSpatiallyVaryingEmissive | SMaterial::SMetadata::ECapabilityBits::NotBlackhole);
}

void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& selfID) const
{
if (profile)
Expand All @@ -325,5 +385,31 @@ void CTrueIR::CEmitter::printDot(std::ostringstream& sstr, const core::string& s
}
}

uint16_t CTrueIR::CDeltaTransmission::getCapabilities() const
{
return static_cast<uint16_t>(SMaterial::SMetadata::ECapabilityBits::DeltaTransmissive | SMaterial::SMetadata::ECapabilityBits::NotBlackhole);
}

uint16_t CTrueIR::COrenNayar::getCapabilities() const
{
return static_cast<uint16_t>(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<uint16_t>(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);
}

template class CTrueIR::CSpectralVariable<CTrueIR::ISpectralVariableFactor>;
}
Loading