Skip to content

Created a new example to test the compilation and concepts of samplers#252

Open
karimsayedre wants to merge 20 commits intomasterfrom
sampler-concepts
Open

Created a new example to test the compilation and concepts of samplers#252
karimsayedre wants to merge 20 commits intomasterfrom
sampler-concepts

Conversation

@karimsayedre
Copy link
Copy Markdown
Contributor

No description provided.

@devshgraphicsprogramming
Copy link
Copy Markdown
Member

devshgraphicsprogramming commented Mar 23, 2026

Everything looks good, although it would be nice to try the CDF and Alias table samples at several different PoT sizes from 8 to 128*1024^2 to find the perf crossover point across sizes

Also do a 1 Reservoir sampling from size of 2 to 32 because that will likely be faster than CDF and Alias at really small sizes (same way linear search is vs binary and hashmap due to caching effects)

@devshgraphicsprogramming
Copy link
Copy Markdown
Member

Also see if you can address any of the open comments in the BxDF testing PR
#236


pdf = rcpPdf > numeric_limits<scalar_type>::min ? (1.0 / rcpPdf) : numeric_limits<scalar_type>::max;
const scalar_type fwdPdf = pst.forwardPdf(pstCache);
pdf = fwdPdf < numeric_limits<scalar_type>::max ? fwdPdf : numeric_limits<scalar_type>::max;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this does nothing

using value_type = T;
template<typename V, typename I>
void get(I i, NBL_REF_ARG(V) val) NBL_CONST_MEMBER_FUNC { val = V(data[i]); }
T operator[](uint32_t i) NBL_CONST_MEMBER_FUNC { return data[i]; }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you need operator[] for ?

Comment on lines -42 to -45

float32_t2 diff = input.u - output.inverted;
output.roundtripError = nbl::hlsl::length(diff);
output.jacobianProduct = (float32_t(1.0) / output.forwardPdf) * output.backwardPdf;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even if you're no longer 100% bijective in all cases, you can perturb input.u by epsillon and work out the Jacobian * forwardPdf and compare against 1

Comment on lines -39 to -44
sampling::Linear<float32_t>::cache_type cache;
output.generateInversed = _sampler.generateInverse(output.generated);
output.backwardPdf = _sampler.backwardPdf(output.generated);
}
output.roundtripError = abs(input.u - output.generateInversed);
output.jacobianProduct = (float32_t(1.0) / output.forwardPdf) * output.backwardPdf;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as bilinear

Comment on lines -41 to -48
{
sampling::ProjectedSphere<float32_t>::cache_type cache;
output.inverted = sampler.generateInverse(output.generated);
output.backwardPdf = sampler.backwardPdf(output.generated);
}
float32_t2 xyDiff = output.modifiedU.xy - output.inverted.xy;
output.roundtripError = nbl::hlsl::length(xyDiff);
output.jacobianProduct = (float32_t(1.0) / output.forwardPdf) * output.backwardPdf;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can still work out a Jacobian from perturbing u

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only for the hemisphere I guess

sampling::ProjectedSphericalTriangle<float32_t>::cache_type cache;
output.generated = sampler.generate(input.u, cache);
output.cachedPdf = cache.pdf;
output.forwardPdf = sampler.forwardPdf(cache);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do a JAcobian test, since its bijective if you wanted to

Comment on lines 51 to 53
output.inverted = sampler.generateInverse(output.generated);
// Backward: evaluate pdf at generated point (no cache needed)
output.backwardPdf = sampler.backwardPdf(output.generated);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

differentiated generateInverse Jacobian determinant should equal the PDF I think

while differentiated generate multiplied with PDF comes out to 1

}

output.backwardPdf = sampler.backwardPdf(output.generated);
output.separateBackwardPdf = sampler.separateBackwardPdf(output.generated);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can test a lot of things, like:

  1. separate/independent PDF multiplying together to give the scalar PDF
    2 Jacobian test follows PDF

Comment on lines +26 to +35
const float32_t toFloat = asfloat(0x2f800004u);
uint32_t2 acc = (uint32_t2)0;
uint32_t accPdf = 0;
for (uint32_t i = 0u; i < uint32_t(BENCH_ITERS); i++)
{
float32_t2 u = float32_t2(rng(), rng()) * toFloat;
sampling::SphericalRectangle<float32_t>::cache_type cache;
acc ^= asuint(sampler.generate(u, cache));
accPdf ^= asuint(sampler.forwardPdf(cache));
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need two benchmark modes, multiple samples from same create and multiple samples with create (to measure set-up overhead)

first one matters only for rejection sampling or multisampling, second one is more real use case when you only draw 1 NEE sample per path vertex so the create to generate ratio is 1:1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants