Skip to content

Created concepts for samplers, added quotient_and_pdf variants to satisfy the concepts#1001

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

Created concepts for samplers, added quotient_and_pdf variants to satisfy the concepts#1001
karimsayedre wants to merge 3 commits intomasterfrom
sampler-concepts

Conversation

@karimsayedre
Copy link
Contributor

@karimsayedre karimsayedre commented Feb 18, 2026

Examples PR

Notes:

  • The quotient_and_pdf() methods in UniformHemisphere, UniformSphere, ProjectedHemisphere, and ProjectedSphere shadow the struct type sampling::quotient_and_pdf<Q, P> from quotient_and_pdf.hlsl. DXC can't resolve the return type because the method name takes precedence over the struct name during lookup. Fixed by fully qualifying with ::nbl::hlsl::sampling::quotient_and_pdf<U, T>.
  • Obv. there's some refactoring to be done to satisfy all the concepts, so for not Basic (Level1) samplers are concept tested

…concepts

- Move codomain_and_*Pdf and domain_and_*Pdf structs into their own warp_and_pdf.hlsl header
- Keeping quotient_and_pdf.hlsl focused on importance sampling quotients for BxDFs
- Add SampleWithPDF, SampleWithRcpPDF, and SampleWithDensity concepts to validate sample types
- Used concept composition (NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT) to build ResamplableSampler on TractableSampler and BijectiveSampler on ResamplableSampler
Comment on lines +47 to +49
static ::nbl::hlsl::sampling::quotient_and_pdf<U, T> quotient_and_pdf(const T L)
{
return ::nbl::hlsl::sampling::quotient_and_pdf<U, T>::create(hlsl::promote<U>(1.0), pdf(L));

Choose a reason for hiding this comment

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

why all of the sudden you need to put full namespace prefixes, you're already in nbl::hlsl::sampling ?

Comment on lines +51 to +85
// Returned by BijectiveSampler::invertGenerate, domain value bundled with its rcpPdf
template<typename V, typename P>
struct domain_and_rcpPdf
{
using this_t = domain_and_rcpPdf<V, P>;

static this_t create(const V _value, const P _rcpPdf)
{
this_t retval;
retval.value = _value;
retval.rcpPdf = _rcpPdf;
return retval;
}

V value;
P rcpPdf;
};

// Returned by BijectiveSampler::invertGenerate, domain value bundled with its pdf
template<typename V, typename P>
struct domain_and_pdf
{
using this_t = domain_and_pdf<V, P>;

static this_t create(const V _value, const P _pdf)
{
this_t retval;
retval.value = _value;
retval.pdf = _pdf;
return retval;
}

V value;
P pdf;
};

Choose a reason for hiding this comment

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

not sure why we need two structs, they could just be implement as one set of value_and_... then used template aliases

Comment on lines +181 to +182
// Because the mapping is bijective, the Jacobian of the inverse is
// the reciprocal of the Jacobian of the forward mapping:

Choose a reason for hiding this comment

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

updte the comment "absolute value of the determinant of the Jacobian"

the Jacobian is a NxM matrix,

Comment on lines +35 to +62
((NBL_CONCEPT_REQ_EXPR)(s.pdf))
((NBL_CONCEPT_REQ_EXPR)(s.value)));
#undef s
#include <nbl/builtin/hlsl/concepts/__end.hlsl>
// clang-format on

// ============================================================================
// SampleWithRcpPDF
//
// Checks that a sample type bundles a value with its reciprocal PDF.
//
// Required members/methods:
// value - the sampled value (member or method)
// rcpPdf - the reciprocal probability density
//
// Satisfied by: codomain_and_rcpPdf, domain_and_rcpPdf
// ============================================================================

// clang-format off
#define NBL_CONCEPT_NAME SampleWithRcpPDF
#define NBL_CONCEPT_TPLT_PRM_KINDS (typename)
#define NBL_CONCEPT_TPLT_PRM_NAMES (T)
#define NBL_CONCEPT_PARAM_0 (s, T)
NBL_CONCEPT_BEGIN(1)
#define s NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0
NBL_CONCEPT_END(
((NBL_CONCEPT_REQ_EXPR)(s.rcpPdf))
((NBL_CONCEPT_REQ_EXPR)(s.value)));

Choose a reason for hiding this comment

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

these shouldn't be members, they should be methods

#undef v
#undef _sampler
#include <nbl/builtin/hlsl/concepts/__end.hlsl>
// clang-format on

Choose a reason for hiding this comment

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

actually I need another rename cause one can resample intractable samplers

ResamplableSampler should have forwardWeight() and backwardWeight() - in comments for write that they're for MIS and RIS

and what is currently ResampleableSampler should be called InvertibleSampler (a reverse mapping could be made via bisection search, but wouldn't necessarily be bijective - input and output pairs wouldn't match)

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