Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7dc5d93
added closest hit shader to draw albedo (as white), ndc to ray still …
keptsecret Mar 10, 2026
225a529
ray trace albedo and normal, look angle still kinda weird
keptsecret Mar 10, 2026
2e63a67
added unit test for pseudoInverse3x4
keptsecret Mar 11, 2026
046236f
fix some matrix calculations, storing normals vis
keptsecret Mar 11, 2026
9079b2f
disable orthogonality check for now, wait for sampling refactor pr me…
keptsecret Mar 12, 2026
41ebd0a
removed one too many lines, needed for next check
keptsecret Mar 12, 2026
147b5d1
Merge branch 'master' into rt_pipeline_debug_render
keptsecret Mar 13, 2026
b71ee98
Merge branch 'master' into rt_pipeline_debug_render
keptsecret Mar 17, 2026
9e5e1b4
update example 13
devshgraphicsprogramming Mar 18, 2026
480060c
add sobol sequence buffer, fill scramble key with noise and use in de…
keptsecret Mar 18, 2026
51aceb4
write the correct scramble key image
keptsecret Mar 18, 2026
2d45d4a
moved sequence buffer and scramble key into CRenderer
keptsecret Mar 18, 2026
d16ccb5
more error handling, TODO investigated
devshgraphicsprogramming Mar 18, 2026
8f045a1
Merge pull request #260 from Devsh-Graphics-Programming/mitsuba_xml_2…
devshgraphicsprogramming Mar 18, 2026
a306806
Merge branch 'master' into rt_pipeline_debug_render
keptsecret Mar 19, 2026
19be252
sample multiple samples with minSPP
keptsecret Mar 19, 2026
080e1d5
add temporal accumulation for debug render
keptsecret Mar 19, 2026
e106cd0
Merge branch 'master' into ris_bxdfs
keptsecret Mar 20, 2026
02fac2d
make Area the default template specialization for NEE samplers for ea…
devshgraphicsprogramming Mar 21, 2026
dcac12e
refactor changes in method names in concepts
keptsecret Mar 23, 2026
ebb025b
Merge branch 'master' into ris_bxdfs
keptsecret Mar 24, 2026
4da04ee
fixes from changes to projected solid angle tri
keptsecret Mar 24, 2026
25e2b43
ray stores depth, nee gets depth from ray
keptsecret Mar 24, 2026
b2a0938
nee deferredPdf is deferredWeight
keptsecret Mar 24, 2026
770899c
refactor bxdfs have cache type
keptsecret Mar 24, 2026
8694bdd
fixes to bxdf unit tests
keptsecret Mar 25, 2026
4bdd81c
refactor eval returns value_and_weight type
keptsecret Mar 25, 2026
5d53317
refactor eval use value_and_weight type
keptsecret Mar 25, 2026
789a88c
refactor use quotient_weight type
keptsecret Mar 26, 2026
4db014b
Merge branch 'master' into rt_pipeline_debug_render
keptsecret Mar 26, 2026
2d50592
split out scramble sequence creation into separate class in example c…
keptsecret Mar 26, 2026
e43b0b0
removed redundant device address in lambda function
keptsecret Mar 26, 2026
84c4c36
improve error reporting in example 22 and friends
devshgraphicsprogramming Mar 26, 2026
46826a5
Use Texture2DArray for the scramble key
devshgraphicsprogramming Mar 26, 2026
ee0c4ab
merge master
keptsecret Mar 27, 2026
89eb0fa
change remaining method names with pdf to weight
keptsecret Mar 27, 2026
88a01d2
avoid division by 0
keptsecret Mar 27, 2026
5d64bab
refactor regular bxdf don't take cache for eval
keptsecret Mar 27, 2026
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
70 changes: 27 additions & 43 deletions 13_MaterialCompilerTest/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

#include "nbl/examples/examples.hpp"

//! Temporary, for faster iteration outside of PCH
#include "nbl/asset/material_compiler3/CFrontendIR.h"


using namespace nbl;
Expand Down Expand Up @@ -399,36 +397,27 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
const auto fresnelH = forest->createNamedFresnel("ThF4");
const auto* fresnel = forestPool.deref(fresnelH);

const auto brdfH = forestPool.emplace<CFrontendIR::CMul>();
const auto ctH = forestPool.emplace<CFrontendIR::CCookTorrance>();
{
auto* mul = forestPool.deref(brdfH);
const auto ctH = forestPool.emplace<CFrontendIR::CCookTorrance>();
{
auto* ct = forestPool.deref(ctH);
ct->ndParams.getRougness()[0].scale = ct->ndParams.getRougness()[1].scale = 0.1f;
// ignored for BRDFs, needed for BTDFs
ct->orientedRealEta = fresnel->orientedRealEta;
}
mul->lhs = ctH;
mul->rhs = fresnelH;
auto* ct = forestPool.deref(ctH);
ct->ndParams.getRougness()[0].scale = ct->ndParams.getRougness()[1].scale = 0.1f;
// ignored for BRDFs, needed for BTDFs
ct->orientedRealEta = fresnel->orientedRealEta;
layer->brdfTop = forest->createMul(ctH,fresnelH);
}
layer->brdfTop = brdfH;
layer->brdfBottom = brdfH;

const auto btdfH = forestPool.emplace<CFrontendIR::CMul>();
// the BTDF
{
auto* mul = forestPool.deref(btdfH);
const auto thinInfiniteScatterH = forestPool.emplace<CFrontendIR::CThinInfiniteScatterCorrection>();
{
auto* thinInfiniteScatter = forestPool.deref(thinInfiniteScatterH);
thinInfiniteScatter->reflectanceTop = fresnelH;
thinInfiniteScatter->reflectanceBottom = fresnelH;
// without extinction
}
mul->lhs = forestPool.emplace<CFrontendIR::CDeltaTransmission>();
mul->rhs = thinInfiniteScatterH;
layer->btdf = forest->createMul(forestPool.emplace<CFrontendIR::CDeltaTransmission>(),thinInfiniteScatterH);
}
layer->btdf = btdfH;
// the interface on top as Air->ThF4, we need interface on bottom to be ThF4->Air so reciprocate te Eta
layer->brdfBottom = forest->createMul(forest->reciprocate(ctH)._const_cast(),fresnelH);

{
auto* imagEta = forestPool.deref(fresnel->orientedImagEta);
Expand All @@ -443,7 +432,7 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
ASSERT_VALUE(forest->addMaterial(layerH,logger),true,"ThinDielectric");
}

// compled materials with coatings with IOR 1.5
// complex materials with coatings with IOR 1.5
{
// make the nodes everyone shares
const auto roughDiffuseH = forestPool.emplace<CFrontendIR::CMul>();
Expand Down Expand Up @@ -474,20 +463,16 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
fresnel->orientedRealEta = forestPool.emplace<CFrontendIR::CSpectralVariable>(std::move(params));
}
// the delta layering should optimize out nicely due to the sampling property
const auto transH = forestPool.emplace<CFrontendIR::CMul>();
{
auto* mul = forestPool.deref(transH);
mul->lhs = forestPool.emplace<CFrontendIR::CDeltaTransmission>();
mul->rhs = fresnelH;
}
const auto transH = forest->createMul(forestPool.emplace<CFrontendIR::CDeltaTransmission>(),fresnelH);
// can't attach a copy of the top layer because we'll have a cycle, also the BRDF needs to be on the other side
const auto bottomH = forestPool.emplace<CFrontendIR::CLayer>();
{
auto* bottomLayer = forestPool.deref(bottomH);
bottomLayer->debugInfo = forestPool.emplace<CNodePool::CDebugInfo>("Rough Coating Copy");
// no brdf on the top of last layer, kill multiscattering
bottomLayer->btdf = transH;
bottomLayer->brdfBottom = dielectricH;
// need the interface to be Air on the bottom, not Glass
bottomLayer->brdfBottom = forest->reciprocate(dielectricH)._const_cast();
}

// twosided rough plastic
Expand All @@ -501,19 +486,19 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
// no brdf on the bottom of first layer, kill multiscattering

const auto diffuseH = forestPool.emplace<CFrontendIR::CLayer>();
auto* midLayer = forestPool.deref(diffuseH);
topLayer->coated = diffuseH;
{
auto* midLayer = forestPool.deref(diffuseH);
midLayer->brdfTop = roughDiffuseH;
// no transmission in the mid-layer, the backend needs to decompose into separate front/back materials
// no transmission in the mid-layer, so the backend needs to decompose into separate front/back materials
midLayer->brdfBottom = roughDiffuseH;
midLayer->coated = bottomH;
}
topLayer->coated = diffuseH;

ASSERT_VALUE(forest->addMaterial(rootH,logger),true,"Twosided Rough Plastic");
}

// Diffuse transmitter normalized to whoel sphere
// Diffuse transmitter normalized to whole sphere
const auto roughDiffTransH = forestPool.emplace<CFrontendIR::CMul>();
{
// normalize the Oren Nayar over the full sphere
Expand Down Expand Up @@ -543,7 +528,7 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
midLayer->btdf = roughDiffTransH;
midLayer->brdfBottom = roughDiffTransH;

// we could even have a BSDF with a different Fresnel and Roughness on the bottom layer!
// we could even have a BSDF with a different Roughness on the bottom layer!
midLayer->coated = bottomH;
}
topLayer->coated = midH;
Expand All @@ -556,22 +541,27 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
const auto rootH = forestPool.emplace<CFrontendIR::CLayer>();
auto* topLayer = forestPool.deref(rootH);
topLayer->debugInfo = forestPool.emplace<CNodePool::CDebugInfo>("Coated Diffuse Extinction Transmitter");

// TODO: triple check this example Material
// we have a choice of where to stick the Beer Absorption:
// - on the BTDF of the outside layer, means that it will be applied to the transmission so twice according to VdotN and LdotN
// (but delta transmission makes special weight nodes behave in a special and only once because `L=-V` is forced in a single scattering)
// - inner layer BRDF or BTDF but thats intractable for most compiler backends because the `L` and `V` in the internal layers are not trivially known
// unless the previous layers are delta distributions (in which case we can equivalently hoist beer to the previous layer).
const auto beerH = forestPool.emplace<CFrontendIR::CBeer>();
auto* beer = forestPool.deref(beerH);
{
auto* beer = forestPool.deref(beerH);
spectral_var_t::SCreationParams<3> params = {};
params.getSemantics() = spectral_var_t::Semantics::Fixed3_SRGB;
params.knots.params[0].scale = 0.3f;
params.knots.params[1].scale = 0.9f;
params.knots.params[2].scale = 0.7f;
beer->perpTransmittance = forestPool.emplace<spectral_var_t>(std::move(params));
}
{
spectral_var_t::SCreationParams<1> params = {};
params.knots.params[0].scale = 1.f;
beer->thickness = forestPool.emplace<spectral_var_t>(std::move(params));
}

topLayer->brdfTop = dielectricH;
// simplest/recommended
Expand All @@ -592,13 +582,7 @@ class MaterialCompilerTest final : public application_templates::MonoDeviceAppli
midLayer->btdf = roughDiffTransH;
// making extra work for our canonicalizer
{
const auto roughAbsorbH = forestPool.emplace<CFrontendIR::CMul>();
auto* transAbsorb = forestPool.deref(roughAbsorbH);
transAbsorb->lhs = roughDiffTransH;
{
transAbsorb->rhs = beerH;
}
midLayer->brdfBottom = roughAbsorbH;
midLayer->brdfBottom = forest->createMul(roughDiffTransH,beerH);
}

// we could even have a BSDF with a different Fresnel and Roughness on the bottom layer!
Expand Down
59 changes: 42 additions & 17 deletions 22_CppCompat/CIntrinsicsTester.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ class CIntrinsicsTester final : public ITester<IntrinsicsIntputTestValues, Intri
realDistribution(getRandomEngine()), realDistribution(getRandomEngine()), realDistribution(getRandomEngine()),
realDistribution(getRandomEngine()), realDistribution(getRandomEngine()), realDistribution(getRandomEngine())
);
testInput.pseudoMat3x4 = float32_t4x4(
realDistribution(getRandomEngine()), 0, 0, realDistribution(getRandomEngine()),
0, realDistribution(getRandomEngine()), 0, realDistribution(getRandomEngine()),
0, 0, realDistribution(getRandomEngine()), realDistribution(getRandomEngine()),
0,0,0,1
);
testInput.minA = realDistribution(getRandomEngine());
testInput.minB = realDistribution(getRandomEngine());
testInput.maxA = realDistribution(getRandomEngine());
Expand Down Expand Up @@ -197,36 +203,54 @@ class CIntrinsicsTester final : public ITester<IntrinsicsIntputTestValues, Intri
auto inverseGlm = glm::inverse(reinterpret_cast<typename float32_t3x3::Base const&>(testInput.inverse));
expected.inverse = reinterpret_cast<float32_t3x3&>(inverseGlm);

auto inverse3x4Glm = hlsl::inverse(testInput.pseudoMat3x4);
expected.pseudoInverse3x4 = nbl::hlsl::mul(inverse3x4Glm, float32_t4(testInput.length, 1));

return expected;
}

bool verifyTestResults(const IntrinsicsTestValues& expectedTestValues, const IntrinsicsTestValues& testValues, const size_t testIteration, const uint32_t seed, TestType testType) override
{
volatile float lengthToleranace = 0.00001;
volatile float dotToleranace = 0.00001;
volatile float determinantToleranace = 0.000212669;
volatile float rsqrtTolerance = 1.1922e-07;
volatile float mixTolerance = 0.00001; // for now
volatile float radiansToleranace = 0.000001;
volatile float degreesToleranace = 0.000001;
volatile float smoothstepToleranace = 3.57628e-07;
volatile float normalizeToleranace = 0.0000001;
volatile float reflectToleranace = 0.0001;
volatile float refractToleranace = 0.001;
volatile float matrixMulToleranace = 0.00001;
volatile float inverseToleranace = 0.0001;
volatile float pseudoInverseToleranace = 0.0001;

bool pass = true;
pass &= verifyTestValue("bitCount", expectedTestValues.bitCount, testValues.bitCount, testIteration, seed, testType);
pass &= verifyTestValue("clamp", expectedTestValues.clamp, testValues.clamp, testIteration, seed, testType);
pass &= verifyTestValue("length", expectedTestValues.length, testValues.length, testIteration, seed, testType, 0.0001);
pass &= verifyTestValue("dot", expectedTestValues.dot, testValues.dot, testIteration, seed, testType, 0.00001);
pass &= verifyTestValue("determinant", expectedTestValues.determinant, testValues.determinant, testIteration, seed, testType);
pass &= verifyTestValue("length", expectedTestValues.length, testValues.length, testIteration, seed, testType, lengthToleranace);
pass &= verifyTestValue("dot", expectedTestValues.dot, testValues.dot, testIteration, seed, testType, dotToleranace);
pass &= verifyTestValue("determinant", expectedTestValues.determinant, testValues.determinant, testIteration, seed, testType, determinantToleranace);
pass &= verifyTestValue("findMSB", expectedTestValues.findMSB, testValues.findMSB, testIteration, seed, testType);
pass &= verifyTestValue("findLSB", expectedTestValues.findLSB, testValues.findLSB, testIteration, seed, testType);
pass &= verifyTestValue("min", expectedTestValues.min, testValues.min, testIteration, seed, testType);
pass &= verifyTestValue("max", expectedTestValues.max, testValues.max, testIteration, seed, testType);
pass &= verifyTestValue("rsqrt", expectedTestValues.rsqrt, testValues.rsqrt, testIteration, seed, testType);
pass &= verifyTestValue("rsqrt", expectedTestValues.rsqrt, testValues.rsqrt, testIteration, seed, testType, rsqrtTolerance);
pass &= verifyTestValue("frac", expectedTestValues.frac, testValues.frac, testIteration, seed, testType);
pass &= verifyTestValue("bitReverse", expectedTestValues.bitReverse, testValues.bitReverse, testIteration, seed, testType);
pass &= verifyTestValue("mix", expectedTestValues.mix, testValues.mix, testIteration, seed, testType);
pass &= verifyTestValue("mix", expectedTestValues.mix, testValues.mix, testIteration, seed, testType, mixTolerance);
pass &= verifyTestValue("sign", expectedTestValues.sign, testValues.sign, testIteration, seed, testType);
pass &= verifyTestValue("radians", expectedTestValues.radians, testValues.radians, testIteration, seed, testType, 0.00001);
pass &= verifyTestValue("degrees", expectedTestValues.degrees, testValues.degrees, testIteration, seed, testType, 0.001);
pass &= verifyTestValue("radians", expectedTestValues.radians, testValues.radians, testIteration, seed, testType, radiansToleranace);
pass &= verifyTestValue("degrees", expectedTestValues.degrees, testValues.degrees, testIteration, seed, testType, degreesToleranace);
pass &= verifyTestValue("step", expectedTestValues.step, testValues.step, testIteration, seed, testType);
pass &= verifyTestValue("smoothStep", expectedTestValues.smoothStep, testValues.smoothStep, testIteration, seed, testType);
pass &= verifyTestValue("smoothStep", expectedTestValues.smoothStep, testValues.smoothStep, testIteration, seed, testType, smoothstepToleranace);
pass &= verifyTestValue("addCarryResult", expectedTestValues.addCarry.result, testValues.addCarry.result, testIteration, seed, testType);
pass &= verifyTestValue("addCarryCarry", expectedTestValues.addCarry.carry, testValues.addCarry.carry, testIteration, seed, testType);
pass &= verifyTestValue("subBorrowResult", expectedTestValues.subBorrow.result, testValues.subBorrow.result, testIteration, seed, testType);
pass &= verifyTestValue("subBorrowBorrow", expectedTestValues.subBorrow.borrow, testValues.subBorrow.borrow, testIteration, seed, testType);

pass &= verifyTestValue("normalize", expectedTestValues.normalize, testValues.normalize, testIteration, seed, testType, 0.000001);
pass &= verifyTestValue("normalize", expectedTestValues.normalize, testValues.normalize, testIteration, seed, testType, normalizeToleranace);
pass &= verifyTestValue("cross", expectedTestValues.cross, testValues.cross, testIteration, seed, testType);
pass &= verifyTestValue("bitCountVec", expectedTestValues.bitCountVec, testValues.bitCountVec, testIteration, seed, testType);
pass &= verifyTestValue("clampVec", expectedTestValues.clampVec, testValues.clampVec, testIteration, seed, testType);
Expand All @@ -240,21 +264,22 @@ class CIntrinsicsTester final : public ITester<IntrinsicsIntputTestValues, Intri
pass &= verifyTestValue("mixVec", expectedTestValues.mixVec, testValues.mixVec, testIteration, seed, testType);

pass &= verifyTestValue("signVec", expectedTestValues.signVec, testValues.signVec, testIteration, seed, testType);
pass &= verifyTestValue("radiansVec", expectedTestValues.radiansVec, testValues.radiansVec, testIteration, seed, testType, 0.00001);
pass &= verifyTestValue("degreesVec", expectedTestValues.degreesVec, testValues.degreesVec, testIteration, seed, testType, 0.001);
pass &= verifyTestValue("radiansVec", expectedTestValues.radiansVec, testValues.radiansVec, testIteration, seed, testType, radiansToleranace);
pass &= verifyTestValue("degreesVec", expectedTestValues.degreesVec, testValues.degreesVec, testIteration, seed, testType, degreesToleranace);
pass &= verifyTestValue("stepVec", expectedTestValues.stepVec, testValues.stepVec, testIteration, seed, testType);
pass &= verifyTestValue("smoothStepVec", expectedTestValues.smoothStepVec, testValues.smoothStepVec, testIteration, seed, testType);
pass &= verifyTestValue("smoothStepVec", expectedTestValues.smoothStepVec, testValues.smoothStepVec, testIteration, seed, testType, smoothstepToleranace);
pass &= verifyTestValue("faceForward", expectedTestValues.faceForward, testValues.faceForward, testIteration, seed, testType);
pass &= verifyTestValue("reflect", expectedTestValues.reflect, testValues.reflect, testIteration, seed, testType, 0.001);
pass &= verifyTestValue("refract", expectedTestValues.refract, testValues.refract, testIteration, seed, testType, 0.01);
pass &= verifyTestValue("reflect", expectedTestValues.reflect, testValues.reflect, testIteration, seed, testType, reflectToleranace);
pass &= verifyTestValue("refract", expectedTestValues.refract, testValues.refract, testIteration, seed, testType, refractToleranace);
pass &= verifyTestValue("addCarryVecResult", expectedTestValues.addCarryVec.result, testValues.addCarryVec.result, testIteration, seed, testType);
pass &= verifyTestValue("addCarryVecCarry", expectedTestValues.addCarryVec.carry, testValues.addCarryVec.carry, testIteration, seed, testType);
pass &= verifyTestValue("subBorrowVecResult", expectedTestValues.subBorrowVec.result, testValues.subBorrowVec.result, testIteration, seed, testType);
pass &= verifyTestValue("subBorrowVecBorrow", expectedTestValues.subBorrowVec.borrow, testValues.subBorrowVec.borrow, testIteration, seed, testType);

pass &= verifyTestValue("mul", expectedTestValues.mul, testValues.mul, testIteration, seed, testType);
pass &= verifyTestValue("transpose", expectedTestValues.transpose, testValues.transpose, testIteration, seed, testType);
pass &= verifyTestValue("inverse", expectedTestValues.inverse, testValues.inverse, testIteration, seed, testType);
pass &= verifyTestValue("mul", expectedTestValues.mul, testValues.mul, testIteration, seed, testType, matrixMulToleranace);
pass &= verifyTestValue("transpose", expectedTestValues.transpose, testValues.transpose, testIteration, seed, testType, 0.0);
pass &= verifyTestValue("inverse", expectedTestValues.inverse, testValues.inverse, testIteration, seed, testType, inverseToleranace);
pass &= verifyTestValue("pseudoInverse3x4", expectedTestValues.pseudoInverse3x4, testValues.pseudoInverse3x4, testIteration, seed, testType, pseudoInverseToleranace);
return pass;
}
};
Expand Down
Loading