Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f71610b
Created concepts for samplers, added quotient_and_pdf variants to sat…
karimsayedre Feb 18, 2026
0e0b0ad
revert bad formatting for hlsl sampling headers
karimsayedre Feb 25, 2026
3574d83
Separate warp sample types from quotient_and_pdf, add sample density …
karimsayedre Feb 25, 2026
168ca4d
merge master, fix conflicts
keptsecret Mar 2, 2026
f1493ed
changes to linear, bilinear, box muller for pdf and backward pdf
keptsecret Jan 20, 2026
5933fe0
changes to solid angle method name, simplified a lot of code in spher…
keptsecret Jan 21, 2026
3ac7b83
removed redundant/unused variables from spherical triangle sample
keptsecret Jan 22, 2026
4ed1cbc
spherical rectangle stores origin, extent, basis and takes observer i…
keptsecret Jan 22, 2026
65ef4b3
added compressed spherical rectangle, comments for info of implementa…
keptsecret Jan 22, 2026
7fc8281
minor fixes to spherical rectangle stuff
keptsecret Feb 25, 2026
855dac4
spherical rectangle constructor for same rectangle and observer
keptsecret Mar 2, 2026
468031f
spherical rectangle create only from compressed, minor fix for spheri…
keptsecret Mar 2, 2026
0f143a0
reduced duplicate methods to only ones matching (close to) concept in…
keptsecret Mar 2, 2026
fb0e8a5
spherical rect generate don't divide by extents, let user do that
keptsecret Mar 2, 2026
ab5ee78
store only needed members from tri
keptsecret Mar 3, 2026
17c85ba
forward/backward pdfs for spherical triangle/rectangle, projected sph…
keptsecret Mar 3, 2026
d95cfa7
copied over fixed linear sampling because merge fucked up, added forw…
keptsecret Mar 3, 2026
0bb7b39
add forward pdf, generate inverse to bilinear
keptsecret Mar 4, 2026
89f6d5f
uniform hemi/sphere samplign make static methods private, added metho…
keptsecret Mar 4, 2026
e07ebc1
cosine hemi/sphere sampling make static methods private, added method…
keptsecret Mar 4, 2026
c4e63b3
box muller transform add forward pdf, generate wasn't merged from pt …
keptsecret Mar 4, 2026
c064b29
`approx_compare` uses abs then relative comparison, better sampler co…
karimsayedre Mar 5, 2026
d254d7a
Merge branch 'master' into sampler-concepts
karimsayedre Mar 5, 2026
5bc073f
Merge branch 'master' into sampler-concepts
karimsayedre Mar 6, 2026
d2114f8
fixes after merge
karimsayedre Mar 7, 2026
4f390b4
Merge remote-tracking branch 'origin/sampling_refactor_for_pt' into s…
karimsayedre Mar 7, 2026
743575f
update `examples_tests`
karimsayedre Mar 7, 2026
4d266ec
All samplers now conform to concepts
karimsayedre Mar 13, 2026
86fa3f6
Added alias table and cumulative prbability builders and samplers
karimsayedre Mar 17, 2026
6c79011
Merge branch 'master' into sampler-concepts
karimsayedre Mar 17, 2026
254404b
update examples_tests
karimsayedre Mar 17, 2026
2fa32a7
Merge branch 'master' into sampler-concepts
karimsayedre Mar 17, 2026
c61a63c
Merge branch 'master' into sampler-concepts
karimsayedre Mar 17, 2026
b720bc0
Merge branch 'master' into sampler-concepts
karimsayedre Mar 18, 2026
1fb987a
addressing comments in concepts.hlsl
karimsayedre Mar 18, 2026
fc7e174
address comments in concepts.hlsl
karimsayedre Mar 19, 2026
38f73af
Merge branch 'master' into sampler-concepts
devshgraphicsprogramming Mar 20, 2026
04d5a30
Merge branch 'master' into sampler-concepts
karimsayedre Mar 23, 2026
edc3c3e
addressed more comments
karimsayedre Mar 23, 2026
b52f3c4
addressed more comments
karimsayedre Mar 26, 2026
9b4ee22
update examples_tests
karimsayedre Mar 26, 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
2 changes: 1 addition & 1 deletion examples_tests
Submodule examples_tests updated 59 files
+1 −1 31_HLSLPathTracer/app_resources/hlsl/material_system.hlsl
+14 −12 31_HLSLPathTracer/app_resources/hlsl/next_event_estimator.hlsl
+71 −0 37_HLSLSamplingTests/CAliasTableGPUTester.h
+59 −0 37_HLSLSamplingTests/CBilinearTester.h
+67 −0 37_HLSLSamplingTests/CBoxMullerTransformTester.h
+59 −0 37_HLSLSamplingTests/CConcentricMappingTester.h
+71 −0 37_HLSLSamplingTests/CCumulativeProbabilityGPUTester.h
+327 −0 37_HLSLSamplingTests/CDiscreteSamplerBenchmark.h
+262 −0 37_HLSLSamplingTests/CDiscreteTableTester.h
+58 −0 37_HLSLSamplingTests/CLinearTester.h
+240 −0 37_HLSLSamplingTests/CMakeLists.txt
+59 −0 37_HLSLSamplingTests/CPolarMappingTester.h
+61 −0 37_HLSLSamplingTests/CProjectedHemisphereTester.h
+59 −0 37_HLSLSamplingTests/CProjectedSphereTester.h
+100 −0 37_HLSLSamplingTests/CProjectedSphericalTriangleTester.h
+265 −0 37_HLSLSamplingTests/CSamplerBenchmark.h
+65 −0 37_HLSLSamplingTests/CSphericalRectangleTester.h
+122 −0 37_HLSLSamplingTests/CSphericalTriangleTester.h
+60 −0 37_HLSLSamplingTests/CUniformHemisphereTester.h
+60 −0 37_HLSLSamplingTests/CUniformSphereTester.h
+73 −0 37_HLSLSamplingTests/app_resources/alias_table_test.comp.hlsl
+38 −0 37_HLSLSamplingTests/app_resources/bilinear_test.comp.hlsl
+39 −0 37_HLSLSamplingTests/app_resources/box_muller_transform_test.comp.hlsl
+69 −0 37_HLSLSamplingTests/app_resources/common/alias_table.hlsl
+19 −0 37_HLSLSamplingTests/app_resources/common/array_accessor.hlsl
+39 −0 37_HLSLSamplingTests/app_resources/common/bilinear.hlsl
+42 −0 37_HLSLSamplingTests/app_resources/common/box_muller_transform.hlsl
+43 −0 37_HLSLSamplingTests/app_resources/common/concentric_mapping.hlsl
+52 −0 37_HLSLSamplingTests/app_resources/common/cumulative_probability.hlsl
+26 −0 37_HLSLSamplingTests/app_resources/common/discrete_sampler_bench.hlsl
+40 −0 37_HLSLSamplingTests/app_resources/common/linear.hlsl
+43 −0 37_HLSLSamplingTests/app_resources/common/polar_mapping.hlsl
+47 −0 37_HLSLSamplingTests/app_resources/common/projected_hemisphere.hlsl
+40 −0 37_HLSLSamplingTests/app_resources/common/projected_sphere.hlsl
+50 −0 37_HLSLSamplingTests/app_resources/common/projected_spherical_triangle.hlsl
+47 −0 37_HLSLSamplingTests/app_resources/common/spherical_rectangle.hlsl
+82 −0 37_HLSLSamplingTests/app_resources/common/spherical_triangle.hlsl
+46 −0 37_HLSLSamplingTests/app_resources/common/uniform_hemisphere.hlsl
+47 −0 37_HLSLSamplingTests/app_resources/common/uniform_sphere.hlsl
+35 −0 37_HLSLSamplingTests/app_resources/concentric_mapping_test.comp.hlsl
+58 −0 37_HLSLSamplingTests/app_resources/cumulative_probability_test.comp.hlsl
+38 −0 37_HLSLSamplingTests/app_resources/linear_test.comp.hlsl
+35 −0 37_HLSLSamplingTests/app_resources/polar_mapping_test.comp.hlsl
+36 −0 37_HLSLSamplingTests/app_resources/projected_hemisphere_test.comp.hlsl
+36 −0 37_HLSLSamplingTests/app_resources/projected_sphere_test.comp.hlsl
+40 −0 37_HLSLSamplingTests/app_resources/projected_spherical_triangle_test.comp.hlsl
+44 −0 37_HLSLSamplingTests/app_resources/spherical_rectangle_test.comp.hlsl
+42 −0 37_HLSLSamplingTests/app_resources/spherical_triangle.comp.hlsl
+159 −0 37_HLSLSamplingTests/app_resources/test_compile.comp.hlsl
+34 −0 37_HLSLSamplingTests/app_resources/uniform_hemisphere_test.comp.hlsl
+34 −0 37_HLSLSamplingTests/app_resources/uniform_sphere_test.comp.hlsl
+407 −0 37_HLSLSamplingTests/main.cpp
+3 −3 59_QuaternionTests/CQuaternionTester.h
+6 −6 66_HLSLBxDFTests/app_resources/test_compile.comp.hlsl
+7 −7 66_HLSLBxDFTests/app_resources/tests.hlsl
+3 −3 66_HLSLBxDFTests/main.cpp
+3 −3 66_HLSLBxDFTests/tests.h
+1 −0 CMakeLists.txt
+383 −384 common/include/nbl/examples/Tester/ITester.h
49 changes: 23 additions & 26 deletions include/nbl/builtin/hlsl/algorithm.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ NBL_CONSTEXPR_FUNC void swap(NBL_REF_ARG(T) lhs, NBL_REF_ARG(T) rhs)
namespace impl
{

template<class Accessor, class Comparator>
template<class Accessor, class Comparator, bool IsUpper = false>
struct bound_t
{
static bound_t<Accessor,Comparator> setup(uint32_t begin, const uint32_t end, const typename Accessor::value_type _value, const Comparator _comp)
static bound_t<Accessor,Comparator,IsUpper> setup(uint32_t begin, const uint32_t end, const typename Accessor::value_type _value, const Comparator _comp)
{
bound_t<Accessor,Comparator> retval;
bound_t<Accessor,Comparator,IsUpper> retval;
retval.comp = _comp;
retval.value = _value;
retval.it = begin;
Expand All @@ -110,7 +110,7 @@ struct bound_t
{
if (isNPoT(len))
{
const uint32_t newLen = 0x1u<<nbl::hlsl::findMSB(len);
const uint32_t newLen = 0x1u<<uint32_t(nbl::hlsl::findMSB(len));
const uint32_t testPoint = it+(len-newLen);
len = newLen;
comp_step(accessor,testPoint);
Expand All @@ -132,9 +132,17 @@ struct bound_t
comp_step(accessor,mid);
}

bool compare(const typename Accessor::value_type lhs, const typename Accessor::value_type rhs)
{
if (IsUpper)
return !comp(rhs,lhs);
else
return comp(lhs,rhs);
}

void comp_step(NBL_REF_ARG(Accessor) accessor, const uint32_t testPoint, const uint32_t rightBegin)
{
if (comp(accessor[testPoint],value))
if (compare(accessor[testPoint],value))
it = rightBegin;
}
void comp_step(NBL_REF_ARG(Accessor) accessor, const uint32_t testPoint)
Expand All @@ -148,36 +156,25 @@ struct bound_t
uint32_t len;
};

template<class Accessor, class Comparator>
struct lower_to_upper_comparator_transform_t
{
bool operator()(const typename Accessor::value_type lhs, const typename Accessor::value_type rhs)
{
return !comp(rhs,lhs);
}

Comparator comp;
};

}


template<class Accessor, class Comparator>
uint32_t lower_bound(NBL_REF_ARG(Accessor) accessor, const uint32_t begin, const uint32_t end, const typename Accessor::value_type value, const Comparator comp)
uint32_t lower_bound(NBL_REF_ARG(Accessor) accessor, const uint32_t begin, const uint32_t end, const typename Accessor::value_type value, NBL_REF_ARG(Comparator) comp)
{
impl::bound_t<Accessor,Comparator> implementation = impl::bound_t<Accessor,Comparator>::setup(begin,end,value,comp);
return implementation(accessor);
impl::bound_t<Accessor,Comparator,false> implementation = impl::bound_t<Accessor,Comparator,false>::setup(begin,end,value,comp);
const uint32_t retval = implementation(accessor);
comp = implementation.comp;
return retval;
}

template<class Accessor, class Comparator>
uint32_t upper_bound(NBL_REF_ARG(Accessor) accessor, const uint32_t begin, const uint32_t end, const typename Accessor::value_type value, const Comparator comp)
uint32_t upper_bound(NBL_REF_ARG(Accessor) accessor, const uint32_t begin, const uint32_t end, const typename Accessor::value_type value, NBL_REF_ARG(Comparator) comp)
{
//using TransformedComparator = impl::lower_to_upper_comparator_transform_t<Accessor,Comparator>;
//TransformedComparator transformedComparator;

impl::lower_to_upper_comparator_transform_t<Accessor,Comparator> transformedComparator;
transformedComparator.comp = comp;
return lower_bound<Accessor,impl::lower_to_upper_comparator_transform_t<Accessor,Comparator> >(accessor,begin,end,value,transformedComparator);
impl::bound_t<Accessor,Comparator,true> implementation = impl::bound_t<Accessor,Comparator,true>::setup(begin,end,value,comp);
const uint32_t retval = implementation(accessor);
comp = implementation.comp;
return retval;
}


Expand Down
20 changes: 12 additions & 8 deletions include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,18 @@ struct SLambertianBase
template<typename C=bool_constant<!IsBSDF> >
enable_if_t<C::value && !IsBSDF, sample_type> generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC
{
typename sampling::ProjectedHemisphere<scalar_type>::cache_type cache;
ray_dir_info_type L;
L.setDirection(sampling::ProjectedHemisphere<scalar_type>::generate(u));
L.setDirection(sampling::ProjectedHemisphere<scalar_type>::generate(u, cache));
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
}
template<typename C=bool_constant<IsBSDF> >
enable_if_t<C::value && IsBSDF, sample_type> generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC
{
typename sampling::ProjectedSphere<scalar_type>::cache_type cache;
vector3_type _u = u;
ray_dir_info_type L;
L.setDirection(sampling::ProjectedSphere<scalar_type>::generate(_u));
L.setDirection(sampling::ProjectedSphere<scalar_type>::generate(_u, cache));
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
}
template<typename C=bool_constant<!IsBSDF> >
Expand All @@ -63,9 +65,9 @@ struct SLambertianBase
scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC
{
NBL_IF_CONSTEXPR (IsBSDF)
return sampling::ProjectedSphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
return sampling::ProjectedSphere<scalar_type>::backwardPdf(vector<scalar_type, 3>(0, 0, _sample.getNdotL(_clamp)));
else
return sampling::ProjectedHemisphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
return sampling::ProjectedHemisphere<scalar_type>::backwardPdf(vector<scalar_type, 3>(0, 0, _sample.getNdotL(_clamp)));
}
scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC
{
Expand All @@ -74,12 +76,14 @@ struct SLambertianBase

quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC
{
sampling::quotient_and_pdf<monochrome_type, scalar_type> qp;
typename sampling::ProjectedHemisphere<scalar_type>::cache_type cache;
cache.L_z = _sample.getNdotL(_clamp);
scalar_type p;
NBL_IF_CONSTEXPR (IsBSDF)
qp = sampling::ProjectedSphere<scalar_type>::template quotient_and_pdf(_sample.getNdotL(_clamp));
p = sampling::ProjectedSphere<scalar_type>::forwardPdf(cache);
else
qp = sampling::ProjectedHemisphere<scalar_type>::template quotient_and_pdf(_sample.getNdotL(_clamp));
return quotient_pdf_type::create(qp.quotient[0], qp.pdf);
p = sampling::ProjectedHemisphere<scalar_type>::forwardPdf(cache);
return quotient_pdf_type::create(scalar_type(1.0), p);
}
quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC
{
Expand Down
10 changes: 6 additions & 4 deletions include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,18 @@ struct SOrenNayarBase
template<typename C=bool_constant<!IsBSDF> >
enable_if_t<C::value && !IsBSDF, sample_type> generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC
{
typename sampling::ProjectedHemisphere<scalar_type>::cache_type cache;
ray_dir_info_type L;
L.setDirection(sampling::ProjectedHemisphere<scalar_type>::generate(u));
L.setDirection(sampling::ProjectedHemisphere<scalar_type>::generate(u, cache));
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
}
template<typename C=bool_constant<IsBSDF> >
enable_if_t<C::value && IsBSDF, sample_type> generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC
{
typename sampling::ProjectedSphere<scalar_type>::cache_type cache;
vector3_type _u = u;
ray_dir_info_type L;
L.setDirection(sampling::ProjectedSphere<scalar_type>::generate(_u));
L.setDirection(sampling::ProjectedSphere<scalar_type>::generate(_u, cache));
return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace());
}
template<typename C=bool_constant<!IsBSDF> >
Expand All @@ -98,9 +100,9 @@ struct SOrenNayarBase
scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC
{
if (IsBSDF)
return sampling::ProjectedSphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
return sampling::ProjectedSphere<scalar_type>::backwardPdf(vector<scalar_type, 3>(0, 0, _sample.getNdotL(_clamp)));
else
return sampling::ProjectedHemisphere<scalar_type>::pdf(_sample.getNdotL(_clamp));
return sampling::ProjectedHemisphere<scalar_type>::backwardPdf(vector<scalar_type, 3>(0, 0, _sample.getNdotL(_clamp)));
}
scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC
{
Expand Down
35 changes: 35 additions & 0 deletions include/nbl/builtin/hlsl/ieee754.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,41 @@ NBL_CONSTEXPR_FUNC bool isZero(T val)
return !(ieee754::impl::bitCastToUintType(val) & exponentAndMantissaMask);
}

// Returns the largest representable value less than `val`.
// For positive values this decrements the bit representation; for negative values it increments.
// Caller must guarantee val is finite and non-zero.
template <bool CanBeNeg = true, typename T NBL_FUNC_REQUIRES(hlsl::is_floating_point_v<T>)
NBL_CONSTEXPR_FUNC T nextDown(T val)
{
using AsUint = typename unsigned_integer_of_size<sizeof(T)>::type;
using traits_t = traits<T>;

const AsUint bits = ieee754::impl::bitCastToUintType(val);

// positive: decrement; negative: increment
AsUint result;
if (CanBeNeg)
{
const bool isNegative = (bits & traits_t::signMask) != AsUint(0);
result = isNegative ? (bits + AsUint(1)) : (bits - AsUint(1));
}
else
result = bits - AsUint(1);
return impl::castBackToFloatType<T>(result);
}

// Returns the representable value nearest to `val` in the direction of zero.
// For positive values this decrements the bit representation; for negative values it decrements (moving toward zero).
// Caller must guarantee val is finite and non-zero.
template <typename T NBL_FUNC_REQUIRES(hlsl::is_floating_point_v<T>)
NBL_CONSTEXPR_FUNC T nextTowardZero(T val)
{
using AsUint = typename unsigned_integer_of_size<sizeof(T)>::type;

const AsUint bits = ieee754::impl::bitCastToUintType(val);
return impl::castBackToFloatType<T>(bits - AsUint(1));
}

}
}
}
Expand Down
4 changes: 2 additions & 2 deletions include/nbl/builtin/hlsl/math/functions.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ struct conditionalAbsOrMax_helper<T NBL_PARTIAL_REQ_BOT(concepts::FloatingPointL
using UintOfTSize = unsigned_integer_of_size_t<sizeof(T)>;
const T condAbs = bit_cast<T>(bit_cast<UintOfTSize>(x) & (cond ? (numeric_limits<UintOfTSize>::max >> 1) : numeric_limits<UintOfTSize>::max));

return max<T>(condAbs, limit);
return nbl::hlsl::max<T>(condAbs, limit);
}
};

Expand All @@ -156,7 +156,7 @@ struct conditionalAbsOrMax_helper<T NBL_PARTIAL_REQ_BOT(concepts::FloatingPointL
const Uint32VectorWithDimensionOfT condAbsAsUint = xAsUintVec & mask;
T condAbs = bit_cast<T, Uint32VectorWithDimensionOfT>(condAbsAsUint);

return max<T>(condAbs, limit);
return nbl::hlsl::max<T>(condAbs, limit);
}
};
}
Expand Down
5 changes: 3 additions & 2 deletions include/nbl/builtin/hlsl/path_tracing/gaussian_filter.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct GaussianFilter
{
this_t retval;
retval.truncation = hlsl::exp(-0.5 * gaussianFilterCutoff * gaussianFilterCutoff);
retval.boxMuller.stddev = stddev;
retval.boxMuller = sampling::BoxMullerTransform<scalar_type>::create(stddev);
return retval;
}

Expand All @@ -31,7 +31,8 @@ struct GaussianFilter
vector2_type remappedRand = randVec;
remappedRand.x *= 1.0 - truncation;
remappedRand.x += truncation;
return boxMuller(remappedRand);
typename nbl::hlsl::sampling::BoxMullerTransform<scalar_type>::cache_type cache;
return boxMuller.generate(remappedRand, cache);
}

scalar_type truncation;
Expand Down
18 changes: 9 additions & 9 deletions include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ struct Unidirectional
// So we need to weigh the Delta lobes as if the MIS weight is always 1, but other areas regularly.
// Meaning that eval's pdf should equal quotient's pdf , this way even the diffuse contributions coming from within a specular lobe get a MIS weight near 0 for NEE.
// This stops a discrepancy in MIS weights and NEE mistakenly trying to add non-delta lobe contributions with a MIS weight > 0 and creating energy from thin air.
if (neeContrib.pdf > scalar_type(0.0))
if (neeContrib.pdf() > scalar_type(0.0))
{
// TODO: we'll need an `eval_and_mis_weight` and `quotient_and_mis_weight`
const scalar_type bsdf_pdf = materialSystem.pdf(matID, nee_sample, interaction);
neeContrib.quotient *= materialSystem.eval(matID, nee_sample, interaction) * rcpChoiceProb;
if (neeContrib.pdf < bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity))
neeContrib._quotient *= materialSystem.eval(matID, nee_sample, interaction) * rcpChoiceProb;
if (neeContrib.pdf() < bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity))
{
const scalar_type otherGenOverLightAndChoice = bsdf_pdf * rcpChoiceProb / neeContrib.pdf;
neeContrib.quotient /= 1.f + otherGenOverLightAndChoice * otherGenOverLightAndChoice; // balance heuristic
const scalar_type otherGenOverLightAndChoice = bsdf_pdf * rcpChoiceProb / neeContrib.pdf();
neeContrib._quotient /= 1.f + otherGenOverLightAndChoice * otherGenOverLightAndChoice; // balance heuristic
}

const vector3_type origin = intersectP;
Expand All @@ -124,8 +124,8 @@ struct Unidirectional
nee_ray.template setInteraction<anisotropic_interaction_type>(interaction);
nee_ray.setT(t);
tolerance_method_type::template adjust<ray_type>(nee_ray, intersectData.getGeometricNormal(), depth);
if (getLuma(neeContrib.quotient) > lumaContributionThreshold)
ray.addPayloadContribution(neeContrib.quotient * intersector_type::traceShadowRay(scene, nee_ray, ret.getLightObjectID()));
if (getLuma(neeContrib.quotient()) > lumaContributionThreshold)
ray.addPayloadContribution(neeContrib.quotient() * intersector_type::traceShadowRay(scene, nee_ray, ret.getLightObjectID()));
}
}

Expand All @@ -142,8 +142,8 @@ struct Unidirectional

// the value of the bsdf divided by the probability of the sample being generated
quotient_pdf_type bsdf_quotient_pdf = materialSystem.quotient_and_pdf(matID, bsdf_sample, interaction, _cache);
throughput *= bsdf_quotient_pdf.quotient;
bxdfPdf = bsdf_quotient_pdf.pdf;
throughput *= bsdf_quotient_pdf.quotient();
bxdfPdf = bsdf_quotient_pdf.pdf();
bxdfSample = bsdf_sample.getL().getDirection();
}

Expand Down
Loading
Loading