Skip to content

Commit 1b0b6f3

Browse files
quick hack around normalmaps and bumpmaps, sketch out the general idea, won't implement right now
1 parent 8aff0f7 commit 1b0b6f3

2 files changed

Lines changed: 64 additions & 37 deletions

File tree

include/nbl/asset/material_compiler3/CFrontendIR.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ class CFrontendIR final : public CNodePool
737737
// if roughness inputs are not equal (same scale, same texture) then NDF can be anisotropic in places
738738
if (getRougness()[0]!=getRougness()[1])
739739
return false;
740-
// if a reference stretch is used, stretched triangles can turn the distribution isotropic
740+
// if a reference stretch is used, stretched triangles can turn the distribution anisotropic
741741
return stretchInvariant();
742742
}
743743
// whether the derivative map and roughness is constant regardless of UV-space texture stretching

src/nbl/ext/MitsubaLoader/CMitsubaLoader.cpp

Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ parameter_t SContext::getTexture(const CElementTexture* const rootTex, hlsl::flo
466466
params.AnisotropicFilter = core::max(hlsl::findMSB<uint32_t>(bitmap.maxAnisotropy),1u);
467467
// TODO: embed the gamma in the material compiler Frontend
468468
// or adjust gamma on pixels (painful and long process)
469-
assert(std::isnan(bitmap.gamma));
469+
//assert(std::isnan(bitmap.gamma));
470470
auto& transform = *outUvTransform;
471471
transform[0][0] = bitmap.uscale;
472472
transform[0][2] = bitmap.uoffset;
@@ -617,6 +617,7 @@ auto SContext::genProfile(const CElementEmissionProfile* profile) -> frontend_ir
617617
return retval;
618618
}
619619

620+
// TODO: include source debug information / location, e.g. XML path, line and column in the nodes
620621
auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileWriter) -> frontend_material_t
621622
{
622623
auto& frontPool = frontIR->getObjectPool();
@@ -632,6 +633,12 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
632633
frontPool.deref(factorH)->debugInfo = commonDebugNames[uint16_t(debug)]._const_cast();
633634
return factorH;
634635
};
636+
637+
struct SDerivativeMap
638+
{
639+
// TODO: derivative map SParameter[2]
640+
};
641+
// TODO: take `SParameter[2]` for the derivative maps
635642
auto createCookTorrance = [&](const CElementBSDF::RoughSpecularBase* base, const frontend_ir_t::typed_pointer_type<frontend_ir_t::CFresnel> fresnelH, const CElementTexture::SpectrumOrTexture& specularReflectance)->auto
636643
{
637644
const auto mulH = frontPool.emplace<frontend_ir_t::CMul>();
@@ -660,6 +667,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
660667
// TODO: check if UV transform is the same and warn if not
661668
getParameters({roughness.data()+1,1},base->alphaV);
662669
}
670+
// TODO: derivative maps
663671
}
664672
else
665673
roughness[0].scale = roughness[1].scale = 0.f;
@@ -687,6 +695,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
687695
// TODO: check if UV transform is the same and warn if not
688696
getParameters({roughness.data()+1,1},alphaV);
689697
}
698+
// TODO: derivative maps
690699
}
691700
return frontIR->createMul(orenNayarH,factorH);
692701
};
@@ -699,7 +708,10 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
699708
const auto transH = frontPool.emplace<frontend_ir_t::CMul>();
700709
{
701710
auto* const trans = frontPool.deref(transH);
702-
trans->lhs = frontIR->createMul(deltaTransmission._const_cast(),extinctionH);
711+
if (extinctionH)
712+
trans->lhs = frontIR->createMul(deltaTransmission._const_cast(),extinctionH);
713+
else
714+
trans->lhs = deltaTransmission._const_cast();
703715
const auto factorH = createFactorNode(element.specularTransmittance,ECommonDebug::MitsubaExtraFactor);
704716
trans->rhs = frontIR->createMul(fresnelH,factorH);
705717
}
@@ -708,10 +720,23 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
708720
layer->brdfBottom = dielectricH;
709721
};
710722

711-
using bxdf_t = frontend_ir_t::typed_pointer_type<frontend_ir_t::IExprNode>;
723+
struct SEntry
724+
{
725+
inline bool operator==(const SEntry& other) const {return bsdf==other.bsdf;}
726+
727+
const CElementBSDF* bsdf;
728+
// SDerivativeMap derivMap;
729+
};
730+
struct HashEntry
731+
{
732+
inline size_t operator()(const SEntry& entry) const {return std::hash<const void*>()(entry.bsdf);}
733+
};
734+
core::unordered_map<SEntry,material_t,HashEntry> localCache;
735+
localCache.reserve(16);
712736
// the layer returned will never have a bottom BRDF
713-
auto createMistubaLeaf = [&](const CElementBSDF* _bsdf/*TODO: debug source information*/)->frontend_ir_t::typed_pointer_type<frontend_ir_t::CLayer>
737+
auto createMistubaLeaf = [&](const SEntry& entry)->frontend_ir_t::typed_pointer_type<frontend_ir_t::CLayer>
714738
{
739+
const CElementBSDF* _bsdf = entry.bsdf;
715740
auto retval = frontPool.emplace<frontend_ir_t::CLayer>();
716741
auto* leaf = frontPool.deref(retval);
717742
switch (_bsdf->type)
@@ -796,7 +821,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
796821
{
797822
// want a specularTransmittance instead of SpecularReflectance factor
798823
const auto factorH = createFactorNode(_bsdf->dielectric.specularTransmittance,ECommonDebug::MitsubaExtraFactor);
799-
bxdf_t btdfH;
824+
frontend_ir_t::typed_pointer_type<frontend_ir_t::IExprNode> btdfH;
800825
{
801826
const auto* const brdf = frontPool.deref(brdfH);
802827
// make the trans node refraction-less for thin dielectric and apply thin scattering correction to the transmissive fresnel
@@ -886,21 +911,18 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
886911
// Post-order Depth First Traversal (create children first, then create parent)
887912
struct SStackEntry
888913
{
889-
const CElementBSDF* bsdf;
890-
uint64_t visited : 1 = false;
891-
uint64_t unused : 63 = 0;
914+
SEntry immutable;
915+
bool visited = false;
892916
};
893917
core::vector<SStackEntry> stack;
894918
stack.reserve(128);
895-
stack.emplace_back() = {.bsdf=bsdf};
896-
// for the static casts of handles
897-
core::unordered_map<const CElementBSDF*,material_t> localCache;
898-
localCache.reserve(16);
919+
stack.emplace_back() = {.immutable={.bsdf=bsdf}};
899920
//
921+
frontend_ir_t::typed_pointer_type<frontend_ir_t::CLayer> rootH = {};
900922
while (!stack.empty())
901923
{
902924
auto& entry = stack.back();
903-
const auto* const _bsdf = entry.bsdf;
925+
const auto* const _bsdf = entry.immutable.bsdf;
904926
assert(_bsdf);
905927
// we only do post-dfs for non-leafs
906928
if (_bsdf->isMeta() && !entry.visited)
@@ -912,9 +934,14 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
912934
switch(_bsdf->type)
913935
{
914936
case CElementBSDF::COATING: [[fallthrough]];
915-
case CElementBSDF::ROUGHCOATING: [[fallthrough]];
937+
case CElementBSDF::ROUGHCOATING:
938+
assert(meta_common.childCount==1);
939+
break;
916940
case CElementBSDF::BUMPMAP: [[fallthrough]];
917-
case CElementBSDF::NORMALMAP: [[fallthrough]];
941+
case CElementBSDF::NORMALMAP:
942+
assert(meta_common.childCount==1);
943+
// TODO : create the derivative map and cache it
944+
break;
918945
case CElementBSDF::MASK:
919946
assert(meta_common.childCount==1);
920947
break;
@@ -930,9 +957,9 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
930957
assert(false); // we shouldn't get this case here
931958
break;
932959
}
933-
stack.emplace_back() = {.bsdf=meta_common.bsdf[0]};
934-
for (decltype(meta_common.childCount) i=1; i<meta_common.childCount; i++)
935-
stack.emplace_back() = {.bsdf=meta_common.bsdf[i]};
960+
// TODO : make sure child gets pushed with derivative map info
961+
for (decltype(meta_common.childCount) i=0; i<meta_common.childCount; i++)
962+
stack.emplace_back() = {.immutable={.bsdf=meta_common.bsdf[i]}};
936963
}
937964
entry.visited = true;
938965
}
@@ -942,6 +969,10 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
942969
if (_bsdf->isMeta())
943970
{
944971
const auto childCount = _bsdf->meta_common.childCount;
972+
auto getChildFromCache = [&](const CElementBSDF* child)->frontend_ir_t::typed_pointer_type<frontend_ir_t::CLayer>
973+
{
974+
return localCache[{.bsdf=child/*, TODO: copy the current normalmap stuff from entry or self if self is bump map*/}]._const_cast();
975+
};
945976
switch(_bsdf->type)
946977
{
947978
case CElementBSDF::COATING: [[fallthrough]];
@@ -962,7 +993,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
962993
}
963994
fillCoatingLayer(coating,_bsdf->coating,_bsdf->type==CElementBSDF::ROUGHCOATING,beerH);
964995
// attach the nested as layer
965-
coating->coated = localCache[_bsdf->mask.bsdf[0]]._const_cast();
996+
coating->coated = getChildFromCache(_bsdf->mask.bsdf[0]);
966997
newMaterialH = coatingH;
967998
break;
968999
}
@@ -971,7 +1002,7 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
9711002
const auto maskH = frontPool.emplace<frontend_ir_t::CLayer>();
9721003
auto* const mask = frontPool.deref(maskH);
9731004
//
974-
const auto nestedH = localCache[_bsdf->mask.bsdf[0]];
1005+
const auto nestedH = getChildFromCache(_bsdf->mask.bsdf[0]);
9751006
const auto* const nested = frontPool.deref(nestedH);
9761007
assert(nested && nested->brdfTop);
9771008
const auto opacityH = createFactorNode(_bsdf->mask.opacity,ECommonDebug::Opacity);
@@ -985,15 +1016,12 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
9851016
mask->brdfBottom = frontIR->createMul(nested->brdfBottom,opacityH);
9861017
newMaterialH = maskH;
9871018
break;
988-
}
989-
case CElementBSDF::BUMPMAP:
990-
{
991-
assert(false); // unimplemented
992-
break;
993-
}
1019+
}
1020+
case CElementBSDF::BUMPMAP: [[fallthrough]];
9941021
case CElementBSDF::NORMALMAP:
9951022
{
996-
assert(false); // unimplemented
1023+
// we basically ignore and skip because derivative map already applied
1024+
newMaterialH = getChildFromCache(_bsdf->mask.bsdf[0]);
9971025
break;
9981026
}
9991027
case CElementBSDF::MIXTURE_BSDF:
@@ -1008,8 +1036,8 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
10081036
}
10091037
case CElementBSDF::TWO_SIDED:
10101038
{
1011-
const auto origFrontH = localCache[_bsdf->twosided.bsdf[0]];
1012-
const auto chosenBackH = childCount!=1 ? localCache[_bsdf->twosided.bsdf[1]]:origFrontH;
1039+
const auto origFrontH = getChildFromCache(_bsdf->twosided.bsdf[0]);
1040+
const auto chosenBackH = childCount!=1 ? getChildFromCache(_bsdf->twosided.bsdf[1]):origFrontH;
10131041
// Mitsuba does a mad thing where it will pick the BSDF to use based on NdotV which would normally break the required reciprocity of a BxDF
10141042
// but then it saves the day by disallowing transmission on the combination two BxDFs it layers together. Lets do the same.
10151043
if (const bool firstIsTransmissive=frontIR->transmissive(origFrontH); firstIsTransmissive && (childCount==1 || frontIR->transmissive(chosenBackH)))
@@ -1043,20 +1071,19 @@ auto SContext::genMaterial(const CElementBSDF* bsdf, system::ISystem* debugFileW
10431071
}
10441072
}
10451073
else
1046-
newMaterialH = createMistubaLeaf(_bsdf);
1074+
newMaterialH = createMistubaLeaf(entry.immutable);
10471075
if (!newMaterialH)
10481076
newMaterialH = errorMaterial;
1049-
localCache[_bsdf] = newMaterialH;
1077+
localCache[entry.immutable] = newMaterialH;
10501078
stack.pop_back();
1079+
if (stack.empty())
1080+
rootH = newMaterialH._const_cast();
10511081
}
10521082
}
1053-
1054-
const auto found = localCache.find(bsdf);
1055-
if (found!=localCache.end())
1056-
return errorMaterial;
1057-
const auto rootH = found->second._const_cast();
10581083
if (!rootH)
10591084
return errorMaterial;
1085+
1086+
// add debug info
10601087
auto* const root = frontPool.deref(rootH);
10611088
root->debugInfo = frontPool.emplace<frontend_ir_t::CDebugInfo>(debugName);
10621089

0 commit comments

Comments
 (0)