Skip to content

Commit 011e7f0

Browse files
I forgot that for blends all layers need to be blended!
1 parent 850536c commit 011e7f0

4 files changed

Lines changed: 63 additions & 42 deletions

File tree

include/nbl/asset/material_compiler3/CFrontendIR.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,14 @@ class CFrontendIR final : public CNodePool
856856
add->rhs = rhs;
857857
return addH;
858858
}
859+
inline typed_pointer_type<IExprNode> createFMA(const typed_pointer_type<IExprNode> a, const typed_pointer_type<IExprNode> b, const typed_pointer_type<IExprNode> c)
860+
{
861+
return createAdd(createMul(a,b),c);
862+
}
863+
inline typed_pointer_type<IExprNode> createWeightedSum(const typed_pointer_type<IExprNode> x0, const typed_pointer_type<IExprNode> w0, const typed_pointer_type<IExprNode> x1, const typed_pointer_type<IExprNode> w1)
864+
{
865+
return createAdd(createMul(x0,w0),createMul(x1,w1));
866+
}
859867
inline typed_pointer_type<CComplement> createComplement(const typed_pointer_type<IExprNode> child)
860868
{
861869
if (!child)

include/nbl/ext/MitsubaLoader/SContext.h

Lines changed: 1 addition & 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;

src/nbl/ext/MitsubaLoader/CMitsubaLoader.cpp

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ parameter_t SContext::getTexture(const CElementTexture* const rootTex, hlsl::flo
474474
transform[1][2] = bitmap.voffset;
475475
}
476476
else
477-
inner.params.logger.log("Failed to load bitmap texture for %p with id %s",LoggerError,tex,tex ? tex->id.c_str():"");
477+
inner.params.logger.log("Failed to load bitmap texture for %p with id %s from path \"%s\"",LoggerError,tex,tex ? tex->id.c_str():"",tex->bitmap.filename);
478478
}
479479
else
480480
inner.params.logger.log("Failed to unroll texture scale for %p with id %s",LoggerError,rootTex,rootTex ? rootTex->id.c_str():"");
@@ -730,6 +730,31 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
730730
// identical BRDF on the bottom, to have correct multiscatter
731731
layer->brdfBottom = dielectricH;
732732
};
733+
734+
using expr_handle_t = frontend_ir_t::typed_pointer_type<frontend_ir_t::IExprNode>;
735+
auto createWeightedSum = [&](frontend_ir_t::CLayer* out, material_t A, const expr_handle_t w0, material_t B, const expr_handle_t w1)->void
736+
{
737+
while (true)
738+
{
739+
auto* const a = frontPool.deref(A);
740+
auto* const b = frontPool.deref(B);
741+
// I don't actually need to check if the child Expressions are non-empty, the CFrontendIR utilities nicely carry through NOOPs
742+
out->brdfTop = frontIR->createWeightedSum(a ? a->brdfTop:expr_handle_t{},w0,b ? b->brdfTop:expr_handle_t{},w1);
743+
out->btdf = frontIR->createWeightedSum(a ? a->btdf :expr_handle_t{},w0,b ? b->btdf:expr_handle_t{},w1);
744+
out->brdfBottom = frontIR->createWeightedSum(a ? a->brdfBottom:expr_handle_t{},w0,b ? b->brdfBottom:expr_handle_t{},w1);
745+
if (a && a->coated || b && b->coated)
746+
{
747+
out = frontPool.deref(out->coated = frontPool.emplace<frontend_ir_t::CLayer>());
748+
A = a ? a->coated:material_t{};
749+
B = b ? b->coated:material_t{};
750+
}
751+
else
752+
{
753+
out->coated = {};
754+
break;
755+
}
756+
}
757+
};
733758

734759
struct SEntry
735760
{
@@ -832,7 +857,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
832857
{
833858
// want a specularTransmittance instead of SpecularReflectance factor
834859
const auto factorH = createFactorNode(_bsdf->dielectric.specularTransmittance,ECommonDebug::MitsubaExtraFactor);
835-
frontend_ir_t::typed_pointer_type<frontend_ir_t::IExprNode> btdfH;
860+
expr_handle_t btdfH;
836861
{
837862
const auto* const brdf = frontPool.deref(brdfH);
838863
// make the trans node refraction-less for thin dielectric and apply thin scattering correction to the transmissive fresnel
@@ -1037,23 +1062,35 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
10371062
}
10381063
case CElementBSDF::MIXTURE_BSDF:
10391064
{
1040-
assert(false); // unimplemented
1065+
const auto mixH = frontPool.emplace<frontend_ir_t::CLayer>();
1066+
auto* const mix = frontPool.deref(mixH);
1067+
const uint8_t realChildCount = hlsl::min<uint8_t>(childCount,_bsdf->mixturebsdf.weightCount);
1068+
const auto firstH = realChildCount>=1 ? getChildFromCache(_bsdf->mixturebsdf.bsdf[0]):frontend_ir_t::typed_pointer_type<frontend_ir_t::CLayer>{};
1069+
spectral_var_t::SCreationParams<1> firstParams = {};
1070+
firstParams.knots.params[0].scale = _bsdf->mixturebsdf.weights[0];
1071+
const auto firstWeightH = frontPool.emplace<frontend_ir_t::CSpectralVariable>(std::move(firstParams));
1072+
if (realChildCount<2)
1073+
createWeightedSum(mix,firstH,firstWeightH,{},{});
1074+
else
1075+
for (uint8_t c=1; c<realChildCount; c++)
1076+
{
1077+
const auto otherH = getChildFromCache(_bsdf->mixturebsdf.bsdf[c]);
1078+
spectral_var_t::SCreationParams<1> params = {};
1079+
params.knots.params[0].scale = _bsdf->mixturebsdf.weights[c];
1080+
// don't feel like spending time on this, since its never used, trust CTrueIR optimizer to remove this during canonicalization
1081+
createWeightedSum(mix,mixH,unityFactor._const_cast(),otherH,frontPool.emplace<frontend_ir_t::CSpectralVariable>(std::move(params)));
1082+
}
1083+
newMaterialH = mixH;
10411084
break;
10421085
}
10431086
case CElementBSDF::BLEND_BSDF:
10441087
{
10451088
const auto blendH = frontPool.emplace<frontend_ir_t::CLayer>();
1046-
auto* const blend = frontPool.deref(blendH);
10471089
const auto tH = createFactorNode(_bsdf->blendbsdf.weight,ECommonDebug::Weight);
10481090
const auto tComplementH = frontIR->createComplement(tH);
10491091
const auto loH = getChildFromCache(_bsdf->blendbsdf.bsdf[0]);
10501092
const auto hiH = getChildFromCache(_bsdf->blendbsdf.bsdf[1]);
1051-
const auto* const lo = frontPool.deref(loH);
1052-
const auto* const hi = frontPool.deref(hiH);
1053-
// I don't actually need to check if the child Expressions are non-empty, the CFrontendIR utilities nicely carry through NOOPs
1054-
blend->brdfTop = frontIR->createAdd(frontIR->createMul(lo->brdfTop,tComplementH),frontIR->createMul(hi->brdfTop,tH));
1055-
blend->btdf = frontIR->createAdd(frontIR->createMul(lo->btdf,tComplementH),frontIR->createMul(hi->btdf,tH));
1056-
blend->brdfBottom = frontIR->createAdd(frontIR->createMul(lo->brdfBottom,tComplementH),frontIR->createMul(hi->brdfBottom,tH));
1093+
createWeightedSum(frontPool.deref(blendH),loH,tComplementH,hiH,tH);
10571094
newMaterialH = blendH;
10581095
break;
10591096
}
@@ -1239,6 +1276,11 @@ SContext::SContext(
12391276
}
12401277
//
12411278
{
1279+
{
1280+
spectral_var_t::SCreationParams<1> params = {};
1281+
params.knots.params[0].scale = 1.f;
1282+
unityFactor = frontPool.emplace<spectral_var_t>(std::move(params));
1283+
}
12421284
deltaTransmission = frontPool.emplace<frontend_ir_t::CDeltaTransmission>();
12431285
const auto mulH = frontPool.emplace<frontend_ir_t::CMul>();
12441286
{

src/nbl/ext/MitsubaLoader/CMitsubaMaterialCompilerFrontend.cpp

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -149,31 +149,6 @@ CMitsubaMaterialCompilerFrontend::tex_ass_type CMitsubaMaterialCompilerFrontend:
149149
}
150150
#endif
151151

152-
auto CMitsubaMaterialCompilerFrontend::createIRNode(asset::material_compiler::IR* ir, const CElementBSDF* _bsdf, const system::logger_opt_ptr& logger) -> IRNode*
153-
{
154-
using namespace asset;
155-
using namespace material_compiler;
156-
157-
158-
159-
const auto type = _bsdf->type;
160-
IRNode* ir_node = nullptr;
161-
switch (type)
162-
{
163-
case CElementBSDF::TWO_SIDED:
164-
//TWO_SIDED is not translated into IR node directly
165-
break;
166-
case CElementBSDF::MASK:
167-
ir_node = ir->allocNode<IR::COpacityNode>();
168-
ir_node->children.count = 1u;
169-
getSpectrumOrTexture(_bsdf->mask.opacity,static_cast<IR::COpacityNode*>(ir_node)->opacity,EIVS_BLEND_WEIGHT);
170-
break;
171-
172-
173-
174-
175-
176-
177152

178153

179154
case CElementBSDF::BUMPMAP:
@@ -223,13 +198,8 @@ CMitsubaMaterialCompilerFrontend::tex_ass_type CMitsubaMaterialCompilerFrontend:
223198
}
224199
}
225200
break;
226-
case CElementBSDF::BLEND_BSDF:
227-
{
228-
ir_node = ir->allocNode<IR::CBSDFBlendNode>();
229-
ir_node->children.count = 2u;
230-
getSpectrumOrTexture(_bsdf->blendbsdf.weight,static_cast<IR::CBSDFBlendNode*>(ir_node)->weight,EIVS_BLEND_WEIGHT);
231-
}
232-
break;
201+
202+
233203
case CElementBSDF::MIXTURE_BSDF:
234204
{
235205
ir_node = ir->allocNode<IR::CBSDFMixNode>();

0 commit comments

Comments
 (0)