Skip to content
Merged
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
2 changes: 1 addition & 1 deletion include/nbl/asset/ICPUScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class ICPUScene final : public IAsset, public IScene
instances.emplace_back().instance = std::move(inst);
}
// TODO: adjust BLAS geometry flags according to materials set opaqueness and NO_DUPLICATE_ANY_HIT_INVOCATION_BIT
SResult retval = {.instances=core::make_refctd_dynamic_array<decltype(SResult::instances)>(instanceCount),.allInstancesValid=allInstancesValid};
SResult retval = {.instances=core::make_refctd_dynamic_array<decltype(SResult::instances)>(instances.size()),.allInstancesValid=allInstancesValid};
std::move(instances.begin(),instances.end(),retval.instances->begin());
return retval;
}
Expand Down
265 changes: 221 additions & 44 deletions include/nbl/asset/material_compiler3/CFrontendIR.h

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions include/nbl/ext/MitsubaLoader/SContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct SContext final
#endif
core::smart_refctd_ptr<frontend_ir_t> frontIR;
// common frontend nodes
frontend_ir_t::typed_pointer_type<const frontend_ir_t::CSpectralVariable> unityFactor;
frontend_ir_t::typed_pointer_type<const frontend_ir_t::IExprNode> errorBRDF;
frontend_ir_t::typed_pointer_type<const frontend_ir_t::CLayer> errorMaterial, unsupportedPhong, unsupportedWard;
frontend_ir_t::typed_pointer_type<const frontend_ir_t::CDeltaTransmission> deltaTransmission;
Expand All @@ -95,6 +96,7 @@ struct SContext final
{
Albedo,
Opacity,
Weight,
MitsubaExtraFactor,
Count
};
Expand Down
7 changes: 4 additions & 3 deletions src/nbl/asset/interchange/CImageLoaderJPG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,11 @@ bool CImageLoaderJPG::isALoadableFileFormat(system::IFile* _file, const system::
if (!_file)
return false;

uint32_t header = 0;
uint16_t soiMarker = 0;
system::IFile::success_t success;
_file->read(success, &header, 6, sizeof(uint32_t));
return success && ((header&0x00FFD8FFu)==0x00FFD8FFu || header == 0x4a464946 || header == 0x4649464a || header == 0x66697845u || header == 0x70747468u); // maybe 0x4a464946 can go
_file->read(success, &soiMarker, 0, sizeof(uint16_t));
constexpr auto JPEG_VALID_SOI_MARKER = 0xD8FF;
return success && (soiMarker == JPEG_VALID_SOI_MARKER);
#endif
}

Expand Down
134 changes: 124 additions & 10 deletions src/nbl/asset/material_compiler3/CFrontendIR.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2022-2025 - DevSH Graphics Programming Sp. z O.O.
// Copyright (C) 2022-2025 - DevSH Graphics Programming Sp. z O.O.
// This file is part of the "Nabla Engine".
// For conditions of distribution and use, see copyright notice in nabla.h
#include "nbl/asset/material_compiler3/CFrontendIR.h"
Expand Down Expand Up @@ -32,6 +32,11 @@ bool CFrontendIR::CBeer::invalid(const SInvalidCheckArgs& args) const
args.logger.log("Perpendicular Transparency node of correct type must be attached, but is %u of type %s",ELL_ERROR,perpTransmittance,args.pool->getTypeName(perpTransmittance).data());
return true;
}
if (const auto* const thick=args.pool->getObjectPool().deref(thickness); !thick || thick->getKnotCount()!=1)
{
args.logger.log("Monochromatic Thickness node must be attached, but is %u of type %s",ELL_ERROR,thickness,args.pool->getTypeName(thickness).data());
return true;
}
return false;
}

Expand Down Expand Up @@ -111,18 +116,127 @@ bool CFrontendIR::CCookTorrance::invalid(const SInvalidCheckArgs& args) const
}


auto CFrontendIR::reciprocate(const typed_pointer_type<const IExprNode> other) -> typed_pointer_type<IExprNode>
auto CFrontendIR::reciprocate(const typed_pointer_type<const IExprNode> orig) -> typed_pointer_type<const IExprNode>
{
if (const auto* in=getObjectPool().deref(block_allocator_type::_static_cast<const CFresnel>(other)); in)
auto& pool = getObjectPool();
struct SEntry
{
typed_pointer_type<const IExprNode> handle;
bool visited = false;
};
core::vector<SEntry> stack;
stack.reserve(32);
stack.push_back({.handle=orig});
// use a hashmap because of holes in child arrays
core::unordered_map<typed_pointer_type<const IExprNode>,typed_pointer_type<IExprNode>> substitutions;
while (!stack.empty())
{
auto fresnelH = getObjectPool().emplace<CFresnel>();
auto* fresnel = getObjectPool().deref(fresnelH);
*fresnel = *in;
fresnel->reciprocateEtas = ~in->reciprocateEtas;
return fresnelH;
auto& entry = stack.back();
const auto* const node = pool.deref(entry.handle);
if (!node) // this is an error
return {};
const auto childCount = node->getChildCount();
if (entry.visited)
{
entry.visited = true;
for (uint8_t c=0; c<childCount; c++)
{
const auto childH = node->getChildHandle(c);
if (auto child=pool.deref(childH); !child)
continue; // this is not an error
stack.push_back({.handle=childH});
}
}
else
{
const bool needToReciprocate = node->reciprocatable();
bool needToCopy = needToReciprocate;
// if one descendant has changed then we need to copy node
if (!needToCopy)
{
uint8_t c = 0;
for (; c<childCount; c++)
{
if (auto found=substitutions.find(node->getChildHandle(c)); found!=substitutions.end())
break;
}
needToCopy = c!=childCount;
}
if (needToCopy)
{
const auto copyH = node->copy(this);
// copy copies everything including children
auto* const copy = pool.deref(copyH);
if (!copy)
return {};
if (needToReciprocate)
node->reciprocate(copy);
// only changed children need to be set
for (uint8_t c=0; c<childCount; c++)
{
const auto childH = node->getChildHandle(c);
if (!childH)
continue;
if (auto found=substitutions.find(childH); found!=substitutions.end())
copy->setChild(c,found->second);
}
substitutions.insert({entry.handle,copyH});
}
stack.pop_back();
}
}
// there was nothing to reciprocate in the expression stack
if (substitutions.empty())
return orig;
return substitutions[orig];
}

auto CFrontendIR::copyLayers(const typed_pointer_type<const CLayer> orig) -> typed_pointer_type<CLayer>
{
auto& pool = getObjectPool();
auto copyH = pool.emplace<CLayer>();
{
auto* outLayer = pool.deref(copyH);
for (const auto* layer=pool.deref(orig); true; layer=pool.deref(layer->coated))
{
*outLayer = *layer;
if (!layer->coated)
{
// terminate the new stack
outLayer->coated = {};
break;
}
// continue the new stack
outLayer->coated = pool.emplace<CLayer>();
outLayer = pool.deref(outLayer->coated);
}
}
return copyH;
}

auto CFrontendIR::reverse(const typed_pointer_type<const CLayer> orig) -> typed_pointer_type<CLayer>
{
auto& pool = getObjectPool();
// we build the new linked list from the tail
auto copyH = pool.emplace<CLayer>();
{
auto* outLayer = pool.deref(copyH);
typed_pointer_type<CLayer> underLayerH={};
for (const auto* layer=pool.deref(orig); true; layer=pool.deref(layer->coated))
{
outLayer->coated = underLayerH;
// we reciprocate everything because numerator and denominator switch (top and bottom of layer stack)
outLayer->brdfBottom = reciprocate(layer->brdfTop)._const_cast();
outLayer->btdf = reciprocate(layer->btdf)._const_cast();
outLayer->brdfTop = reciprocate(layer->brdfBottom)._const_cast();
if (!layer->coated)
break;
underLayerH = copyH;
copyH = pool.emplace<CLayer>();
outLayer = pool.deref(copyH);
}
}
assert(false); // unimplemented
return {};
return copyH;
}

auto CFrontendIR::createNamedFresnel(const std::string_view name) -> typed_pointer_type<CFresnel>
Expand Down
Loading
Loading