Skip to content

Commit 1a3d26a

Browse files
Merge pull request #1021 from Devsh-Graphics-Programming/mitsuba_xml_2_material_frontend
Mitsuba Material Parsing complete
2 parents 00017ad + c292f41 commit 1a3d26a

8 files changed

Lines changed: 718 additions & 409 deletions

File tree

include/nbl/asset/ICPUScene.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ class ICPUScene final : public IAsset, public IScene
276276
instances.emplace_back().instance = std::move(inst);
277277
}
278278
// TODO: adjust BLAS geometry flags according to materials set opaqueness and NO_DUPLICATE_ANY_HIT_INVOCATION_BIT
279-
SResult retval = {.instances=core::make_refctd_dynamic_array<decltype(SResult::instances)>(instanceCount),.allInstancesValid=allInstancesValid};
279+
SResult retval = {.instances=core::make_refctd_dynamic_array<decltype(SResult::instances)>(instances.size()),.allInstancesValid=allInstancesValid};
280280
std::move(instances.begin(),instances.end(),retval.instances->begin());
281281
return retval;
282282
}

include/nbl/asset/material_compiler3/CFrontendIR.h

Lines changed: 221 additions & 44 deletions
Large diffs are not rendered by default.

include/nbl/ext/MitsubaLoader/SContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct SContext final
8787
#endif
8888
core::smart_refctd_ptr<frontend_ir_t> frontIR;
8989
// common frontend nodes
90+
frontend_ir_t::typed_pointer_type<const frontend_ir_t::CSpectralVariable> unityFactor;
9091
frontend_ir_t::typed_pointer_type<const frontend_ir_t::IExprNode> errorBRDF;
9192
frontend_ir_t::typed_pointer_type<const frontend_ir_t::CLayer> errorMaterial, unsupportedPhong, unsupportedWard;
9293
frontend_ir_t::typed_pointer_type<const frontend_ir_t::CDeltaTransmission> deltaTransmission;
@@ -95,6 +96,7 @@ struct SContext final
9596
{
9697
Albedo,
9798
Opacity,
99+
Weight,
98100
MitsubaExtraFactor,
99101
Count
100102
};

src/nbl/asset/interchange/CImageLoaderJPG.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,11 @@ bool CImageLoaderJPG::isALoadableFileFormat(system::IFile* _file, const system::
157157
if (!_file)
158158
return false;
159159

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

src/nbl/asset/material_compiler3/CFrontendIR.cpp

Lines changed: 124 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2022-2025 - DevSH Graphics Programming Sp. z O.O.
1+
// Copyright (C) 2022-2025 - DevSH Graphics Programming Sp. z O.O.
22
// This file is part of the "Nabla Engine".
33
// For conditions of distribution and use, see copyright notice in nabla.h
44
#include "nbl/asset/material_compiler3/CFrontendIR.h"
@@ -32,6 +32,11 @@ bool CFrontendIR::CBeer::invalid(const SInvalidCheckArgs& args) const
3232
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());
3333
return true;
3434
}
35+
if (const auto* const thick=args.pool->getObjectPool().deref(thickness); !thick || thick->getKnotCount()!=1)
36+
{
37+
args.logger.log("Monochromatic Thickness node must be attached, but is %u of type %s",ELL_ERROR,thickness,args.pool->getTypeName(thickness).data());
38+
return true;
39+
}
3540
return false;
3641
}
3742

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

113118

114-
auto CFrontendIR::reciprocate(const typed_pointer_type<const IExprNode> other) -> typed_pointer_type<IExprNode>
119+
auto CFrontendIR::reciprocate(const typed_pointer_type<const IExprNode> orig) -> typed_pointer_type<const IExprNode>
115120
{
116-
if (const auto* in=getObjectPool().deref(block_allocator_type::_static_cast<const CFresnel>(other)); in)
121+
auto& pool = getObjectPool();
122+
struct SEntry
123+
{
124+
typed_pointer_type<const IExprNode> handle;
125+
bool visited = false;
126+
};
127+
core::vector<SEntry> stack;
128+
stack.reserve(32);
129+
stack.push_back({.handle=orig});
130+
// use a hashmap because of holes in child arrays
131+
core::unordered_map<typed_pointer_type<const IExprNode>,typed_pointer_type<IExprNode>> substitutions;
132+
while (!stack.empty())
117133
{
118-
auto fresnelH = getObjectPool().emplace<CFresnel>();
119-
auto* fresnel = getObjectPool().deref(fresnelH);
120-
*fresnel = *in;
121-
fresnel->reciprocateEtas = ~in->reciprocateEtas;
122-
return fresnelH;
134+
auto& entry = stack.back();
135+
const auto* const node = pool.deref(entry.handle);
136+
if (!node) // this is an error
137+
return {};
138+
const auto childCount = node->getChildCount();
139+
if (entry.visited)
140+
{
141+
entry.visited = true;
142+
for (uint8_t c=0; c<childCount; c++)
143+
{
144+
const auto childH = node->getChildHandle(c);
145+
if (auto child=pool.deref(childH); !child)
146+
continue; // this is not an error
147+
stack.push_back({.handle=childH});
148+
}
149+
}
150+
else
151+
{
152+
const bool needToReciprocate = node->reciprocatable();
153+
bool needToCopy = needToReciprocate;
154+
// if one descendant has changed then we need to copy node
155+
if (!needToCopy)
156+
{
157+
uint8_t c = 0;
158+
for (; c<childCount; c++)
159+
{
160+
if (auto found=substitutions.find(node->getChildHandle(c)); found!=substitutions.end())
161+
break;
162+
}
163+
needToCopy = c!=childCount;
164+
}
165+
if (needToCopy)
166+
{
167+
const auto copyH = node->copy(this);
168+
// copy copies everything including children
169+
auto* const copy = pool.deref(copyH);
170+
if (!copy)
171+
return {};
172+
if (needToReciprocate)
173+
node->reciprocate(copy);
174+
// only changed children need to be set
175+
for (uint8_t c=0; c<childCount; c++)
176+
{
177+
const auto childH = node->getChildHandle(c);
178+
if (!childH)
179+
continue;
180+
if (auto found=substitutions.find(childH); found!=substitutions.end())
181+
copy->setChild(c,found->second);
182+
}
183+
substitutions.insert({entry.handle,copyH});
184+
}
185+
stack.pop_back();
186+
}
187+
}
188+
// there was nothing to reciprocate in the expression stack
189+
if (substitutions.empty())
190+
return orig;
191+
return substitutions[orig];
192+
}
193+
194+
auto CFrontendIR::copyLayers(const typed_pointer_type<const CLayer> orig) -> typed_pointer_type<CLayer>
195+
{
196+
auto& pool = getObjectPool();
197+
auto copyH = pool.emplace<CLayer>();
198+
{
199+
auto* outLayer = pool.deref(copyH);
200+
for (const auto* layer=pool.deref(orig); true; layer=pool.deref(layer->coated))
201+
{
202+
*outLayer = *layer;
203+
if (!layer->coated)
204+
{
205+
// terminate the new stack
206+
outLayer->coated = {};
207+
break;
208+
}
209+
// continue the new stack
210+
outLayer->coated = pool.emplace<CLayer>();
211+
outLayer = pool.deref(outLayer->coated);
212+
}
213+
}
214+
return copyH;
215+
}
216+
217+
auto CFrontendIR::reverse(const typed_pointer_type<const CLayer> orig) -> typed_pointer_type<CLayer>
218+
{
219+
auto& pool = getObjectPool();
220+
// we build the new linked list from the tail
221+
auto copyH = pool.emplace<CLayer>();
222+
{
223+
auto* outLayer = pool.deref(copyH);
224+
typed_pointer_type<CLayer> underLayerH={};
225+
for (const auto* layer=pool.deref(orig); true; layer=pool.deref(layer->coated))
226+
{
227+
outLayer->coated = underLayerH;
228+
// we reciprocate everything because numerator and denominator switch (top and bottom of layer stack)
229+
outLayer->brdfBottom = reciprocate(layer->brdfTop)._const_cast();
230+
outLayer->btdf = reciprocate(layer->btdf)._const_cast();
231+
outLayer->brdfTop = reciprocate(layer->brdfBottom)._const_cast();
232+
if (!layer->coated)
233+
break;
234+
underLayerH = copyH;
235+
copyH = pool.emplace<CLayer>();
236+
outLayer = pool.deref(copyH);
237+
}
123238
}
124-
assert(false); // unimplemented
125-
return {};
239+
return copyH;
126240
}
127241

128242
auto CFrontendIR::createNamedFresnel(const std::string_view name) -> typed_pointer_type<CFresnel>

0 commit comments

Comments
 (0)