From 067d107e36ae99c3f2c281b8e078a6bbe36a4364 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 20 Mar 2026 16:55:36 +0700 Subject: [PATCH 01/35] change concepts for bxdf to *_and_weight methods, make changes for common bxdfs --- .../builtin/hlsl/bxdf/base/lambertian.hlsl | 15 ++- .../builtin/hlsl/bxdf/base/oren_nayar.hlsl | 18 +-- include/nbl/builtin/hlsl/bxdf/common.hlsl | 123 ++++++++++++++++-- .../bxdf/reflection/delta_distribution.hlsl | 14 +- .../bxdf/transmission/delta_distribution.hlsl | 14 +- .../bxdf/transmission/smooth_dielectric.hlsl | 30 ++--- 6 files changed, 161 insertions(+), 53 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 3f7b85875a..92c5e2867d 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -25,13 +25,14 @@ struct SLambertianBase NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); + const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); + return quotient_pdf_type::create(quo, pdf(_sample, interaction)); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return eval(_sample, interaction.isotropic); + return eval_and_weight(_sample, interaction.isotropic); } template > @@ -74,7 +75,7 @@ struct SLambertianBase return pdf(_sample, interaction.isotropic); } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { sampling::quotient_and_pdf qp; NBL_IF_CONSTEXPR (IsBSDF) @@ -83,9 +84,9 @@ struct SLambertianBase qp = sampling::ProjectedHemisphere::template quotientAndPdf(_sample.getNdotL(_clamp)); return quotient_pdf_type::create(qp.quotient()[0], qp.pdf()); } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_pdf(_sample, interaction.isotropic); + return quotient_and_weight(_sample, interaction.isotropic); } }; diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index ab06e8d43a..ae414cfcec 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -58,15 +58,15 @@ struct SOrenNayarBase return hlsl::promote(NdotL * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF) * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp))); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); - return __eval(query, _sample, interaction); + return quotient_pdf_type::create(__eval(query, _sample, interaction), pdf(_sample, interaction)); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return eval(_sample, interaction.isotropic); + return eval_and_weight(_sample, interaction.isotropic); } template > @@ -110,21 +110,21 @@ struct SOrenNayarBase } template - quotient_pdf_type __quotient_and_pdf(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type __quotient_and_weight(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { scalar_type _pdf = pdf(_sample, interaction); scalar_type q = __rec_pi_factored_out_wo_clamps(query.getVdotL(), _sample.getNdotL(_clamp), interaction.getNdotV(_clamp)); return quotient_pdf_type::create(q, _pdf); } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); - return __quotient_and_pdf(query, _sample, interaction); + return __quotient_and_weight(query, _sample, interaction); } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_pdf(_sample, interaction.isotropic); + return quotient_and_weight(_sample, interaction.isotropic); } scalar_type A2; diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index c114222c7c..47ba881d9e 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -918,9 +918,9 @@ NBL_CONCEPT_BEGIN(3) #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) @@ -930,6 +930,32 @@ NBL_CONCEPT_END( #undef bxdf #include +// TODO: make these tractable_pdf_bxdf concepts (for existing bxdfs) -- or maybe not, tractable pdf may become a property + +// #define NBL_CONCEPT_NAME bxdf_common +// #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +// #define NBL_CONCEPT_TPLT_PRM_NAMES (T) +// #define NBL_CONCEPT_PARAM_0 (bxdf, T) +// #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) +// #define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) +// NBL_CONCEPT_BEGIN(3) +// #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +// #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +// #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +// NBL_CONCEPT_END( +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) +// ); +// #undef aniso +// #undef _sample +// #undef bxdf +// #include + #define NBL_CONCEPT_NAME iso_bxdf_common #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) @@ -943,9 +969,9 @@ NBL_CONCEPT_BEGIN(3) NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) ); @@ -953,6 +979,30 @@ NBL_CONCEPT_END( #undef _sample #undef bxdf #include + +// #define NBL_CONCEPT_NAME iso_bxdf_common +// #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +// #define NBL_CONCEPT_TPLT_PRM_NAMES (T) +// #define NBL_CONCEPT_PARAM_0 (bxdf, T) +// #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) +// #define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) +// NBL_CONCEPT_BEGIN(3) +// #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +// #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +// #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +// NBL_CONCEPT_END( +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) +// ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) +// ); +// #undef iso +// #undef _sample +// #undef bxdf +// #include } #define NBL_CONCEPT_NAME BRDF @@ -1054,9 +1104,9 @@ NBL_CONCEPT_BEGIN(4) NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) @@ -1068,6 +1118,35 @@ NBL_CONCEPT_END( #undef bxdf #include +// #define NBL_CONCEPT_NAME microfacet_bxdf_common +// #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +// #define NBL_CONCEPT_TPLT_PRM_NAMES (T) +// #define NBL_CONCEPT_PARAM_0 (bxdf, T) +// #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) +// #define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) +// #define NBL_CONCEPT_PARAM_3 (anisocache, typename T::anisocache_type) +// NBL_CONCEPT_BEGIN(4) +// #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +// #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +// #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +// #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +// NBL_CONCEPT_END( +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) +// ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) +// ); +// #undef anisocache +// #undef aniso +// #undef _sample +// #undef bxdf +// #include + #define NBL_CONCEPT_NAME iso_microfacet_bxdf_common #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) @@ -1084,9 +1163,9 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(microfacet_bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(CreatableIsotropicMicrofacetCache, typename T::isocache_type)) ); @@ -1095,6 +1174,34 @@ NBL_CONCEPT_END( #undef _sample #undef bxdf #include + +// #define NBL_CONCEPT_NAME iso_microfacet_bxdf_common +// #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +// #define NBL_CONCEPT_TPLT_PRM_NAMES (T) +// #define NBL_CONCEPT_PARAM_0 (bxdf, T) +// #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) +// #define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) +// #define NBL_CONCEPT_PARAM_3 (isocache, typename T::isocache_type) +// NBL_CONCEPT_BEGIN(4) +// #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +// #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +// #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +// #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +// NBL_CONCEPT_END( +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(microfacet_bxdf_common, T)) +// ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) +// ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) +// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) +// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(CreatableIsotropicMicrofacetCache, typename T::isocache_type)) +// ); +// #undef isocache +// #undef iso +// #undef _sample +// #undef bxdf +// #include } #define NBL_CONCEPT_NAME MicrofacetBRDF diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index 9bf9e16aa9..fd8291e3c2 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -25,13 +25,13 @@ struct SDeltaDistribution NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(0); + return quotient_pdf_type::create(0.0, 0.0); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(0); + return quotient_pdf_type::create(0.0, 0.0); } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC @@ -61,14 +61,14 @@ struct SDeltaDistribution return 0; } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(1.0, _pdf); } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_pdf(_sample, interaction.isotropic); + return quotient_and_weight(_sample, interaction.isotropic); } }; diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index 7ec41aeed5..1796971b10 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -25,13 +25,13 @@ struct SDeltaDistribution NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(0); + return quotient_pdf_type::create(0.0, 0.0); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(0); + return quotient_pdf_type::create(0.0, 0.0); } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC @@ -58,14 +58,14 @@ struct SDeltaDistribution return 0; } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(1.0, _pdf); } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_pdf(_sample, interaction.isotropic); + return quotient_and_weight(_sample, interaction.isotropic); } }; diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index bee202dc8d..c5f38dd13e 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -26,13 +26,13 @@ struct SSmoothDielectric NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(0); + return quotient_pdf_type::create(0.0, 0.0); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(0); + return quotient_pdf_type::create(0.0, 0.0); } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(vector3_type) u) NBL_CONST_MEMBER_FUNC @@ -67,13 +67,13 @@ struct SSmoothDielectric } // smooth BxDFs are isotropic by definition - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(1.0, bit_cast(numeric_limits::infinity)); } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_pdf(_sample, interaction.isotropic); + return quotient_and_weight(_sample, interaction.isotropic); } fresnel::OrientedEtas orientedEta; @@ -105,19 +105,19 @@ struct SThinSmoothDielectric return retval; } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(0); + return quotient_pdf_type::create(0.0, 0.0); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return hlsl::promote(0); + return quotient_pdf_type::create(0.0, 0.0); } // usually `luminosityContributionHint` would be the Rec.709 luma coefficients (the Y row of the RGB to CIE XYZ matrix) // its basically a set of weights that determine // assert(1.0==luminosityContributionHint.r+luminosityContributionHint.g+luminosityContributionHint.b); - // `remainderMetadata` is a variable which the generator function returns byproducts of sample generation that would otherwise have to be redundantly calculated `quotient_and_pdf` + // `remainderMetadata` is a variable which the generator function returns byproducts of sample generation that would otherwise have to be redundantly calculated `quotient_and_weight` sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u, NBL_REF_ARG(spectral_type) remainderMetadata) NBL_CONST_MEMBER_FUNC { // we will only ever intersect from the outside @@ -160,7 +160,7 @@ struct SThinSmoothDielectric } // smooth BxDFs are isotropic by definition - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const bool transmitted = ComputeMicrofacetNormal::isTransmissionPath(interaction.getNdotV(), _sample.getNdotL()); const spectral_type reflectance = fresnel::thinDielectricInfiniteScatter(fresnel(interaction.getNdotV(_clamp))); @@ -171,9 +171,9 @@ struct SThinSmoothDielectric const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(sampleValue / sampleProb, _pdf); } - 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 + quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_pdf(_sample, interaction.isotropic); + return quotient_and_weight(_sample, interaction.isotropic); } fresnel::Dielectric fresnel; From fc6deb80f457e6e50ea79da0ec35f1f8787be72b Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 20 Mar 2026 17:03:34 +0700 Subject: [PATCH 02/35] pdf method renamed to denominator, don't expect to be used --- include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl | 9 +++++---- include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl | 11 ++++++----- include/nbl/builtin/hlsl/bxdf/common.hlsl | 4 ++-- .../hlsl/bxdf/reflection/delta_distribution.hlsl | 4 ++-- .../hlsl/bxdf/transmission/delta_distribution.hlsl | 4 ++-- .../hlsl/bxdf/transmission/smooth_dielectric.hlsl | 10 +++++----- 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 92c5e2867d..01bd494fc5 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -28,7 +28,7 @@ struct SLambertianBase quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); - return quotient_pdf_type::create(quo, pdf(_sample, interaction)); + return quotient_pdf_type::create(quo, denominator(_sample, interaction)); } quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { @@ -63,16 +63,17 @@ struct SLambertianBase return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + // pdf function, because this BxDF has a tractable pdf, indicates that eval weight is also pdf + scalar_type denominator(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::pdf(_sample.getNdotL(_clamp)); else return sampling::ProjectedHemisphere::pdf(_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 + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return pdf(_sample, interaction.isotropic); + return denominator(_sample, interaction.isotropic); } quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index ae414cfcec..eb75217569 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -62,7 +62,7 @@ struct SOrenNayarBase { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); - return quotient_pdf_type::create(__eval(query, _sample, interaction), pdf(_sample, interaction)); + return quotient_pdf_type::create(__eval(query, _sample, interaction), denominator(_sample, interaction)); } quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { @@ -97,22 +97,23 @@ struct SOrenNayarBase return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + // pdf function, because this BxDF has a tractable pdf + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { if (IsBSDF) return sampling::ProjectedSphere::pdf(_sample.getNdotL(_clamp)); else return sampling::ProjectedHemisphere::pdf(_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 + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return pdf(_sample, interaction.isotropic); + return denominator(_sample, interaction.isotropic); } template quotient_pdf_type __quotient_and_weight(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - scalar_type _pdf = pdf(_sample, interaction); + scalar_type _pdf = denominator(_sample, interaction); scalar_type q = __rec_pi_factored_out_wo_clamps(query.getVdotL(), _sample.getNdotL(_clamp), interaction.getNdotV(_clamp)); return quotient_pdf_type::create(q, _pdf); } diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 47ba881d9e..25911adee1 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -919,7 +919,7 @@ NBL_CONCEPT_BEGIN(3) NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.denominator(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) @@ -970,7 +970,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.denominator(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index fd8291e3c2..34da8fdfc9 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -52,11 +52,11 @@ struct SDeltaDistribution return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index 1796971b10..03fc46acc4 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -49,11 +49,11 @@ struct SDeltaDistribution return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index c5f38dd13e..3a01ee8dd5 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -26,6 +26,7 @@ struct SSmoothDielectric NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; + // eval and weight return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); @@ -56,12 +57,11 @@ struct SSmoothDielectric return generate(anisotropic_interaction_type::create(interaction), u); } - // eval and pdf return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } @@ -150,11 +150,11 @@ struct SThinSmoothDielectric return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } From f2e2265da888165163ba6aba03458ab9ad700ead Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 23 Mar 2026 11:13:38 +0700 Subject: [PATCH 03/35] camelcase method names, no need for denominator method (pdf is pdf and weight is separate) --- .../builtin/hlsl/bxdf/base/lambertian.hlsl | 21 +++++++------- .../builtin/hlsl/bxdf/base/oren_nayar.hlsl | 27 +++++++++--------- include/nbl/builtin/hlsl/bxdf/common.hlsl | 10 +++---- .../bxdf/reflection/delta_distribution.hlsl | 14 +++++----- .../bxdf/transmission/delta_distribution.hlsl | 14 +++++----- .../bxdf/transmission/smooth_dielectric.hlsl | 28 +++++++++---------- 6 files changed, 55 insertions(+), 59 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 01bd494fc5..b99bde6292 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -25,14 +25,14 @@ struct SLambertianBase NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); - return quotient_pdf_type::create(quo, denominator(_sample, interaction)); + return quotient_pdf_type::create(quo, pdf(_sample, interaction)); } - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return eval_and_weight(_sample, interaction.isotropic); + return evalAndWeight(_sample, interaction.isotropic); } template > @@ -63,20 +63,19 @@ struct SLambertianBase return generate(anisotropic_interaction_type::create(interaction), u); } - // pdf function, because this BxDF has a tractable pdf, indicates that eval weight is also pdf - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + 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::pdf(_sample.getNdotL(_clamp)); else return sampling::ProjectedHemisphere::pdf(_sample.getNdotL(_clamp)); } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return denominator(_sample, interaction.isotropic); + return pdf(_sample, interaction.isotropic); } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { sampling::quotient_and_pdf qp; NBL_IF_CONSTEXPR (IsBSDF) @@ -85,9 +84,9 @@ struct SLambertianBase qp = sampling::ProjectedHemisphere::template quotientAndPdf(_sample.getNdotL(_clamp)); return quotient_pdf_type::create(qp.quotient()[0], qp.pdf()); } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_weight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic); } }; diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index eb75217569..585dd7c818 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -58,15 +58,15 @@ struct SOrenNayarBase return hlsl::promote(NdotL * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF) * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp))); } - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); - return quotient_pdf_type::create(__eval(query, _sample, interaction), denominator(_sample, interaction)); + return quotient_pdf_type::create(__eval(query, _sample, interaction), pdf(_sample, interaction)); } - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return eval_and_weight(_sample, interaction.isotropic); + return evalAndWeight(_sample, interaction.isotropic); } template > @@ -97,35 +97,34 @@ struct SOrenNayarBase return generate(anisotropic_interaction_type::create(interaction), u); } - // pdf function, because this BxDF has a tractable pdf - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + 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::pdf(_sample.getNdotL(_clamp)); else return sampling::ProjectedHemisphere::pdf(_sample.getNdotL(_clamp)); } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return denominator(_sample, interaction.isotropic); + return pdf(_sample, interaction.isotropic); } template - quotient_pdf_type __quotient_and_weight(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type __quotientAndWeight(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - scalar_type _pdf = denominator(_sample, interaction); + scalar_type _pdf = pdf(_sample, interaction); scalar_type q = __rec_pi_factored_out_wo_clamps(query.getVdotL(), _sample.getNdotL(_clamp), interaction.getNdotV(_clamp)); return quotient_pdf_type::create(q, _pdf); } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); - return __quotient_and_weight(query, _sample, interaction); + return __quotientAndWeight(query, _sample, interaction); } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_weight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic); } scalar_type A2; diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 25911adee1..a094e5c6b1 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -918,9 +918,8 @@ NBL_CONCEPT_BEGIN(3) #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.denominator(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) @@ -969,9 +968,8 @@ NBL_CONCEPT_BEGIN(3) NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.denominator(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) ); diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index 34da8fdfc9..f492ac0fdd 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -25,11 +25,11 @@ struct SDeltaDistribution NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } @@ -52,23 +52,23 @@ struct SDeltaDistribution return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(1.0, _pdf); } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_weight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic); } }; diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index 03fc46acc4..dffde471dd 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -25,11 +25,11 @@ struct SDeltaDistribution NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } @@ -49,23 +49,23 @@ struct SDeltaDistribution return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(1.0, _pdf); } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_weight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic); } }; diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index 3a01ee8dd5..5fc2587d87 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -27,11 +27,11 @@ struct SSmoothDielectric NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; // eval and weight return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } @@ -57,23 +57,23 @@ struct SSmoothDielectric return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } // smooth BxDFs are isotropic by definition - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(1.0, bit_cast(numeric_limits::infinity)); } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_weight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic); } fresnel::OrientedEtas orientedEta; @@ -105,11 +105,11 @@ struct SThinSmoothDielectric return retval; } - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type eval_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } @@ -150,17 +150,17 @@ struct SThinSmoothDielectric return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type denominator(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } // smooth BxDFs are isotropic by definition - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const bool transmitted = ComputeMicrofacetNormal::isTransmissionPath(interaction.getNdotV(), _sample.getNdotL()); const spectral_type reflectance = fresnel::thinDielectricInfiniteScatter(fresnel(interaction.getNdotV(_clamp))); @@ -171,9 +171,9 @@ struct SThinSmoothDielectric const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(sampleValue / sampleProb, _pdf); } - quotient_pdf_type quotient_and_weight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return quotient_and_weight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic); } fresnel::Dielectric fresnel; From 070885996d413b1e6998998364f758d29c8f878c Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 23 Mar 2026 11:39:40 +0700 Subject: [PATCH 04/35] refactor cook torrance to fit concept --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 30639d6b7c..78345032bd 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -156,11 +156,15 @@ struct SCookTorrance template, class MicrofacetCache=conditional_t NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); if (!__checkValid(_f, _sample, interaction, cache)) - return hlsl::promote(0.0); + return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); + + bool isInfinity; + scalar_type _pdf = __pdf(_sample, interaction, cache, isInfinity); + _pdf = hlsl::mix(_pdf, scalar_type(0.0), isInfinity); using quant_query_type = typename ndf_type::quant_query_type; quant_query_type qq = impl::quant_query_helper::template __call(ndf, _f, interaction, cache); @@ -168,7 +172,6 @@ struct SCookTorrance using g2g1_query_type = typename ndf_type::g2g1_query_type; g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); - bool isInfinity; quant_type D = ndf.template D(qq, _sample, interaction, cache, isInfinity); scalar_type DG = D.projectedLightMeasure; if (!isInfinity) @@ -179,19 +182,22 @@ struct SCookTorrance // immediately return only after all calls setting DG // allows compiler to throw away calls to ndf.D if using __overwriteDG, before that we only avoid computation for G2(correlated) if (isInfinity) - return hlsl::promote(0.0); + return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); scalar_type clampedVdotH = cache.getVdotH(); NBL_IF_CONSTEXPR(IsBSDF) clampedVdotH = hlsl::abs(clampedVdotH); + spectral_type quo; NBL_IF_CONSTEXPR(IsBSDF) { const spectral_type reflectance = impl::__implicit_promote::__call(_f(clampedVdotH)); - return hlsl::mix(reflectance, hlsl::promote(1.0) - reflectance, cache.isTransmission()) * DG; + quo = hlsl::mix(reflectance, hlsl::promote(1.0) - reflectance, cache.isTransmission()) * DG; } else - return impl::__implicit_promote::__call(_f(clampedVdotH)) * DG; + quo = impl::__implicit_promote::__call(_f(clampedVdotH)) * DG; + + return quotient_pdf_type::create(quo, _pdf); } sample_type __generate_common(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type localH, @@ -380,7 +386,7 @@ struct SCookTorrance template, class MicrofacetCache=conditional_t NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { if (!_sample.isValid()) return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); // set pdf=0 when quo=0 because we don't want to give high weight to sampling strategy that yields 0 contribution From 63cd4df209b89e884d69b3d4cada17363cb8e712 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 23 Mar 2026 14:16:44 +0700 Subject: [PATCH 05/35] changes to method names in pt concept, use *_weight instead of pdf and camelcase --- .../builtin/hlsl/path_tracing/concepts.hlsl | 13 +++++------ .../hlsl/path_tracing/unidirectional.hlsl | 23 +++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl index 25ca98772c..f028de756d 100644 --- a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl @@ -182,10 +182,9 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::bxdfnode_type)) ((NBL_CONCEPT_REQ_TYPE)(T::create_params_t)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(BxdfNode, typename T::bxdfnode_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.eval(matid, _sample, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::measure_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.evalAndWeight(matid, _sample, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.generate(matid, aniso_inter, u, cache_)), ::nbl::hlsl::is_same_v, typename T::sample_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.pdf(matid, _sample, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.quotient_and_pdf(matid, _sample, aniso_inter, cache_)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.quotientAndWeight(matid, _sample, aniso_inter, cache_)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.getBxDFNode(matid, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::bxdfnode_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.hasEmission(matid)), ::nbl::hlsl::is_same_v, bool)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.setMonochromeEta(matid, cie_y)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) @@ -261,10 +260,10 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::tolerance_method_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(NextEventEstimatorSampleQuotientReturn, typename T::sample_quotient_return_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(Ray, typename T::ray_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.deferred_pdf(scene, id, ray)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.template generate_and_quotient_and_pdf(scene, matSys, v/*origin*/, interaction, v/*xi*/, depth)), ::nbl::hlsl::is_same_v, typename T::sample_quotient_return_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.get_env_light_id()), ::nbl::hlsl::is_same_v, typename T::light_id_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.get_environment_radiance(ray)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.deferredPdf(scene, id, ray)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.template generateAndQuotientAndWeight(scene, matSys, v/*origin*/, interaction, v/*xi*/, depth)), ::nbl::hlsl::is_same_v, typename T::sample_quotient_return_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.getEnvLightId()), ::nbl::hlsl::is_same_v, typename T::light_id_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.getEnvRadiance(ray)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) ); #undef scene #undef depth diff --git a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl index 98a81738cb..68eaf6d089 100644 --- a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl @@ -69,7 +69,7 @@ struct Unidirectional if (ray.shouldDoMIS() && matLightID.isLight()) { emissive *= ray.getPayloadThroughput(); - const scalar_type pdf = nee.deferred_pdf(scene, lightID, ray); + const scalar_type pdf = nee.deferredPdf(scene, lightID, ray); assert(!hlsl::isinf(pdf)); emissive *= ray.foundEmissiveMIS(pdf * pdf); } @@ -94,7 +94,7 @@ struct Unidirectional assert(neeProbability >= 0.0 && neeProbability <= 1.0); if (!partitionRandVariable(eps0.z, rcpChoiceProb)) { - typename nee_type::sample_quotient_return_type ret = nee.template generate_and_quotient_and_pdf( + typename nee_type::sample_quotient_return_type ret = nee.template generateAndQuotientAndWeight( scene, materialSystem, intersectP, interaction, eps0, depth ); @@ -108,12 +108,11 @@ struct Unidirectional // 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)) { - // 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; + quotient_pdf_type bsdfContrib = materialSystem.evalAndWeight(matID, nee_sample, interaction); + neeContrib._quotient *= bsdfContrib.quotient() * rcpChoiceProb; if (neeContrib.pdf() < bit_cast(numeric_limits::infinity)) { - const scalar_type otherGenOverLightAndChoice = bsdf_pdf * rcpChoiceProb / neeContrib.pdf(); + const scalar_type otherGenOverLightAndChoice = bsdfContrib.pdf() * rcpChoiceProb / neeContrib.pdf(); neeContrib._quotient /= 1.f + otherGenOverLightAndChoice * otherGenOverLightAndChoice; // balance heuristic } @@ -141,9 +140,9 @@ struct Unidirectional return false; // 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(); + quotient_pdf_type bsdf_quotient_weight = materialSystem.quotientAndWeight(matID, bsdf_sample, interaction, _cache); + throughput *= bsdf_quotient_weight.quotient(); + bxdfPdf = bsdf_quotient_weight.pdf(); bxdfSample = bsdf_sample.getL().getDirection(); } @@ -170,9 +169,9 @@ struct Unidirectional void missProgram(NBL_REF_ARG(ray_type) ray) { - measure_type finalContribution = nee.get_environment_radiance(ray); - typename nee_type::light_id_type env_light_id = nee.get_env_light_id(); - const scalar_type pdf = nee.deferred_pdf(scene, env_light_id, ray); + measure_type finalContribution = nee.getEnvRadiance(ray); + typename nee_type::light_id_type env_light_id = nee.getEnvLightId(); + const scalar_type pdf = nee.deferredPdf(scene, env_light_id, ray); finalContribution *= ray.getPayloadThroughput(); if (pdf > scalar_type(0.0)) finalContribution *= ray.foundEmissiveMIS(pdf * pdf); From a877934d0f3928b543cb0e6f28c0612f2cbc29df Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 23 Mar 2026 14:46:11 +0700 Subject: [PATCH 06/35] renamed pdf to forwardPdf --- .../nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl | 10 +++++----- include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl | 10 +++++----- include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl | 10 +++++----- .../hlsl/bxdf/reflection/delta_distribution.hlsl | 4 ++-- .../hlsl/bxdf/transmission/delta_distribution.hlsl | 4 ++-- .../hlsl/bxdf/transmission/smooth_dielectric.hlsl | 8 ++++---- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 78345032bd..b478716cd0 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -163,7 +163,7 @@ struct SCookTorrance return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); bool isInfinity; - scalar_type _pdf = __pdf(_sample, interaction, cache, isInfinity); + scalar_type _pdf = __forwardPdf(_sample, interaction, cache, isInfinity); _pdf = hlsl::mix(_pdf, scalar_type(0.0), isInfinity); using quant_query_type = typename ndf_type::quant_query_type; @@ -347,7 +347,7 @@ struct SCookTorrance } template - scalar_type __pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC + scalar_type __forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { using quant_query_type = typename ndf_type::quant_query_type; using dg1_query_type = typename ndf_type::dg1_query_type; @@ -372,14 +372,14 @@ struct SCookTorrance template, class MicrofacetCache=conditional_t NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); if (!__checkValid(_f, _sample, interaction, cache)) return scalar_type(0.0); bool isInfinity; - scalar_type _pdf = __pdf(_sample, interaction, cache, isInfinity); + scalar_type _pdf = __forwardPdf(_sample, interaction, cache, isInfinity); return hlsl::mix(_pdf, scalar_type(0.0), isInfinity); } @@ -392,7 +392,7 @@ struct SCookTorrance return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); // set pdf=0 when quo=0 because we don't want to give high weight to sampling strategy that yields 0 contribution bool isInfinity; - scalar_type _pdf = __pdf(_sample, interaction, cache, isInfinity); + scalar_type _pdf = __forwardPdf(_sample, interaction, cache, isInfinity); fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); const bool valid = __checkValid(_f, _sample, interaction, cache); diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index b99bde6292..4d5dc9ce26 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -28,7 +28,7 @@ struct SLambertianBase quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); - return quotient_pdf_type::create(quo, pdf(_sample, interaction)); + return quotient_pdf_type::create(quo, forwardPdf(_sample, interaction)); } quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { @@ -63,16 +63,16 @@ struct SLambertianBase return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(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::pdf(_sample.getNdotL(_clamp)); else return sampling::ProjectedHemisphere::pdf(_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 + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return pdf(_sample, interaction.isotropic); + return forwardPdf(_sample, interaction.isotropic); } quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -82,7 +82,7 @@ struct SLambertianBase qp = sampling::ProjectedSphere::template quotientAndPdf(_sample.getNdotL(_clamp)); else qp = sampling::ProjectedHemisphere::template quotientAndPdf(_sample.getNdotL(_clamp)); - return quotient_pdf_type::create(qp.quotient()[0], qp.pdf()); + return quotient_pdf_type::create(qp.quotient(), qp.pdf()); } quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index 585dd7c818..d8cb919754 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -62,7 +62,7 @@ struct SOrenNayarBase { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); - return quotient_pdf_type::create(__eval(query, _sample, interaction), pdf(_sample, interaction)); + return quotient_pdf_type::create(__eval(query, _sample, interaction), forwardPdf(_sample, interaction)); } quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { @@ -97,22 +97,22 @@ struct SOrenNayarBase return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { if (IsBSDF) return sampling::ProjectedSphere::pdf(_sample.getNdotL(_clamp)); else return sampling::ProjectedHemisphere::pdf(_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 + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - return pdf(_sample, interaction.isotropic); + return forwardPdf(_sample, interaction.isotropic); } template quotient_pdf_type __quotientAndWeight(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - scalar_type _pdf = pdf(_sample, interaction); + scalar_type _pdf = forwardPdf(_sample, interaction); scalar_type q = __rec_pi_factored_out_wo_clamps(query.getVdotL(), _sample.getNdotL(_clamp), interaction.getNdotV(_clamp)); return quotient_pdf_type::create(q, _pdf); } diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index f492ac0fdd..c6abb8646a 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -52,11 +52,11 @@ struct SDeltaDistribution return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index dffde471dd..f99d3f246a 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -49,11 +49,11 @@ struct SDeltaDistribution return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index 5fc2587d87..c9ff42cec0 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -57,11 +57,11 @@ struct SSmoothDielectric return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } @@ -150,11 +150,11 @@ struct SThinSmoothDielectric return generate(anisotropic_interaction_type::create(interaction), u); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return 0; } From 64ce3baeb6cd49b9ab80553b927849f0f0c4c620 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 23 Mar 2026 14:53:34 +0700 Subject: [PATCH 07/35] add tractable pdf trait to bxdfs --- include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl | 1 + include/nbl/builtin/hlsl/bxdf/reflection/lambertian.hlsl | 1 + include/nbl/builtin/hlsl/bxdf/reflection/oren_nayar.hlsl | 1 + .../nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl | 1 + include/nbl/builtin/hlsl/bxdf/transmission/lambertian.hlsl | 1 + include/nbl/builtin/hlsl/bxdf/transmission/oren_nayar.hlsl | 1 + .../nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl | 2 ++ 7 files changed, 8 insertions(+) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index b478716cd0..4d0672902b 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -442,6 +442,7 @@ struct traits > NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = true; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = !__type::IsBSDF; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = !__type::IsBSDF; + NBL_CONSTEXPR_STATIC_INLINE bool TractablePdf = true; }; } diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/lambertian.hlsl index 0e0e6bebb0..da0411eb4d 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/lambertian.hlsl @@ -28,6 +28,7 @@ struct traits > NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; + NBL_CONSTEXPR_STATIC_INLINE bool TractablePdf = true; }; } diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/oren_nayar.hlsl index df0e6ebc19..4ea6000419 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/oren_nayar.hlsl @@ -28,6 +28,7 @@ struct traits > NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = true; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; + NBL_CONSTEXPR_STATIC_INLINE bool TractablePdf = true; }; } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index f99d3f246a..9a30bf440a 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -78,6 +78,7 @@ struct traits > NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; + NBL_CONSTEXPR_STATIC_INLINE bool TractablePdf = true; }; } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/lambertian.hlsl index 6ea67a65fd..0751ead92f 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/lambertian.hlsl @@ -28,6 +28,7 @@ struct traits > NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; + NBL_CONSTEXPR_STATIC_INLINE bool TractablePdf = true; }; } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/oren_nayar.hlsl index b39d48d2bf..1b224b34e1 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/oren_nayar.hlsl @@ -28,6 +28,7 @@ struct traits > NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = true; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; + NBL_CONSTEXPR_STATIC_INLINE bool TractablePdf = true; }; } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index c9ff42cec0..ee72fa0a9d 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -188,6 +188,7 @@ struct traits > NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = true; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; + NBL_CONSTEXPR_STATIC_INLINE bool TractablePdf = true; }; template @@ -197,6 +198,7 @@ struct traits > NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = false; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = true; NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = true; + NBL_CONSTEXPR_STATIC_INLINE bool TractablePdf = true; }; } From 148b9bdb90b2bfe5661f4b004c3fede61c0675ee Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 23 Mar 2026 16:54:55 +0700 Subject: [PATCH 08/35] bxdf input random to generate has variable dimensions (brdf>=2; bsdf>=3) for RIS sampling --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 7 +- .../builtin/hlsl/bxdf/base/lambertian.hlsl | 14 +- .../builtin/hlsl/bxdf/base/oren_nayar.hlsl | 14 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 135 +++--------------- .../bxdf/reflection/delta_distribution.hlsl | 6 +- .../bxdf/transmission/delta_distribution.hlsl | 6 +- .../bxdf/transmission/smooth_dielectric.hlsl | 25 ++-- 7 files changed, 53 insertions(+), 154 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 4d0672902b..6b68879166 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -83,6 +83,7 @@ struct SCookTorrance NBL_CONSTEXPR_STATIC_INLINE bool IsAnisotropic = ndf_type::IsAnisotropic; NBL_CONSTEXPR_STATIC_INLINE bool IsBSDF = ndf_type::SupportedPaths != ndf::MTT_REFLECT; + using random_type = conditional_t; NBL_HLSL_BXDF_ANISOTROPIC_COND_DECLS(IsAnisotropic); // utility functions @@ -251,7 +252,7 @@ struct SCookTorrance return sample_type::create(L, T, B, NdotL); } template NBL_FUNC_REQUIRES(C::value && !IsBSDF) - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u, NBL_REF_ARG(anisocache_type) cache) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) cache) NBL_CONST_MEMBER_FUNC { const scalar_type NdotV = interaction.getNdotV(); if (NdotV < numeric_limits::min) @@ -281,7 +282,7 @@ struct SCookTorrance return s; } template NBL_FUNC_REQUIRES(C::value && IsBSDF) - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u, NBL_REF_ARG(anisocache_type) cache) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) cache) NBL_CONST_MEMBER_FUNC { const vector3_type localV = interaction.getTangentSpaceV(); const scalar_type NdotV = localV.z; @@ -338,7 +339,7 @@ struct SCookTorrance return s; } template NBL_FUNC_REQUIRES(C::value && !IsAnisotropic) - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const conditional_t u, NBL_REF_ARG(isocache_type) cache) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(isocache_type) cache) NBL_CONST_MEMBER_FUNC { anisocache_type aniso_cache; sample_type s = generate(anisotropic_interaction_type::create(interaction), u, aniso_cache); diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 4d5dc9ce26..1d2588b008 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -23,6 +23,8 @@ struct SLambertianBase using this_t = SLambertianBase; BXDF_CONFIG_TYPE_ALIASES(Config); + using random_type = conditional_t; + NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -36,7 +38,7 @@ struct SLambertianBase } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { typename sampling::ProjectedHemisphere::cache_type cache; ray_dir_info_type L; @@ -44,7 +46,7 @@ struct SLambertianBase return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { typename sampling::ProjectedSphere::cache_type cache; vector3_type _u = u; @@ -52,13 +54,7 @@ struct SLambertianBase L.setDirection(sampling::ProjectedSphere::generate(_u, cache)); return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } - template > - enable_if_t generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC - { - return generate(anisotropic_interaction_type::create(interaction), u); - } - template > - enable_if_t generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { return generate(anisotropic_interaction_type::create(interaction), u); } diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index d8cb919754..4b356a1ecd 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -23,6 +23,8 @@ struct SOrenNayarBase using this_t = SOrenNayarBase; BXDF_CONFIG_TYPE_ALIASES(Config); + using random_type = conditional_t; + NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; struct SCreationParams @@ -70,7 +72,7 @@ struct SOrenNayarBase } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { typename sampling::ProjectedHemisphere::cache_type cache; ray_dir_info_type L; @@ -78,7 +80,7 @@ struct SOrenNayarBase return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { typename sampling::ProjectedSphere::cache_type cache; vector3_type _u = u; @@ -86,13 +88,7 @@ struct SOrenNayarBase L.setDirection(sampling::ProjectedSphere::generate(_u, cache)); return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } - template > - enable_if_t generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC - { - return generate(anisotropic_interaction_type::create(interaction), u); - } - template > - enable_if_t generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { return generate(anisotropic_interaction_type::create(interaction), u); } diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index a094e5c6b1..e9e103e203 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -902,6 +902,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::random_type)) ); #undef bxdf #include @@ -929,32 +930,6 @@ NBL_CONCEPT_END( #undef bxdf #include -// TODO: make these tractable_pdf_bxdf concepts (for existing bxdfs) -- or maybe not, tractable pdf may become a property - -// #define NBL_CONCEPT_NAME bxdf_common -// #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -// #define NBL_CONCEPT_TPLT_PRM_NAMES (T) -// #define NBL_CONCEPT_PARAM_0 (bxdf, T) -// #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) -// #define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) -// NBL_CONCEPT_BEGIN(3) -// #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -// #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -// #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -// NBL_CONCEPT_END( -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) -// ); -// #undef aniso -// #undef _sample -// #undef bxdf -// #include - #define NBL_CONCEPT_NAME iso_bxdf_common #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) @@ -978,29 +953,10 @@ NBL_CONCEPT_END( #undef bxdf #include -// #define NBL_CONCEPT_NAME iso_bxdf_common -// #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -// #define NBL_CONCEPT_TPLT_PRM_NAMES (T) -// #define NBL_CONCEPT_PARAM_0 (bxdf, T) -// #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) -// #define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) -// NBL_CONCEPT_BEGIN(3) -// #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -// #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -// #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -// NBL_CONCEPT_END( -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) -// ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) -// ); -// #undef iso -// #undef _sample -// #undef bxdf -// #include +template +NBL_BOOL_CONCEPT VecDim2OrMore = vector_traits::Dimension >= 2; +template +NBL_BOOL_CONCEPT VecDim3OrMore = vector_traits::Dimension >= 3; } #define NBL_CONCEPT_NAME BRDF @@ -1008,13 +964,14 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (aniso, typename T::anisotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, vector) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) NBL_CONCEPT_BEGIN(3) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); #undef u @@ -1027,13 +984,14 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (aniso, typename T::anisotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, vector) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) NBL_CONCEPT_BEGIN(3) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); #undef u @@ -1046,13 +1004,14 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (iso, typename T::isotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, vector) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) NBL_CONCEPT_BEGIN(3) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); #undef u @@ -1065,13 +1024,14 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (iso, typename T::isotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, vector) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) NBL_CONCEPT_BEGIN(3) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); #undef u @@ -1116,35 +1076,6 @@ NBL_CONCEPT_END( #undef bxdf #include -// #define NBL_CONCEPT_NAME microfacet_bxdf_common -// #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -// #define NBL_CONCEPT_TPLT_PRM_NAMES (T) -// #define NBL_CONCEPT_PARAM_0 (bxdf, T) -// #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) -// #define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) -// #define NBL_CONCEPT_PARAM_3 (anisocache, typename T::anisocache_type) -// NBL_CONCEPT_BEGIN(4) -// #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -// #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -// #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -// #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 -// NBL_CONCEPT_END( -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) -// ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) -// ); -// #undef anisocache -// #undef aniso -// #undef _sample -// #undef bxdf -// #include - #define NBL_CONCEPT_NAME iso_microfacet_bxdf_common #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) @@ -1172,34 +1103,6 @@ NBL_CONCEPT_END( #undef _sample #undef bxdf #include - -// #define NBL_CONCEPT_NAME iso_microfacet_bxdf_common -// #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -// #define NBL_CONCEPT_TPLT_PRM_NAMES (T) -// #define NBL_CONCEPT_PARAM_0 (bxdf, T) -// #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) -// #define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) -// #define NBL_CONCEPT_PARAM_3 (isocache, typename T::isocache_type) -// NBL_CONCEPT_BEGIN(4) -// #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -// #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -// #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -// #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 -// NBL_CONCEPT_END( -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(microfacet_bxdf_common, T)) -// ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) -// ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) -// ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) -// ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(CreatableIsotropicMicrofacetCache, typename T::isocache_type)) -// ); -// #undef isocache -// #undef iso -// #undef _sample -// #undef bxdf -// #include } #define NBL_CONCEPT_NAME MicrofacetBRDF @@ -1207,7 +1110,7 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (aniso, typename T::anisotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, vector) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) #define NBL_CONCEPT_PARAM_3 (anisocache, typename T::anisocache_type) NBL_CONCEPT_BEGIN(4) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 @@ -1216,6 +1119,7 @@ NBL_CONCEPT_BEGIN(4) #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u,anisocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); #undef anisocache @@ -1229,7 +1133,7 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (aniso, typename T::anisotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, vector) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) #define NBL_CONCEPT_PARAM_3 (anisocache, typename T::anisocache_type) NBL_CONCEPT_BEGIN(4) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 @@ -1238,6 +1142,7 @@ NBL_CONCEPT_BEGIN(4) #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u,anisocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); #undef anisocache @@ -1251,7 +1156,7 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (iso, typename T::isotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, vector) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) #define NBL_CONCEPT_PARAM_3 (isocache, typename T::isocache_type) NBL_CONCEPT_BEGIN(4) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 @@ -1260,6 +1165,7 @@ NBL_CONCEPT_BEGIN(4) #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u,isocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); #undef isocache @@ -1273,7 +1179,7 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (iso, typename T::isotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, vector) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) #define NBL_CONCEPT_PARAM_3 (isocache, typename T::isocache_type) NBL_CONCEPT_BEGIN(4) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 @@ -1282,6 +1188,7 @@ NBL_CONCEPT_BEGIN(4) #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u,isocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); #undef isocache diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index c6abb8646a..84c25fb4fb 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -23,6 +23,8 @@ struct SDeltaDistribution using this_t = SDeltaDistribution; BXDF_CONFIG_TYPE_ALIASES(Config); + using random_type = vector2_type; + NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -34,7 +36,7 @@ struct SDeltaDistribution return quotient_pdf_type::create(0.0, 0.0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { vector3_type V = interaction.getV().getDirection(); bxdf::Reflect r = bxdf::Reflect::create(V, interaction.getN()); @@ -47,7 +49,7 @@ struct SDeltaDistribution return s; } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { return generate(anisotropic_interaction_type::create(interaction), u); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index 9a30bf440a..835b41a044 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -23,6 +23,8 @@ struct SDeltaDistribution using this_t = SDeltaDistribution; BXDF_CONFIG_TYPE_ALIASES(Config); + using random_type = vector2_type; + NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -34,7 +36,7 @@ struct SDeltaDistribution return quotient_pdf_type::create(0.0, 0.0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { ray_dir_info_type L = interaction.getV().transmit(); sample_type s = sample_type::create(L, interaction.getN()); @@ -44,7 +46,7 @@ struct SDeltaDistribution s.NdotL2 = interaction.getNdotV2(); return s; } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { return generate(anisotropic_interaction_type::create(interaction), u); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index ee72fa0a9d..d3af6840ec 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -24,6 +24,8 @@ struct SSmoothDielectric using this_t = SSmoothDielectric; BXDF_CONFIG_TYPE_ALIASES(Config); + using random_type = vector3_type; + NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; // eval and weight return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction @@ -36,7 +38,7 @@ struct SSmoothDielectric return quotient_pdf_type::create(0.0, 0.0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(vector3_type) u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(random_type) u) NBL_CONST_MEMBER_FUNC { const scalar_type reflectance = fresnel::Dielectric::__call(orientedEta.value*orientedEta.value, interaction.getNdotV(_clamp))[0]; @@ -52,7 +54,7 @@ struct SSmoothDielectric ray_dir_info_type L = V.reflectRefract(rr, transmitted, orientedEta.rcp[0]); return sample_type::create(L, interaction.getT(), interaction.getB(), interaction.getN()); } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_REF_ARG(vector3_type) u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_REF_ARG(random_type) u) NBL_CONST_MEMBER_FUNC { return generate(anisotropic_interaction_type::create(interaction), u); } @@ -83,16 +85,9 @@ template; - NBL_BXDF_CONFIG_ALIAS(scalar_type, Config); - NBL_BXDF_CONFIG_ALIAS(vector2_type, Config); - NBL_BXDF_CONFIG_ALIAS(vector3_type, Config); - NBL_BXDF_CONFIG_ALIAS(monochrome_type, Config); - NBL_BXDF_CONFIG_ALIAS(ray_dir_info_type, Config); - NBL_BXDF_CONFIG_ALIAS(isotropic_interaction_type, Config); - NBL_BXDF_CONFIG_ALIAS(anisotropic_interaction_type, Config); - NBL_BXDF_CONFIG_ALIAS(sample_type, Config); - NBL_BXDF_CONFIG_ALIAS(spectral_type, Config); - NBL_BXDF_CONFIG_ALIAS(quotient_pdf_type, Config); + BXDF_CONFIG_TYPE_ALIASES(Config); + + using random_type = vector3_type; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; @@ -118,7 +113,7 @@ struct SThinSmoothDielectric // its basically a set of weights that determine // assert(1.0==luminosityContributionHint.r+luminosityContributionHint.g+luminosityContributionHint.b); // `remainderMetadata` is a variable which the generator function returns byproducts of sample generation that would otherwise have to be redundantly calculated `quotient_and_weight` - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u, NBL_REF_ARG(spectral_type) remainderMetadata) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(spectral_type) remainderMetadata) NBL_CONST_MEMBER_FUNC { // we will only ever intersect from the outside const spectral_type reflectance = fresnel::thinDielectricInfiniteScatter(fresnel(interaction.getNdotV(_clamp))); @@ -140,12 +135,12 @@ struct SThinSmoothDielectric return sample_type::create(L, interaction.getT(), interaction.getB(), N); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { vector3_type dummy; return generate(interaction, u, dummy); } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC { return generate(anisotropic_interaction_type::create(interaction), u); } From 946c9c735913fe68125137772c0da52afb8b6106 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 24 Mar 2026 11:18:11 +0700 Subject: [PATCH 09/35] pass ray to nee generate instead, store depth in ray --- .../nbl/builtin/hlsl/path_tracing/concepts.hlsl | 11 ++++------- .../hlsl/path_tracing/unidirectional.hlsl | 17 +++++++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl index f028de756d..c4be1d83ad 100644 --- a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl @@ -234,17 +234,15 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_PARAM_3 (v, typename T::vector3_type) #define NBL_CONCEPT_PARAM_4 (matSys, impl::DummyMaterialSystem) #define NBL_CONCEPT_PARAM_5 (interaction, typename T::interaction_type) -#define NBL_CONCEPT_PARAM_6 (depth, uint16_t) -#define NBL_CONCEPT_PARAM_7 (scene, typename T::scene_type) -NBL_CONCEPT_BEGIN(8) +#define NBL_CONCEPT_PARAM_6 (scene, typename T::scene_type) +NBL_CONCEPT_BEGIN(7) #define nee NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define ray NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define id NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define v NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 #define matSys NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_4 #define interaction NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_5 -#define depth NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_6 -#define scene NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_7 +#define scene NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_6 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::scalar_type)) ((NBL_CONCEPT_REQ_TYPE)(T::vector3_type)) @@ -261,12 +259,11 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(NextEventEstimatorSampleQuotientReturn, typename T::sample_quotient_return_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(Ray, typename T::ray_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.deferredPdf(scene, id, ray)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.template generateAndQuotientAndWeight(scene, matSys, v/*origin*/, interaction, v/*xi*/, depth)), ::nbl::hlsl::is_same_v, typename T::sample_quotient_return_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.template generateAndQuotientAndWeight(scene, matSys, v/*origin*/, interaction, v/*xi*/, ray)), ::nbl::hlsl::is_same_v, typename T::sample_quotient_return_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.getEnvLightId()), ::nbl::hlsl::is_same_v, typename T::light_id_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.getEnvRadiance(ray)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) ); #undef scene -#undef depth #undef interaction #undef matSys #undef v diff --git a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl index ff12ea7f16..1aecf129bb 100644 --- a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl @@ -69,9 +69,9 @@ struct Unidirectional if (ray.shouldDoMIS() && matLightID.isLight()) { emissive *= ray.getPayloadThroughput(); - const scalar_type pdf = nee.deferredPdf(scene, lightID, ray); - assert(!hlsl::isinf(pdf)); - emissive *= ray.foundEmissiveMIS(pdf * pdf); + const scalar_type weight = nee.deferredPdf(scene, lightID, ray); + assert(!hlsl::isinf(weight)); + emissive *= ray.foundEmissiveMIS(weight * weight); } ray.addPayloadContribution(emissive); } @@ -95,8 +95,8 @@ struct Unidirectional if (!partitionRandVariable(eps0.z, rcpChoiceProb)) { typename nee_type::sample_quotient_return_type ret = nee.template generateAndQuotientAndWeight( - scene, materialSystem, intersectP, interaction, - eps0, depth + scene, materialSystem, intersectP, + interaction, eps0, ray ); scalar_type t = ret.getT(); sample_type nee_sample = ret.getSample(); @@ -171,10 +171,10 @@ struct Unidirectional { measure_type finalContribution = nee.getEnvRadiance(ray); typename nee_type::light_id_type env_light_id = nee.getEnvLightId(); - const scalar_type pdf = nee.deferredPdf(scene, env_light_id, ray); + const scalar_type weight = nee.deferredPdf(scene, env_light_id, ray); finalContribution *= ray.getPayloadThroughput(); - if (pdf > scalar_type(0.0)) - finalContribution *= ray.foundEmissiveMIS(pdf * pdf); + if (weight > scalar_type(0.0)) + finalContribution *= ray.foundEmissiveMIS(weight * weight); ray.addPayloadContribution(finalContribution); } @@ -188,6 +188,7 @@ struct Unidirectional for (uint16_t d = 1; (d <= maxDepth) && continuePath; d++) { ray.setT(numeric_limits::max); + ray.setDepth(d); closest_hit_type intersection = intersector_type::traceClosestHit(scene, ray); notMissed = intersection.foundHit(); From 4f4421d4bb6039e55f09e2701639c821f630aed1 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 24 Mar 2026 11:36:02 +0700 Subject: [PATCH 10/35] nee deferredPdf is deferredWeight --- include/nbl/builtin/hlsl/path_tracing/concepts.hlsl | 2 +- include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl index c4be1d83ad..438f0391de 100644 --- a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl @@ -258,7 +258,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::tolerance_method_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(NextEventEstimatorSampleQuotientReturn, typename T::sample_quotient_return_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(Ray, typename T::ray_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.deferredPdf(scene, id, ray)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.deferredWeight(scene, id, ray)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.template generateAndQuotientAndWeight(scene, matSys, v/*origin*/, interaction, v/*xi*/, ray)), ::nbl::hlsl::is_same_v, typename T::sample_quotient_return_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.getEnvLightId()), ::nbl::hlsl::is_same_v, typename T::light_id_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((nee.getEnvRadiance(ray)), ::nbl::hlsl::is_same_v, typename T::spectral_type)) diff --git a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl index 1aecf129bb..1752e9c768 100644 --- a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl @@ -69,7 +69,7 @@ struct Unidirectional if (ray.shouldDoMIS() && matLightID.isLight()) { emissive *= ray.getPayloadThroughput(); - const scalar_type weight = nee.deferredPdf(scene, lightID, ray); + const scalar_type weight = nee.deferredWeight(scene, lightID, ray); assert(!hlsl::isinf(weight)); emissive *= ray.foundEmissiveMIS(weight * weight); } @@ -171,7 +171,7 @@ struct Unidirectional { measure_type finalContribution = nee.getEnvRadiance(ray); typename nee_type::light_id_type env_light_id = nee.getEnvLightId(); - const scalar_type weight = nee.deferredPdf(scene, env_light_id, ray); + const scalar_type weight = nee.deferredWeight(scene, env_light_id, ray); finalContribution *= ray.getPayloadThroughput(); if (weight > scalar_type(0.0)) finalContribution *= ray.foundEmissiveMIS(weight * weight); From a70f420c4f84865ce4eaff72dc427e87ed7eca4e Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 24 Mar 2026 16:03:08 +0700 Subject: [PATCH 11/35] all bxdfs have a cache type from generate to quotient_weight, microfacet checks cache with concept --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 1 - .../builtin/hlsl/bxdf/base/lambertian.hlsl | 23 ++- .../builtin/hlsl/bxdf/base/oren_nayar.hlsl | 23 ++- include/nbl/builtin/hlsl/bxdf/common.hlsl | 175 +++--------------- .../bxdf/reflection/delta_distribution.hlsl | 19 +- .../bxdf/transmission/delta_distribution.hlsl | 17 +- .../bxdf/transmission/smooth_dielectric.hlsl | 38 ++-- 7 files changed, 95 insertions(+), 201 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 6b68879166..f243d717ac 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -165,7 +165,6 @@ struct SCookTorrance bool isInfinity; scalar_type _pdf = __forwardPdf(_sample, interaction, cache, isInfinity); - _pdf = hlsl::mix(_pdf, scalar_type(0.0), isInfinity); using quant_query_type = typename ndf_type::quant_query_type; quant_query_type qq = impl::quant_query_helper::template __call(ndf, _f, interaction, cache); diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 1d2588b008..3b3dd21e59 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -24,21 +24,24 @@ struct SLambertianBase BXDF_CONFIG_TYPE_ALIASES(Config); using random_type = conditional_t; + struct Cache {}; + using isocache_type = Cache; + using anisocache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); return quotient_pdf_type::create(quo, forwardPdf(_sample, interaction)); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return evalAndWeight(_sample, interaction.isotropic); + return evalAndWeight(_sample, interaction.isotropic, _cache); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { typename sampling::ProjectedHemisphere::cache_type cache; ray_dir_info_type L; @@ -46,7 +49,7 @@ struct SLambertianBase return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { typename sampling::ProjectedSphere::cache_type cache; vector3_type _u = u; @@ -54,9 +57,9 @@ struct SLambertianBase L.setDirection(sampling::ProjectedSphere::generate(_u, cache)); return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return generate(anisotropic_interaction_type::create(interaction), u); + return generate(anisotropic_interaction_type::create(interaction), u, _cache); } scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -71,7 +74,7 @@ struct SLambertianBase return forwardPdf(_sample, interaction.isotropic); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { sampling::quotient_and_pdf qp; NBL_IF_CONSTEXPR (IsBSDF) @@ -80,9 +83,9 @@ struct SLambertianBase qp = sampling::ProjectedHemisphere::template quotientAndPdf(_sample.getNdotL(_clamp)); return quotient_pdf_type::create(qp.quotient(), qp.pdf()); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotientAndWeight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic, _cache); } }; diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index 4b356a1ecd..137ab211cf 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -24,6 +24,9 @@ struct SOrenNayarBase BXDF_CONFIG_TYPE_ALIASES(Config); using random_type = conditional_t; + struct Cache {}; + using isocache_type = Cache; + using anisocache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; @@ -60,19 +63,19 @@ struct SOrenNayarBase return hlsl::promote(NdotL * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF) * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp))); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); return quotient_pdf_type::create(__eval(query, _sample, interaction), forwardPdf(_sample, interaction)); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return evalAndWeight(_sample, interaction.isotropic); + return evalAndWeight(_sample, interaction.isotropic, _cache); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { typename sampling::ProjectedHemisphere::cache_type cache; ray_dir_info_type L; @@ -80,7 +83,7 @@ struct SOrenNayarBase return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { typename sampling::ProjectedSphere::cache_type cache; vector3_type _u = u; @@ -88,9 +91,9 @@ struct SOrenNayarBase L.setDirection(sampling::ProjectedSphere::generate(_u, cache)); return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return generate(anisotropic_interaction_type::create(interaction), u); + return generate(anisotropic_interaction_type::create(interaction), u, _cache); } scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -112,15 +115,15 @@ struct SOrenNayarBase scalar_type q = __rec_pi_factored_out_wo_clamps(query.getVdotL(), _sample.getNdotL(_clamp), interaction.getNdotV(_clamp)); return quotient_pdf_type::create(q, _pdf); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); return __quotientAndWeight(query, _sample, interaction); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotientAndWeight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic, _cache); } scalar_type A2; diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index e9e103e203..494dcdd0c2 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -900,6 +900,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::scalar_type)) ((NBL_CONCEPT_REQ_TYPE)(T::anisotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE)(T::random_type)) @@ -907,147 +908,12 @@ NBL_CONCEPT_END( #undef bxdf #include -#define NBL_CONCEPT_NAME bxdf_common -#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -#define NBL_CONCEPT_TPLT_PRM_NAMES (T) -#define NBL_CONCEPT_PARAM_0 (bxdf, T) -#define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) -#define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) -NBL_CONCEPT_BEGIN(3) -#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -#define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -#define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) -); -#undef aniso -#undef _sample -#undef bxdf -#include - -#define NBL_CONCEPT_NAME iso_bxdf_common -#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -#define NBL_CONCEPT_TPLT_PRM_NAMES (T) -#define NBL_CONCEPT_PARAM_0 (bxdf, T) -#define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) -#define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) -NBL_CONCEPT_BEGIN(3) -#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -#define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -#define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) - ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) -); -#undef iso -#undef _sample -#undef bxdf -#include - template NBL_BOOL_CONCEPT VecDim2OrMore = vector_traits::Dimension >= 2; template NBL_BOOL_CONCEPT VecDim3OrMore = vector_traits::Dimension >= 3; -} - -#define NBL_CONCEPT_NAME BRDF -#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -#define NBL_CONCEPT_TPLT_PRM_NAMES (T) -#define NBL_CONCEPT_PARAM_0 (bxdf, T) -#define NBL_CONCEPT_PARAM_1 (aniso, typename T::anisotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) -NBL_CONCEPT_BEGIN(3) -#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -#define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -#define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::bxdf_common, T)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u)), ::nbl::hlsl::is_same_v, typename T::sample_type)) -); -#undef u -#undef aniso -#undef bxdf -#include -#define NBL_CONCEPT_NAME BSDF -#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -#define NBL_CONCEPT_TPLT_PRM_NAMES (T) -#define NBL_CONCEPT_PARAM_0 (bxdf, T) -#define NBL_CONCEPT_PARAM_1 (aniso, typename T::anisotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) -NBL_CONCEPT_BEGIN(3) -#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -#define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -#define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::bxdf_common, T)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u)), ::nbl::hlsl::is_same_v, typename T::sample_type)) -); -#undef u -#undef aniso -#undef bxdf -#include - -#define NBL_CONCEPT_NAME IsotropicBRDF -#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -#define NBL_CONCEPT_TPLT_PRM_NAMES (T) -#define NBL_CONCEPT_PARAM_0 (bxdf, T) -#define NBL_CONCEPT_PARAM_1 (iso, typename T::isotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) -NBL_CONCEPT_BEGIN(3) -#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -#define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -#define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_bxdf_common, T)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u)), ::nbl::hlsl::is_same_v, typename T::sample_type)) -); -#undef u -#undef iso -#undef bxdf -#include - -#define NBL_CONCEPT_NAME IsotropicBSDF -#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) -#define NBL_CONCEPT_TPLT_PRM_NAMES (T) -#define NBL_CONCEPT_PARAM_0 (bxdf, T) -#define NBL_CONCEPT_PARAM_1 (iso, typename T::isotropic_interaction_type) -#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) -NBL_CONCEPT_BEGIN(3) -#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 -#define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 -#define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_bxdf_common, T)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u)), ::nbl::hlsl::is_same_v, typename T::sample_type)) -); -#undef u -#undef iso -#undef bxdf -#include - -template -NBL_BOOL_CONCEPT BxDF = BRDF || BSDF; -template -NBL_BOOL_CONCEPT IsotropicBxDF = IsotropicBRDF || IsotropicBSDF; - - -namespace impl -{ -#define NBL_CONCEPT_NAME microfacet_bxdf_common +#define NBL_CONCEPT_NAME bxdf_common #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) @@ -1061,14 +927,12 @@ NBL_CONCEPT_BEGIN(4) #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) - ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) ); #undef anisocache #undef aniso @@ -1076,7 +940,7 @@ NBL_CONCEPT_END( #undef bxdf #include -#define NBL_CONCEPT_NAME iso_microfacet_bxdf_common +#define NBL_CONCEPT_NAME iso_bxdf_common #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) @@ -1089,14 +953,13 @@ NBL_CONCEPT_BEGIN(4) #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(CreatableIsotropicMicrofacetCache, typename T::isocache_type)) ); #undef isocache #undef iso @@ -1105,7 +968,7 @@ NBL_CONCEPT_END( #include } -#define NBL_CONCEPT_NAME MicrofacetBRDF +#define NBL_CONCEPT_NAME BRDF #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) @@ -1118,7 +981,7 @@ NBL_CONCEPT_BEGIN(4) #define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u,anisocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); @@ -1128,7 +991,7 @@ NBL_CONCEPT_END( #undef bxdf #include -#define NBL_CONCEPT_NAME MicrofacetBSDF +#define NBL_CONCEPT_NAME BSDF #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) @@ -1141,7 +1004,7 @@ NBL_CONCEPT_BEGIN(4) #define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u,anisocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); @@ -1151,7 +1014,7 @@ NBL_CONCEPT_END( #undef bxdf #include -#define NBL_CONCEPT_NAME IsotropicMicrofacetBRDF +#define NBL_CONCEPT_NAME IsotropicBRDF #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) @@ -1164,7 +1027,7 @@ NBL_CONCEPT_BEGIN(4) #define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u,isocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); @@ -1174,7 +1037,7 @@ NBL_CONCEPT_END( #undef bxdf #include -#define NBL_CONCEPT_NAME IsotropicMicrofacetBSDF +#define NBL_CONCEPT_NAME IsotropicBSDF #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) #define NBL_CONCEPT_PARAM_0 (bxdf, T) @@ -1187,7 +1050,7 @@ NBL_CONCEPT_BEGIN(4) #define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::iso_bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u,isocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ); @@ -1197,8 +1060,22 @@ NBL_CONCEPT_END( #undef bxdf #include +template +NBL_BOOL_CONCEPT BxDF = BRDF || BSDF; +template +NBL_BOOL_CONCEPT IsotropicBxDF = IsotropicBRDF || IsotropicBSDF; + +template +NBL_BOOL_CONCEPT MicrofacetBRDF = BRDF && AnisotropicMicrofacetCache; +template +NBL_BOOL_CONCEPT MicrofacetBSDF = BSDF && AnisotropicMicrofacetCache; template NBL_BOOL_CONCEPT MicrofacetBxDF = MicrofacetBRDF || MicrofacetBSDF; + +template +NBL_BOOL_CONCEPT IsotropicMicrofacetBRDF = IsotropicBRDF && AnisotropicMicrofacetCache && CreatableIsotropicMicrofacetCache; +template +NBL_BOOL_CONCEPT IsotropicMicrofacetBSDF = IsotropicBSDF && AnisotropicMicrofacetCache && CreatableIsotropicMicrofacetCache; template NBL_BOOL_CONCEPT IsotropicMicrofacetBxDF = IsotropicMicrofacetBRDF || IsotropicMicrofacetBSDF; } diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index 84c25fb4fb..c926096e59 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -24,19 +24,22 @@ struct SDeltaDistribution BXDF_CONFIG_TYPE_ALIASES(Config); using random_type = vector2_type; + struct Cache {}; + using isocache_type = Cache; + using anisocache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { vector3_type V = interaction.getV().getDirection(); bxdf::Reflect r = bxdf::Reflect::create(V, interaction.getN()); @@ -49,9 +52,9 @@ struct SDeltaDistribution return s; } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return generate(anisotropic_interaction_type::create(interaction), u); + return generate(anisotropic_interaction_type::create(interaction), u, _cache); } scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -63,14 +66,14 @@ struct SDeltaDistribution return 0; } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(1.0, _pdf); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotientAndWeight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic, _cache); } }; diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index 835b41a044..5666231e2d 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -24,19 +24,22 @@ struct SDeltaDistribution BXDF_CONFIG_TYPE_ALIASES(Config); using random_type = vector2_type; + struct Cache {}; + using isocache_type = Cache; + using anisocache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { ray_dir_info_type L = interaction.getV().transmit(); sample_type s = sample_type::create(L, interaction.getN()); @@ -46,9 +49,9 @@ struct SDeltaDistribution s.NdotL2 = interaction.getNdotV2(); return s; } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return generate(anisotropic_interaction_type::create(interaction), u); + return generate(anisotropic_interaction_type::create(interaction), u, _cache); } scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -60,12 +63,12 @@ struct SDeltaDistribution return 0; } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(1.0, _pdf); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotientAndWeight(_sample, interaction.isotropic); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index d3af6840ec..ad85be0c92 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -25,20 +25,23 @@ struct SSmoothDielectric BXDF_CONFIG_TYPE_ALIASES(Config); using random_type = vector3_type; + struct Cache {}; + using isocache_type = Cache; + using anisocache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; // eval and weight return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(random_type) u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(random_type) u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { const scalar_type reflectance = fresnel::Dielectric::__call(orientedEta.value*orientedEta.value, interaction.getNdotV(_clamp))[0]; @@ -54,9 +57,9 @@ struct SSmoothDielectric ray_dir_info_type L = V.reflectRefract(rr, transmitted, orientedEta.rcp[0]); return sample_type::create(L, interaction.getT(), interaction.getB(), interaction.getN()); } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_REF_ARG(random_type) u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_REF_ARG(random_type) u, NBL_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return generate(anisotropic_interaction_type::create(interaction), u); + return generate(anisotropic_interaction_type::create(interaction), u, _cache); } scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -69,13 +72,13 @@ struct SSmoothDielectric } // smooth BxDFs are isotropic by definition - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(1.0, bit_cast(numeric_limits::infinity)); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotientAndWeight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic, _cache); } fresnel::OrientedEtas orientedEta; @@ -88,6 +91,9 @@ struct SThinSmoothDielectric BXDF_CONFIG_TYPE_ALIASES(Config); using random_type = vector3_type; + struct Cache {}; + using isocache_type = Cache; + using anisocache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; @@ -100,11 +106,11 @@ struct SThinSmoothDielectric return retval; } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } @@ -135,14 +141,14 @@ struct SThinSmoothDielectric return sample_type::create(L, interaction.getT(), interaction.getB(), N); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { vector3_type dummy; return generate(interaction, u, dummy); } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u) NBL_CONST_MEMBER_FUNC + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return generate(anisotropic_interaction_type::create(interaction), u); + return generate(anisotropic_interaction_type::create(interaction), u, _cache); } scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC @@ -155,7 +161,7 @@ struct SThinSmoothDielectric } // smooth BxDFs are isotropic by definition - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { const bool transmitted = ComputeMicrofacetNormal::isTransmissionPath(interaction.getNdotV(), _sample.getNdotL()); const spectral_type reflectance = fresnel::thinDielectricInfiniteScatter(fresnel(interaction.getNdotV(_clamp))); @@ -166,9 +172,9 @@ struct SThinSmoothDielectric const scalar_type _pdf = bit_cast(numeric_limits::infinity); return quotient_pdf_type::create(sampleValue / sampleProb, _pdf); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotientAndWeight(_sample, interaction.isotropic); + return quotientAndWeight(_sample, interaction.isotropic, _cache); } fresnel::Dielectric fresnel; From dab4a18431ff9d319198dbf1253b064bd84fbfa1 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 24 Mar 2026 16:56:56 +0700 Subject: [PATCH 12/35] eval should have its own cache type in concepts --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 1 + .../builtin/hlsl/bxdf/base/lambertian.hlsl | 5 +++-- .../builtin/hlsl/bxdf/base/oren_nayar.hlsl | 5 +++-- include/nbl/builtin/hlsl/bxdf/common.hlsl | 20 ++++++++++++------- .../bxdf/reflection/delta_distribution.hlsl | 5 +++-- .../bxdf/transmission/delta_distribution.hlsl | 5 +++-- .../bxdf/transmission/smooth_dielectric.hlsl | 10 ++++++---- 7 files changed, 32 insertions(+), 19 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index f243d717ac..e9b3d0ee54 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -85,6 +85,7 @@ struct SCookTorrance NBL_CONSTEXPR_STATIC_INLINE bool IsBSDF = ndf_type::SupportedPaths != ndf::MTT_REFLECT; using random_type = conditional_t; NBL_HLSL_BXDF_ANISOTROPIC_COND_DECLS(IsAnisotropic); + using evalcache_type = conditional_t; // utility functions template, diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 3b3dd21e59..2d4ae956ff 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -27,15 +27,16 @@ struct SLambertianBase struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; + using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); return quotient_pdf_type::create(quo, forwardPdf(_sample, interaction)); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return evalAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index 137ab211cf..d6f2e6e6c8 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -27,6 +27,7 @@ struct SOrenNayarBase struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; + using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; @@ -63,13 +64,13 @@ struct SOrenNayarBase return hlsl::promote(NdotL * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF) * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp))); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); return quotient_pdf_type::create(__eval(query, _sample, interaction), forwardPdf(_sample, interaction)); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return evalAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 494dcdd0c2..bfe1bf7aa8 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -889,7 +889,6 @@ namespace bxdf_concepts { namespace impl { - #define NBL_CONCEPT_NAME bxdf_common_typdefs #define NBL_CONCEPT_TPLT_PRM_KINDS (typename) #define NBL_CONCEPT_TPLT_PRM_NAMES (T) @@ -901,6 +900,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::anisotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE)(T::random_type)) @@ -920,20 +920,23 @@ NBL_BOOL_CONCEPT VecDim3OrMore = vector_traits::Dimension >= 3; #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) #define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) #define NBL_CONCEPT_PARAM_3 (anisocache, typename T::anisocache_type) -NBL_CONCEPT_BEGIN(4) +#define NBL_CONCEPT_PARAM_4 (evalcache, typename T::evalcache_type) +NBL_CONCEPT_BEGIN(5) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_4 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, evalcache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) ); +#undef evalcache #undef anisocache #undef aniso #undef _sample @@ -947,20 +950,23 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) #define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) #define NBL_CONCEPT_PARAM_3 (isocache, typename T::isocache_type) -NBL_CONCEPT_BEGIN(4) +#define NBL_CONCEPT_PARAM_4 (evalcache, typename T::evalcache_type) +NBL_CONCEPT_BEGIN(5) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, evalcache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) ); +#undef evalcache #undef isocache #undef iso #undef _sample diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index c926096e59..07c75930e1 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -27,14 +27,15 @@ struct SDeltaDistribution struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; + using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index 5666231e2d..719d08dfcb 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -27,14 +27,15 @@ struct SDeltaDistribution struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; + using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index ad85be0c92..1835d4c1be 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -28,15 +28,16 @@ struct SSmoothDielectric struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; + using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; // eval and weight return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } @@ -94,6 +95,7 @@ struct SThinSmoothDielectric struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; + using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; @@ -106,11 +108,11 @@ struct SThinSmoothDielectric return retval; } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotient_pdf_type::create(0.0, 0.0); } From fb878a610b61dade047810f3f90d90910db7d621 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Wed, 25 Mar 2026 10:49:03 +0700 Subject: [PATCH 13/35] minor typo bug fixes --- include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl | 2 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 2d4ae956ff..e5948030e2 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -82,7 +82,7 @@ struct SLambertianBase qp = sampling::ProjectedSphere::template quotientAndPdf(_sample.getNdotL(_clamp)); else qp = sampling::ProjectedHemisphere::template quotientAndPdf(_sample.getNdotL(_clamp)); - return quotient_pdf_type::create(qp.quotient(), qp.pdf()); + return quotient_pdf_type::create(qp.quotient()[0], qp.pdf()); } quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index bfe1bf7aa8..cd548bf4e1 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -956,7 +956,7 @@ NBL_CONCEPT_BEGIN(5) #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 -#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_4 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) From 4171059716089ebcc93b54ac6419f60a03b90917 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Wed, 25 Mar 2026 14:44:38 +0700 Subject: [PATCH 14/35] eval returns a value_and_weight type, fixed some bugs in bxdf concept --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 14 +-- .../builtin/hlsl/bxdf/base/lambertian.hlsl | 6 +- .../builtin/hlsl/bxdf/base/oren_nayar.hlsl | 6 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 8 +- include/nbl/builtin/hlsl/bxdf/config.hlsl | 4 + .../bxdf/reflection/delta_distribution.hlsl | 8 +- .../bxdf/transmission/delta_distribution.hlsl | 8 +- .../bxdf/transmission/smooth_dielectric.hlsl | 16 ++-- .../builtin/hlsl/path_tracing/concepts.hlsl | 3 +- .../hlsl/path_tracing/unidirectional.hlsl | 9 +- .../hlsl/sampling/value_and_weight.hlsl | 91 +++++++++++++++++++ src/nbl/builtin/CMakeLists.txt | 1 + 12 files changed, 136 insertions(+), 38 deletions(-) create mode 100644 include/nbl/builtin/hlsl/sampling/value_and_weight.hlsl diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index e9b3d0ee54..f43e242efc 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -158,11 +158,11 @@ struct SCookTorrance template, class MicrofacetCache=conditional_t NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); if (!__checkValid(_f, _sample, interaction, cache)) - return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); + return value_weight_type::create(scalar_type(0.0), scalar_type(0.0)); bool isInfinity; scalar_type _pdf = __forwardPdf(_sample, interaction, cache, isInfinity); @@ -183,22 +183,22 @@ struct SCookTorrance // immediately return only after all calls setting DG // allows compiler to throw away calls to ndf.D if using __overwriteDG, before that we only avoid computation for G2(correlated) if (isInfinity) - return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); + return value_weight_type::create(scalar_type(0.0), scalar_type(0.0)); scalar_type clampedVdotH = cache.getVdotH(); NBL_IF_CONSTEXPR(IsBSDF) clampedVdotH = hlsl::abs(clampedVdotH); - spectral_type quo; + spectral_type eval; NBL_IF_CONSTEXPR(IsBSDF) { const spectral_type reflectance = impl::__implicit_promote::__call(_f(clampedVdotH)); - quo = hlsl::mix(reflectance, hlsl::promote(1.0) - reflectance, cache.isTransmission()) * DG; + eval = hlsl::mix(reflectance, hlsl::promote(1.0) - reflectance, cache.isTransmission()) * DG; } else - quo = impl::__implicit_promote::__call(_f(clampedVdotH)) * DG; + eval = impl::__implicit_promote::__call(_f(clampedVdotH)) * DG; - return quotient_pdf_type::create(quo, _pdf); + return value_weight_type::create(eval, _pdf); } sample_type __generate_common(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type localH, diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index e5948030e2..d79f191b60 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -31,12 +31,12 @@ struct SLambertianBase NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); - return quotient_pdf_type::create(quo, forwardPdf(_sample, interaction)); + return value_weight_type::create(quo, forwardPdf(_sample, interaction)); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return evalAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index d6f2e6e6c8..cea334a5e8 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -64,13 +64,13 @@ struct SOrenNayarBase return hlsl::promote(NdotL * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF) * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp))); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); - return quotient_pdf_type::create(__eval(query, _sample, interaction), forwardPdf(_sample, interaction)); + return value_weight_type::create(__eval(query, _sample, interaction), forwardPdf(_sample, interaction)); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { return evalAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index cd548bf4e1..42e2fd6058 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -15,6 +15,7 @@ #include "nbl/builtin/hlsl/cpp_compat/promote.hlsl" #include "nbl/builtin/hlsl/bxdf/fresnel.hlsl" #include "nbl/builtin/hlsl/sampling/quotient_and_pdf.hlsl" +#include "nbl/builtin/hlsl/sampling/value_and_weight.hlsl" #include "nbl/builtin/hlsl/vector_utils/vector_traits.hlsl" namespace nbl @@ -903,6 +904,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::value_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::random_type)) ); #undef bxdf @@ -929,8 +931,7 @@ NBL_CONCEPT_BEGIN(5) #define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_4 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, evalcache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) @@ -961,8 +962,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, evalcache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) ); diff --git a/include/nbl/builtin/hlsl/bxdf/config.hlsl b/include/nbl/builtin/hlsl/bxdf/config.hlsl index 0d49d45b3f..3141914242 100644 --- a/include/nbl/builtin/hlsl/bxdf/config.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/config.hlsl @@ -32,6 +32,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::value_weight_type)) ); #undef conf #include @@ -76,6 +77,7 @@ struct SConfiguration using sample_type = LS; using spectral_type = Spectrum; using quotient_pdf_type = sampling::quotient_and_pdf; + using value_weight_type = sampling::value_and_weight; }; #define CONF_ANISO LightSample && surface_interactions::Anisotropic && concepts::FloatingPointLikeVectorial @@ -98,6 +100,7 @@ struct SConfiguration using sample_type = LS; using spectral_type = Spectrum; using quotient_pdf_type = sampling::quotient_and_pdf; + using value_weight_type = sampling::value_and_weight; }; template @@ -150,6 +153,7 @@ NBL_BXDF_CONFIG_ALIAS(anisotropic_interaction_type, Config);\ NBL_BXDF_CONFIG_ALIAS(sample_type, Config);\ NBL_BXDF_CONFIG_ALIAS(spectral_type, Config);\ NBL_BXDF_CONFIG_ALIAS(quotient_pdf_type, Config);\ +NBL_BXDF_CONFIG_ALIAS(value_weight_type, Config);\ #define MICROFACET_BXDF_CONFIG_TYPE_ALIASES(Config) BXDF_CONFIG_TYPE_ALIASES(Config);\ NBL_BXDF_CONFIG_ALIAS(matrix3x3_type, Config);\ diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index 07c75930e1..7de8d56152 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -31,13 +31,13 @@ struct SDeltaDistribution NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(0.0, 0.0); + return value_weight_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(0.0, 0.0); + return value_weight_type::create(0.0, 0.0); } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index 719d08dfcb..f44e313b9c 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -31,13 +31,13 @@ struct SDeltaDistribution NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(0.0, 0.0); + return value_weight_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(0.0, 0.0); + return value_weight_type::create(0.0, 0.0); } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index 1835d4c1be..08f54950a1 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -33,13 +33,13 @@ struct SSmoothDielectric NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; // eval and weight return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(0.0, 0.0); + return value_weight_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(0.0, 0.0); + return value_weight_type::create(0.0, 0.0); } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(random_type) u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC @@ -108,13 +108,13 @@ struct SThinSmoothDielectric return retval; } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(0.0, 0.0); + return value_weight_type::create(0.0, 0.0); } - quotient_pdf_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(0.0, 0.0); + return value_weight_type::create(0.0, 0.0); } // usually `luminosityContributionHint` would be the Rec.709 luma coefficients (the Y row of the RGB to CIE XYZ matrix) diff --git a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl index 438f0391de..0ac5c9166a 100644 --- a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl @@ -176,13 +176,14 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::material_id_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::value_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::measure_type)) ((NBL_CONCEPT_REQ_TYPE)(T::anisotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::cache_type)) ((NBL_CONCEPT_REQ_TYPE)(T::bxdfnode_type)) ((NBL_CONCEPT_REQ_TYPE)(T::create_params_t)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(BxdfNode, typename T::bxdfnode_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.evalAndWeight(matid, _sample, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.evalAndWeight(matid, _sample, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.generate(matid, aniso_inter, u, cache_)), ::nbl::hlsl::is_same_v, typename T::sample_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.quotientAndWeight(matid, _sample, aniso_inter, cache_)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.getBxDFNode(matid, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::bxdfnode_type)) diff --git a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl index 1752e9c768..d75ebeae39 100644 --- a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl @@ -46,7 +46,8 @@ struct Unidirectional using bxdfnode_type = typename MaterialSystem::bxdfnode_type; using anisotropic_interaction_type = typename MaterialSystem::anisotropic_interaction_type; using cache_type = typename MaterialSystem::cache_type; - using quotient_pdf_type = typename NextEventEstimator::quotient_pdf_type; + using quotient_pdf_type = typename MaterialSystem::quotient_pdf_type; + using value_weight_type = typename MaterialSystem::value_weight_type; using tolerance_method_type = typename NextEventEstimator::tolerance_method_type; scalar_type getLuma(NBL_CONST_REF_ARG(vector3_type) col) @@ -108,11 +109,11 @@ struct Unidirectional // 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)) { - quotient_pdf_type bsdfContrib = materialSystem.evalAndWeight(matID, nee_sample, interaction); - neeContrib._quotient *= bsdfContrib.quotient() * rcpChoiceProb; + value_weight_type bsdfContrib = materialSystem.evalAndWeight(matID, nee_sample, interaction); + neeContrib._quotient *= bsdfContrib.value() * rcpChoiceProb; if (neeContrib.pdf() < bit_cast(numeric_limits::infinity)) { - const scalar_type otherGenOverLightAndChoice = bsdfContrib.pdf() * rcpChoiceProb / neeContrib.pdf(); + const scalar_type otherGenOverLightAndChoice = bsdfContrib.weight() * rcpChoiceProb / neeContrib.pdf(); neeContrib._quotient /= 1.f + otherGenOverLightAndChoice * otherGenOverLightAndChoice; // balance heuristic } diff --git a/include/nbl/builtin/hlsl/sampling/value_and_weight.hlsl b/include/nbl/builtin/hlsl/sampling/value_and_weight.hlsl new file mode 100644 index 0000000000..f1a9e2462a --- /dev/null +++ b/include/nbl/builtin/hlsl/sampling/value_and_weight.hlsl @@ -0,0 +1,91 @@ +// Copyright (C) 2018-2026 - DevSH Graphics Programming Sp. z O.O. +// This file is part of the "Nabla Engine". +// For conditions of distribution and use, see copyright notice in nabla.h + +#ifndef _NBL_BUILTIN_HLSL_SAMPLING_VALUE_AND_WEIGHT_INCLUDED_ +#define _NBL_BUILTIN_HLSL_SAMPLING_VALUE_AND_WEIGHT_INCLUDED_ + +#include "nbl/builtin/hlsl/sampling/value_and_pdf.hlsl" + +namespace nbl +{ +namespace hlsl +{ +namespace sampling +{ + +template +struct value_and_rcpWeight +{ + using this_t = value_and_rcpWeight; + using scalar_v = typename vector_traits::scalar_type; + + static this_t create(const V _value, const W _rcpWeight) + { + this_t retval; + retval._value = _value; + retval._rcpWeight = _rcpWeight; + return retval; + } + + static this_t create(const scalar_v _value, const W _rcpWeight) + { + this_t retval; + retval._value = hlsl::promote(_value); + retval._rcpWeight = _rcpWeight; + return retval; + } + + V value() { return _value; } + W rcpWeight() { return _rcpWeight; } + + V _value; + W _rcpWeight; +}; + +template +struct value_and_weight +{ + using this_t = value_and_weight; + using scalar_v = typename vector_traits::scalar_type; + + static this_t create(const V _value, const W _weight) + { + this_t retval; + retval._value = _value; + retval._weight = _weight; + return retval; + } + + static this_t create(const scalar_v _value, const W _weight) + { + this_t retval; + retval._value = hlsl::promote(_value); + retval._weight = _weight; + return retval; + } + + V value() { return _value; } + W weight() { return _weight; } + + V _value; + W _weight; +}; + +template +using codomain_and_rcpWeight = value_and_rcpWeight; + +template +using codomain_and_weight = value_and_weight; + +template +using domain_and_rcpWeight = value_and_rcpWeight; + +template +using domain_and_weight = value_and_weight; + +} // namespace sampling +} // namespace hlsl +} // namespace nbl + +#endif diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 839c5e3778..2057e56ba4 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -281,6 +281,7 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/spherical_rectangle. LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/cos_weighted_spheres.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/quotient_and_pdf.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/value_and_pdf.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/value_and_weight.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/concepts.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/uniform_spheres.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/alias_table.hlsl") From 0e16279073ad2e9d05137022c2292bd7269606f4 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Wed, 25 Mar 2026 15:06:45 +0700 Subject: [PATCH 15/35] made value_and_pdf compose from value_and_weight --- .../builtin/hlsl/sampling/value_and_pdf.hlsl | 26 ++++++++++--------- .../hlsl/sampling/value_and_weight.hlsl | 2 -- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/nbl/builtin/hlsl/sampling/value_and_pdf.hlsl b/include/nbl/builtin/hlsl/sampling/value_and_pdf.hlsl index a037c0e3d8..ac7e448295 100644 --- a/include/nbl/builtin/hlsl/sampling/value_and_pdf.hlsl +++ b/include/nbl/builtin/hlsl/sampling/value_and_pdf.hlsl @@ -5,6 +5,8 @@ #ifndef _NBL_BUILTIN_HLSL_SAMPLING_VALUE_AND_PDF_INCLUDED_ #define _NBL_BUILTIN_HLSL_SAMPLING_VALUE_AND_PDF_INCLUDED_ +#include "nbl/builtin/hlsl/sampling/value_and_weight.hlsl" + namespace nbl { namespace hlsl @@ -16,40 +18,40 @@ template struct value_and_rcpPdf { using this_t = value_and_rcpPdf; + using base_t = value_and_rcpWeight; static this_t create(const V _value, const P _rcpPdf) { this_t retval; - retval._value = _value; - retval._rcpPdf = _rcpPdf; + retval._base._value = _value; + retval._base._rcpWeight = _rcpPdf; return retval; } - V value() { return _value; } - P rcpPdf() { return _rcpPdf; } + V value() { return _base._value; } + P rcpPdf() { return _base._rcpWeight; } - V _value; - P _rcpPdf; + base_t _base; }; template struct value_and_pdf { using this_t = value_and_pdf; + using base_t = value_and_weight; static this_t create(const V _value, const P _pdf) { this_t retval; - retval._value = _value; - retval._pdf = _pdf; + retval._base._value = _value; + retval._base._weight = _pdf; return retval; } - V value() { return _value; } - P pdf() { return _pdf; } + V value() { return _base._value; } + P pdf() { return _base._weight; } - V _value; - P _pdf; + base_t _base; }; // Returned by TractableSampler::generate, codomain sample bundled with its rcpPdf diff --git a/include/nbl/builtin/hlsl/sampling/value_and_weight.hlsl b/include/nbl/builtin/hlsl/sampling/value_and_weight.hlsl index f1a9e2462a..19711174c5 100644 --- a/include/nbl/builtin/hlsl/sampling/value_and_weight.hlsl +++ b/include/nbl/builtin/hlsl/sampling/value_and_weight.hlsl @@ -5,8 +5,6 @@ #ifndef _NBL_BUILTIN_HLSL_SAMPLING_VALUE_AND_WEIGHT_INCLUDED_ #define _NBL_BUILTIN_HLSL_SAMPLING_VALUE_AND_WEIGHT_INCLUDED_ -#include "nbl/builtin/hlsl/sampling/value_and_pdf.hlsl" - namespace nbl { namespace hlsl From 345865f6537182c873ed2933be61fd5429f17e71 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Wed, 25 Mar 2026 16:34:56 +0700 Subject: [PATCH 16/35] reuse quant query and other stuff from forwardPdf in quotient and eval methods --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 105 ++++++++++-------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index f43e242efc..7626d1d3ba 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -87,6 +87,16 @@ struct SCookTorrance NBL_HLSL_BXDF_ANISOTROPIC_COND_DECLS(IsAnisotropic); using evalcache_type = conditional_t; + struct PdfQuery + { + scalar_type pdf; + fresnel_type orientedFresnel; + typename ndf_type::quant_query_type quantQuery; + + spectral_type reflectance; + scalar_type scaled_reflectance; + }; + // utility functions template, class MicrofacetCache=conditional_t @@ -160,19 +170,20 @@ struct SCookTorrance NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { - fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); - if (!__checkValid(_f, _sample, interaction, cache)) + PdfQuery pdfQuery = __forwardPdf(_sample, interaction, cache); + scalar_type _pdf = pdfQuery.pdf; + if (_pdf == scalar_type(0.0)) return value_weight_type::create(scalar_type(0.0), scalar_type(0.0)); - bool isInfinity; - scalar_type _pdf = __forwardPdf(_sample, interaction, cache, isInfinity); + fresnel_type _f = pdfQuery.orientedFresnel; using quant_query_type = typename ndf_type::quant_query_type; - quant_query_type qq = impl::quant_query_helper::template __call(ndf, _f, interaction, cache); + quant_query_type qq = pdfQuery.quantQuery; using g2g1_query_type = typename ndf_type::g2g1_query_type; g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); + bool isInfinity; quant_type D = ndf.template D(qq, _sample, interaction, cache, isInfinity); scalar_type DG = D.projectedLightMeasure; if (!isInfinity) @@ -347,41 +358,48 @@ struct SCookTorrance return s; } - template - scalar_type __forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC + template + PdfQuery __forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { - using quant_query_type = typename ndf_type::quant_query_type; - using dg1_query_type = typename ndf_type::dg1_query_type; + PdfQuery query; + query.pdf = scalar_type(0.0); + query.orientedFresnel = __getOrientedFresnel(fresnel, interaction.getNdotV()); + const bool cacheIsValid = __checkValid(query.orientedFresnel, _sample, interaction, cache); + assert(!FromGenerator || cacheIsValid); + const bool isValid = FromGenerator ? _sample.isValid() : cacheIsValid; // when from generator, expect the generated sample to always be valid, different checks for brdf and btdf + + if (isValid) + { + using dg1_query_type = typename ndf_type::dg1_query_type; + dg1_query_type dq = ndf.template createDG1Query(interaction, cache); - dg1_query_type dq = ndf.template createDG1Query(interaction, cache); + bool isInfinity; + query.quantQuery = impl::quant_query_helper::template __call(ndf, query.orientedFresnel, interaction, cache); + quant_type DG1 = ndf.template DG1(dq, query.quantQuery, _sample, interaction, isInfinity); - fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); - quant_query_type qq = impl::quant_query_helper::template __call(ndf, _f, interaction, cache); - quant_type DG1 = ndf.template DG1(dq, qq, _sample, interaction, isInfinity); + if (isInfinity) + return query; - NBL_IF_CONSTEXPR(IsBSDF) - { - spectral_type dummy; - const scalar_type reflectance = __getScaledReflectance(_f, interaction, hlsl::abs(cache.getVdotH()), cache.isTransmission(), dummy); - return reflectance * DG1.projectedLightMeasure; - } - else - { - return DG1.projectedLightMeasure; + NBL_IF_CONSTEXPR(IsBSDF) + { + query.scaled_reflectance = __getScaledReflectance(query.orientedFresnel, interaction, hlsl::abs(cache.getVdotH()), cache.isTransmission(), query.reflectance); + query.pdf = query.scaled_reflectance * DG1.projectedLightMeasure; + } + else + { + query.pdf = DG1.projectedLightMeasure; + } } + + return query; } template, class MicrofacetCache=conditional_t NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) scalar_type forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { - fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); - if (!__checkValid(_f, _sample, interaction, cache)) - return scalar_type(0.0); - - bool isInfinity; - scalar_type _pdf = __forwardPdf(_sample, interaction, cache, isInfinity); - return hlsl::mix(_pdf, scalar_type(0.0), isInfinity); + PdfQuery query = __forwardPdf(_sample, interaction, cache); + return query.pdf; } template, @@ -389,23 +407,16 @@ struct SCookTorrance NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { - if (!_sample.isValid()) - return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); // set pdf=0 when quo=0 because we don't want to give high weight to sampling strategy that yields 0 contribution - - bool isInfinity; - scalar_type _pdf = __forwardPdf(_sample, interaction, cache, isInfinity); - fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); + PdfQuery pdfQuery = __forwardPdf(_sample, interaction, cache); + scalar_type _pdf = pdfQuery.pdf; + if (_pdf == scalar_type(0.0)) + return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); - const bool valid = __checkValid(_f, _sample, interaction, cache); - assert(valid); // expect the generated sample to always be valid, different checks for brdf and btdf + fresnel_type _f = pdfQuery.orientedFresnel; - scalar_type G2_over_G1 = scalar_type(1.0); - if (!isInfinity) - { - using g2g1_query_type = typename N::g2g1_query_type; - g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); - G2_over_G1 = ndf.template G2_over_G1(gq, _sample, interaction, cache); - } + using g2g1_query_type = typename N::g2g1_query_type; + g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); + scalar_type G2_over_G1 = ndf.template G2_over_G1(gq, _sample, interaction, cache); spectral_type quo; NBL_IF_CONSTEXPR(IsBSDF) @@ -413,11 +424,7 @@ struct SCookTorrance NBL_IF_CONSTEXPR(fresnel_type::ReturnsMonochrome) quo = hlsl::promote(G2_over_G1); else - { - spectral_type reflectance; - const scalar_type scaled_reflectance = __getScaledReflectance(_f, interaction, hlsl::abs(cache.getVdotH()), cache.isTransmission(), reflectance); - quo = reflectance / scaled_reflectance * G2_over_G1; - } + quo = pdfQuery.reflectance / pdfQuery.scaled_reflectance * G2_over_G1; } else { From a98cd4512471a8d825ce242178aa9a127e0130d7 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Wed, 25 Mar 2026 17:05:03 +0700 Subject: [PATCH 17/35] reuse reflectance from forwardpdf in eval --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 7626d1d3ba..9d86777222 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -155,7 +155,9 @@ struct SCookTorrance static scalar_type __getScaledReflectance(NBL_CONST_REF_ARG(fresnel_type) orientedFresnel, NBL_CONST_REF_ARG(Interaction) interaction, scalar_type clampedVdotH, bool transmitted, NBL_REF_ARG(spectral_type) outFresnelVal) { scalar_type reflectance = orientedFresnel(clampedVdotH)[0]; - return hlsl::mix(reflectance, scalar_type(1.0)-reflectance, transmitted); + reflectance = hlsl::mix(reflectance, scalar_type(1.0)-reflectance, transmitted); + outFresnelVal = hlsl::promote(reflectance); + return reflectance; } bool __dotIsValue(const vector3_type a, const vector3_type b, const scalar_type value) NBL_CONST_MEMBER_FUNC @@ -202,12 +204,10 @@ struct SCookTorrance spectral_type eval; NBL_IF_CONSTEXPR(IsBSDF) - { - const spectral_type reflectance = impl::__implicit_promote::__call(_f(clampedVdotH)); - eval = hlsl::mix(reflectance, hlsl::promote(1.0) - reflectance, cache.isTransmission()) * DG; - } + eval = pdfQuery.reflectance; else - eval = impl::__implicit_promote::__call(_f(clampedVdotH)) * DG; + eval = impl::__implicit_promote::__call(_f(clampedVdotH)); + eval *= DG; return value_weight_type::create(eval, _pdf); } @@ -378,7 +378,10 @@ struct SCookTorrance quant_type DG1 = ndf.template DG1(dq, query.quantQuery, _sample, interaction, isInfinity); if (isInfinity) + { + query.pdf = bit_cast(numeric_limits::infinity); return query; + } NBL_IF_CONSTEXPR(IsBSDF) { From d0ed7d3855c39d52d0fb99d31edec414552682ab Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 26 Mar 2026 10:41:48 +0700 Subject: [PATCH 18/35] renamed quotient_pdf type to quotient_weight type --- .../builtin/hlsl/bxdf/base/cook_torrance_base.hlsl | 6 +++--- include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl | 6 +++--- include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl | 8 ++++---- include/nbl/builtin/hlsl/bxdf/common.hlsl | 6 +++--- include/nbl/builtin/hlsl/bxdf/config.hlsl | 8 ++++---- .../hlsl/bxdf/reflection/delta_distribution.hlsl | 6 +++--- .../hlsl/bxdf/transmission/delta_distribution.hlsl | 6 +++--- .../hlsl/bxdf/transmission/smooth_dielectric.hlsl | 12 ++++++------ include/nbl/builtin/hlsl/path_tracing/concepts.hlsl | 10 +++++----- .../builtin/hlsl/path_tracing/unidirectional.hlsl | 6 +++--- 10 files changed, 37 insertions(+), 37 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 9d86777222..47e9ea90ca 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -408,12 +408,12 @@ struct SCookTorrance template, class MicrofacetCache=conditional_t NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { PdfQuery pdfQuery = __forwardPdf(_sample, interaction, cache); scalar_type _pdf = pdfQuery.pdf; if (_pdf == scalar_type(0.0)) - return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); + return quotient_weight_type::create(scalar_type(0.0), scalar_type(0.0)); fresnel_type _f = pdfQuery.orientedFresnel; @@ -436,7 +436,7 @@ struct SCookTorrance quo = _f(VdotH) * G2_over_G1; } - return quotient_pdf_type::create(quo, _pdf); + return quotient_weight_type::create(quo, _pdf); } ndf_type ndf; diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index d79f191b60..f2ba2e259a 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -75,16 +75,16 @@ struct SLambertianBase return forwardPdf(_sample, interaction.isotropic); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { sampling::quotient_and_pdf qp; NBL_IF_CONSTEXPR (IsBSDF) qp = sampling::ProjectedSphere::template quotientAndPdf(_sample.getNdotL(_clamp)); else qp = sampling::ProjectedHemisphere::template quotientAndPdf(_sample.getNdotL(_clamp)); - return quotient_pdf_type::create(qp.quotient()[0], qp.pdf()); + return quotient_weight_type::create(qp.quotient()[0], qp.pdf()); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotientAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index cea334a5e8..f4a036ce98 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -110,19 +110,19 @@ struct SOrenNayarBase } template - quotient_pdf_type __quotientAndWeight(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + quotient_weight_type __quotientAndWeight(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { scalar_type _pdf = forwardPdf(_sample, interaction); scalar_type q = __rec_pi_factored_out_wo_clamps(query.getVdotL(), _sample.getNdotL(_clamp), interaction.getNdotV(_clamp)); - return quotient_pdf_type::create(q, _pdf); + return quotient_weight_type::create(q, _pdf); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); return __quotientAndWeight(query, _sample, interaction); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotientAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 42e2fd6058..628c153848 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -903,7 +903,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) - ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::value_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::random_type)) ); @@ -932,7 +932,7 @@ NBL_CONCEPT_BEGIN(5) NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) @@ -963,7 +963,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) ); #undef evalcache diff --git a/include/nbl/builtin/hlsl/bxdf/config.hlsl b/include/nbl/builtin/hlsl/bxdf/config.hlsl index 3141914242..25ddf20881 100644 --- a/include/nbl/builtin/hlsl/bxdf/config.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/config.hlsl @@ -31,7 +31,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::anisotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) - ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::value_weight_type)) ); #undef conf @@ -76,7 +76,7 @@ struct SConfiguration using anisotropic_interaction_type = surface_interactions::SAnisotropic; using sample_type = LS; using spectral_type = Spectrum; - using quotient_pdf_type = sampling::quotient_and_pdf; + using quotient_weight_type = sampling::quotient_and_pdf; using value_weight_type = sampling::value_and_weight; }; @@ -99,7 +99,7 @@ struct SConfiguration using anisotropic_interaction_type = Interaction; using sample_type = LS; using spectral_type = Spectrum; - using quotient_pdf_type = sampling::quotient_and_pdf; + using quotient_weight_type = sampling::quotient_and_pdf; using value_weight_type = sampling::value_and_weight; }; @@ -152,7 +152,7 @@ NBL_BXDF_CONFIG_ALIAS(isotropic_interaction_type, Config);\ NBL_BXDF_CONFIG_ALIAS(anisotropic_interaction_type, Config);\ NBL_BXDF_CONFIG_ALIAS(sample_type, Config);\ NBL_BXDF_CONFIG_ALIAS(spectral_type, Config);\ -NBL_BXDF_CONFIG_ALIAS(quotient_pdf_type, Config);\ +NBL_BXDF_CONFIG_ALIAS(quotient_weight_type, Config);\ NBL_BXDF_CONFIG_ALIAS(value_weight_type, Config);\ #define MICROFACET_BXDF_CONFIG_TYPE_ALIASES(Config) BXDF_CONFIG_TYPE_ALIASES(Config);\ diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index 7de8d56152..eb9bbb6943 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -67,12 +67,12 @@ struct SDeltaDistribution return 0; } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { const scalar_type _pdf = bit_cast(numeric_limits::infinity); - return quotient_pdf_type::create(1.0, _pdf); + return quotient_weight_type::create(1.0, _pdf); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotientAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index f44e313b9c..600405a533 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -64,12 +64,12 @@ struct SDeltaDistribution return 0; } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { const scalar_type _pdf = bit_cast(numeric_limits::infinity); - return quotient_pdf_type::create(1.0, _pdf); + return quotient_weight_type::create(1.0, _pdf); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotientAndWeight(_sample, interaction.isotropic); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index 08f54950a1..d04c4cd821 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -73,11 +73,11 @@ struct SSmoothDielectric } // smooth BxDFs are isotropic by definition - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return quotient_pdf_type::create(1.0, bit_cast(numeric_limits::infinity)); + return quotient_weight_type::create(1.0, bit_cast(numeric_limits::infinity)); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotientAndWeight(_sample, interaction.isotropic, _cache); } @@ -163,7 +163,7 @@ struct SThinSmoothDielectric } // smooth BxDFs are isotropic by definition - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { const bool transmitted = ComputeMicrofacetNormal::isTransmissionPath(interaction.getNdotV(), _sample.getNdotL()); const spectral_type reflectance = fresnel::thinDielectricInfiniteScatter(fresnel(interaction.getNdotV(_clamp))); @@ -172,9 +172,9 @@ struct SThinSmoothDielectric const scalar_type sampleProb = nbl::hlsl::dot(sampleValue,interaction.getLuminosityContributionHint()); const scalar_type _pdf = bit_cast(numeric_limits::infinity); - return quotient_pdf_type::create(sampleValue / sampleProb, _pdf); + return quotient_weight_type::create(sampleValue / sampleProb, _pdf); } - quotient_pdf_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return quotientAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl index 0ac5c9166a..94cc51490d 100644 --- a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl @@ -175,7 +175,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::vector3_type)) ((NBL_CONCEPT_REQ_TYPE)(T::material_id_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) - ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::value_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::measure_type)) ((NBL_CONCEPT_REQ_TYPE)(T::anisotropic_interaction_type)) @@ -185,7 +185,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(BxdfNode, typename T::bxdfnode_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.evalAndWeight(matid, _sample, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.generate(matid, aniso_inter, u, cache_)), ::nbl::hlsl::is_same_v, typename T::sample_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.quotientAndWeight(matid, _sample, aniso_inter, cache_)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.quotientAndWeight(matid, _sample, aniso_inter, cache_)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.getBxDFNode(matid, aniso_inter)), ::nbl::hlsl::is_same_v, typename T::bxdfnode_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.hasEmission(matid)), ::nbl::hlsl::is_same_v, bool)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((matsys.setMonochromeEta(matid, cie_y)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) @@ -216,10 +216,10 @@ NBL_CONCEPT_BEGIN(1) NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::scalar_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) - ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::object_handle_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getSample()), ::nbl::hlsl::is_same_v, typename T::sample_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getQuotientPdf()), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getQuotientPdf()), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getT()), ::nbl::hlsl::is_same_v, typename T::scalar_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getLightObjectID()), ::nbl::hlsl::is_same_v, typename T::object_handle_type)) ); @@ -253,7 +253,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::ray_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) - ((NBL_CONCEPT_REQ_TYPE)(T::quotient_pdf_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_quotient_return_type)) ((NBL_CONCEPT_REQ_TYPE)(T::tolerance_method_type)) diff --git a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl index d75ebeae39..33a906fff7 100644 --- a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl @@ -46,7 +46,7 @@ struct Unidirectional using bxdfnode_type = typename MaterialSystem::bxdfnode_type; using anisotropic_interaction_type = typename MaterialSystem::anisotropic_interaction_type; using cache_type = typename MaterialSystem::cache_type; - using quotient_pdf_type = typename MaterialSystem::quotient_pdf_type; + using quotient_weight_type = typename MaterialSystem::quotient_weight_type; using value_weight_type = typename MaterialSystem::value_weight_type; using tolerance_method_type = typename NextEventEstimator::tolerance_method_type; @@ -101,7 +101,7 @@ struct Unidirectional ); scalar_type t = ret.getT(); sample_type nee_sample = ret.getSample(); - quotient_pdf_type neeContrib = ret.getQuotientPdf(); + quotient_weight_type neeContrib = ret.getQuotientPdf(); // While NEE or other generators are not supposed to pick up Delta lobes by accident, we need the MIS weights to add up to 1 for the non-delta lobes. // So we need to weigh the Delta lobes as if the MIS weight is always 1, but other areas regularly. @@ -141,7 +141,7 @@ struct Unidirectional return false; // the value of the bsdf divided by the probability of the sample being generated - quotient_pdf_type bsdf_quotient_weight = materialSystem.quotientAndWeight(matID, bsdf_sample, interaction, _cache); + quotient_weight_type bsdf_quotient_weight = materialSystem.quotientAndWeight(matID, bsdf_sample, interaction, _cache); throughput *= bsdf_quotient_weight.quotient(); bxdfPdf = bsdf_quotient_weight.pdf(); bxdfSample = bsdf_sample.getL().getDirection(); From 110547a6143c825034299b21b84bb1ce5f3d8821 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 26 Mar 2026 11:46:36 +0700 Subject: [PATCH 19/35] minor fixes to cook torrance, removed redundant functions --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 34 ++----------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 47e9ea90ca..328dc8e549 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -20,27 +20,6 @@ namespace bxdf namespace impl { -template -struct __implicit_promote; - -template -struct __implicit_promote -{ - static T __call(const T v) - { - return v; - } -}; - -template -struct __implicit_promote::scalar_type, 1> > -{ - static T __call(const vector::scalar_type, 1> v) - { - return hlsl::promote(v[0]); - } -}; - template struct quant_query_helper; @@ -197,16 +176,12 @@ struct SCookTorrance // allows compiler to throw away calls to ndf.D if using __overwriteDG, before that we only avoid computation for G2(correlated) if (isInfinity) return value_weight_type::create(scalar_type(0.0), scalar_type(0.0)); - - scalar_type clampedVdotH = cache.getVdotH(); - NBL_IF_CONSTEXPR(IsBSDF) - clampedVdotH = hlsl::abs(clampedVdotH); spectral_type eval; NBL_IF_CONSTEXPR(IsBSDF) eval = pdfQuery.reflectance; else - eval = impl::__implicit_promote::__call(_f(clampedVdotH)); + eval = _f(cache.getVdotH()); eval *= DG; return value_weight_type::create(eval, _pdf); @@ -383,14 +358,11 @@ struct SCookTorrance return query; } + query.pdf = DG1.projectedLightMeasure; NBL_IF_CONSTEXPR(IsBSDF) { query.scaled_reflectance = __getScaledReflectance(query.orientedFresnel, interaction, hlsl::abs(cache.getVdotH()), cache.isTransmission(), query.reflectance); - query.pdf = query.scaled_reflectance * DG1.projectedLightMeasure; - } - else - { - query.pdf = DG1.projectedLightMeasure; + query.pdf *= query.scaled_reflectance; } } From ef9156ee7302b0647ae202ae40e3f5c00580760d Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 26 Mar 2026 15:04:12 +0700 Subject: [PATCH 20/35] only microfacet bxdfs need eval cache type, allow for overload with existing cache type too --- .../builtin/hlsl/bxdf/base/lambertian.hlsl | 5 +- .../builtin/hlsl/bxdf/base/oren_nayar.hlsl | 5 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 165 +++++++++++++++--- .../bxdf/reflection/delta_distribution.hlsl | 5 +- .../bxdf/transmission/delta_distribution.hlsl | 5 +- .../bxdf/transmission/smooth_dielectric.hlsl | 10 +- 6 files changed, 157 insertions(+), 38 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index f2ba2e259a..39e24c3ac2 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -27,16 +27,15 @@ struct SLambertianBase struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; - using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); return value_weight_type::create(quo, forwardPdf(_sample, interaction)); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return evalAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index f4a036ce98..0ea8c95584 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -27,7 +27,6 @@ struct SOrenNayarBase struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; - using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; @@ -64,13 +63,13 @@ struct SOrenNayarBase return hlsl::promote(NdotL * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF) * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp))); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); return value_weight_type::create(__eval(query, _sample, interaction), forwardPdf(_sample, interaction)); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return evalAndWeight(_sample, interaction.isotropic, _cache); } diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 628c153848..d2d557d2b0 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -901,7 +901,6 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::anisotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) - ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) ((NBL_CONCEPT_REQ_TYPE)(T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE)(T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::value_weight_type)) @@ -922,22 +921,19 @@ NBL_BOOL_CONCEPT VecDim3OrMore = vector_traits::Dimension >= 3; #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) #define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) #define NBL_CONCEPT_PARAM_3 (anisocache, typename T::anisocache_type) -#define NBL_CONCEPT_PARAM_4 (evalcache, typename T::evalcache_type) -NBL_CONCEPT_BEGIN(5) +NBL_CONCEPT_BEGIN(4) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 -#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_4 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Anisotropic, typename T::anisotropic_interaction_type)) ); -#undef evalcache #undef anisocache #undef aniso #undef _sample @@ -951,27 +947,73 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) #define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) #define NBL_CONCEPT_PARAM_3 (isocache, typename T::isocache_type) -#define NBL_CONCEPT_PARAM_4 (evalcache, typename T::evalcache_type) -NBL_CONCEPT_BEGIN(5) +NBL_CONCEPT_BEGIN(4) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 -#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_4 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) ); -#undef evalcache #undef isocache #undef iso #undef _sample #undef bxdf #include + +#define NBL_CONCEPT_NAME microfacet_bxdf_common +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (T) +#define NBL_CONCEPT_PARAM_0 (bxdf, T) +#define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) +#define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) +#define NBL_CONCEPT_PARAM_3 (evalcache, typename T::evalcache_type) +NBL_CONCEPT_BEGIN(4) +#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +#define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +#define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) +); +#undef evalcache +#undef aniso +#undef _sample +#undef bxdf +#include + +#define NBL_CONCEPT_NAME microfacet_iso_bxdf_common +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (T) +#define NBL_CONCEPT_PARAM_0 (bxdf, T) +#define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) +#define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) +#define NBL_CONCEPT_PARAM_3 (evalcache, typename T::evalcache_type) +NBL_CONCEPT_BEGIN(4) +#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +#define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +#define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(iso_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(CreatableIsotropicMicrofacetCache, typename T::isocache_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) +); +#undef evalcache +#undef iso +#undef _sample +#undef bxdf +#include } #define NBL_CONCEPT_NAME BRDF @@ -1071,17 +1113,100 @@ NBL_BOOL_CONCEPT BxDF = BRDF || BSDF; template NBL_BOOL_CONCEPT IsotropicBxDF = IsotropicBRDF || IsotropicBSDF; -template -NBL_BOOL_CONCEPT MicrofacetBRDF = BRDF && AnisotropicMicrofacetCache; -template -NBL_BOOL_CONCEPT MicrofacetBSDF = BSDF && AnisotropicMicrofacetCache; -template -NBL_BOOL_CONCEPT MicrofacetBxDF = MicrofacetBRDF || MicrofacetBSDF; +#define NBL_CONCEPT_NAME MicrofacetBRDF +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (T) +#define NBL_CONCEPT_PARAM_0 (bxdf, T) +#define NBL_CONCEPT_PARAM_1 (aniso, typename T::anisotropic_interaction_type) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) +#define NBL_CONCEPT_PARAM_3 (anisocache, typename T::anisocache_type) +NBL_CONCEPT_BEGIN(4) +#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +#define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +#define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +#define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u,anisocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) +); +#undef anisocache +#undef u +#undef aniso +#undef bxdf +#include + +#define NBL_CONCEPT_NAME MicrofacetBSDF +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (T) +#define NBL_CONCEPT_PARAM_0 (bxdf, T) +#define NBL_CONCEPT_PARAM_1 (aniso, typename T::anisotropic_interaction_type) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) +#define NBL_CONCEPT_PARAM_3 (anisocache, typename T::anisocache_type) +NBL_CONCEPT_BEGIN(4) +#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +#define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +#define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +#define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::microfacet_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(aniso,u,anisocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) +); +#undef anisocache +#undef u +#undef aniso +#undef bxdf +#include + +#define NBL_CONCEPT_NAME IsotropicMicrofacetBRDF +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (T) +#define NBL_CONCEPT_PARAM_0 (bxdf, T) +#define NBL_CONCEPT_PARAM_1 (iso, typename T::isotropic_interaction_type) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) +#define NBL_CONCEPT_PARAM_3 (isocache, typename T::isocache_type) +NBL_CONCEPT_BEGIN(4) +#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +#define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +#define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +#define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::microfacet_iso_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim2OrMore, typename T::random_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u,isocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) +); +#undef isocache +#undef u +#undef iso +#undef bxdf +#include + +#define NBL_CONCEPT_NAME IsotropicMicrofacetBSDF +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (T) +#define NBL_CONCEPT_PARAM_0 (bxdf, T) +#define NBL_CONCEPT_PARAM_1 (iso, typename T::isotropic_interaction_type) +#define NBL_CONCEPT_PARAM_2 (u, typename T::random_type) +#define NBL_CONCEPT_PARAM_3 (isocache, typename T::isocache_type) +NBL_CONCEPT_BEGIN(4) +#define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +#define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +#define u NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 +#define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::microfacet_iso_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(impl::VecDim3OrMore, typename T::random_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.generate(iso,u,isocache)), ::nbl::hlsl::is_same_v, typename T::sample_type)) +); +#undef isocache +#undef u +#undef iso +#undef bxdf +#include template -NBL_BOOL_CONCEPT IsotropicMicrofacetBRDF = IsotropicBRDF && AnisotropicMicrofacetCache && CreatableIsotropicMicrofacetCache; -template -NBL_BOOL_CONCEPT IsotropicMicrofacetBSDF = IsotropicBSDF && AnisotropicMicrofacetCache && CreatableIsotropicMicrofacetCache; +NBL_BOOL_CONCEPT MicrofacetBxDF = MicrofacetBRDF || MicrofacetBSDF; template NBL_BOOL_CONCEPT IsotropicMicrofacetBxDF = IsotropicMicrofacetBRDF || IsotropicMicrofacetBSDF; } diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index eb9bbb6943..cfebabd5fb 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -27,15 +27,14 @@ struct SDeltaDistribution struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; - using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index 600405a533..d1b221560e 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -27,15 +27,14 @@ struct SDeltaDistribution struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; - using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index d04c4cd821..673bc42472 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -28,16 +28,15 @@ struct SSmoothDielectric struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; - using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; // eval and weight return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); } @@ -95,7 +94,6 @@ struct SThinSmoothDielectric struct Cache {}; using isocache_type = Cache; using anisocache_type = Cache; - using evalcache_type = Cache; NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; @@ -108,11 +106,11 @@ struct SThinSmoothDielectric return retval; } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(evalcache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); } From 05124c2eb2cf8f525120bef75d4e0808514545a8 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 26 Mar 2026 15:08:39 +0700 Subject: [PATCH 21/35] latest example --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index ebb025be79..789a88c514 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit ebb025be792c6dcd37855526180a9dcf8119322e +Subproject commit 789a88c51453b4719473ec80c5af5f4611236c92 From bea47804dd8f84fd56ae8ebd31820f0597bc56be Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 27 Mar 2026 11:55:47 +0700 Subject: [PATCH 22/35] minor changes to concepts, microfacet bxdfs have eval that autogenerates cache --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 27 ++++++++++++++++++- include/nbl/builtin/hlsl/bxdf/common.hlsl | 22 ++++++++------- .../builtin/hlsl/path_tracing/concepts.hlsl | 2 +- .../hlsl/path_tracing/unidirectional.hlsl | 2 +- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 328dc8e549..05e632177b 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -64,7 +64,7 @@ struct SCookTorrance NBL_CONSTEXPR_STATIC_INLINE bool IsBSDF = ndf_type::SupportedPaths != ndf::MTT_REFLECT; using random_type = conditional_t; NBL_HLSL_BXDF_ANISOTROPIC_COND_DECLS(IsAnisotropic); - using evalcache_type = conditional_t; + using cache_type = conditional_t; struct PdfQuery { @@ -145,6 +145,20 @@ struct SCookTorrance return hlsl::max(ab, value / ab) <= scalar_type(value + 1e-3); } + template, + typename C=bool_constant NBL_FUNC_REQUIRES(C::value && !fresnel_type::ReturnsMonochrome) + static scalar_type __getMonochromeEta(NBL_CONST_REF_ARG(fresnel_type) fresnel, NBL_CONST_REF_ARG(Interaction) interaction) + { + spectral_type throughputWeights = interaction.getLuminosityContributionHint(); + return hlsl::dot(fresnel.eta, throughputWeights) / (throughputWeights.r + throughputWeights.g + throughputWeights.b); + } + template, + typename C=bool_constant NBL_FUNC_REQUIRES(C::value && fresnel_type::ReturnsMonochrome) + static scalar_type __getMonochromeEta(NBL_CONST_REF_ARG(fresnel_type) fresnel, NBL_CONST_REF_ARG(Interaction) interaction) + { + return fresnel.getRefractionOrientedEta(); + } + // bxdf stuff template, class MicrofacetCache=conditional_t @@ -187,6 +201,17 @@ struct SCookTorrance return value_weight_type::create(eval, _pdf); } + template, + class MicrofacetCache=conditional_t + NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction) NBL_CONST_MEMBER_FUNC + { + const scalar_type eta = __getMonochromeEta(fresnel, interaction); + fresnel::OrientedEtas orientedEta = fresnel::OrientedEtas::create(interaction.getNdotV(), hlsl::promote(eta)); + MicrofacetCache cache = MicrofacetCache::template create(interaction, _sample, orientedEta); + return evalAndWeight(_sample, interaction, cache); + } + sample_type __generate_common(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type localH, const scalar_type NdotV, const scalar_type VdotH, const scalar_type LdotH, bool transmitted, NBL_CONST_REF_ARG(fresnel::OrientedEtaRcps) rcpEta, diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index d2d557d2b0..7980d11793 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -972,19 +972,20 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) #define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) -#define NBL_CONCEPT_PARAM_3 (evalcache, typename T::evalcache_type) +#define NBL_CONCEPT_PARAM_3 (microfacetCache, typename T::cache_type) NBL_CONCEPT_BEGIN(4) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +#define microfacetCache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::cache_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, microfacetCache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ); -#undef evalcache +#undef microfacetCache #undef aniso #undef _sample #undef bxdf @@ -996,20 +997,21 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_PARAM_0 (bxdf, T) #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) #define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) -#define NBL_CONCEPT_PARAM_3 (evalcache, typename T::evalcache_type) +#define NBL_CONCEPT_PARAM_3 (microfacetCache, typename T::cache_type) NBL_CONCEPT_BEGIN(4) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 -#define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +#define microfacetCache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( - ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) + ((NBL_CONCEPT_REQ_TYPE)(T::cache_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(iso_bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(CreatableIsotropicMicrofacetCache, typename T::isocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, microfacetCache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ); -#undef evalcache +#undef microfacetCache #undef iso #undef _sample #undef bxdf diff --git a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl index 94cc51490d..76f5c61e47 100644 --- a/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/concepts.hlsl @@ -219,7 +219,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE)(T::object_handle_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getSample()), ::nbl::hlsl::is_same_v, typename T::sample_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getQuotientPdf()), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getQuotientWeight()), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getT()), ::nbl::hlsl::is_same_v, typename T::scalar_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getLightObjectID()), ::nbl::hlsl::is_same_v, typename T::object_handle_type)) ); diff --git a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl index 33a906fff7..1f1e0da37f 100644 --- a/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl +++ b/include/nbl/builtin/hlsl/path_tracing/unidirectional.hlsl @@ -101,7 +101,7 @@ struct Unidirectional ); scalar_type t = ret.getT(); sample_type nee_sample = ret.getSample(); - quotient_weight_type neeContrib = ret.getQuotientPdf(); + quotient_weight_type neeContrib = ret.getQuotientWeight(); // While NEE or other generators are not supposed to pick up Delta lobes by accident, we need the MIS weights to add up to 1 for the non-delta lobes. // So we need to weigh the Delta lobes as if the MIS weight is always 1, but other areas regularly. From 7d2708136a78be62fbffd575fa738f48343c8046 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 27 Mar 2026 14:59:40 +0700 Subject: [PATCH 23/35] added additional checks for a=0 to get pdf=inf --- .../builtin/hlsl/bxdf/base/cook_torrance_base.hlsl | 4 ++-- include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 05e632177b..0159e15b55 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -167,7 +167,7 @@ struct SCookTorrance { PdfQuery pdfQuery = __forwardPdf(_sample, interaction, cache); scalar_type _pdf = pdfQuery.pdf; - if (_pdf == scalar_type(0.0)) + if (_pdf == scalar_type(0.0) || hlsl::isinf(_pdf)) return value_weight_type::create(scalar_type(0.0), scalar_type(0.0)); fresnel_type _f = pdfQuery.orientedFresnel; @@ -409,7 +409,7 @@ struct SCookTorrance { PdfQuery pdfQuery = __forwardPdf(_sample, interaction, cache); scalar_type _pdf = pdfQuery.pdf; - if (_pdf == scalar_type(0.0)) + if (_pdf == scalar_type(0.0) || hlsl::isinf(_pdf)) return quotient_weight_type::create(scalar_type(0.0), scalar_type(0.0)); fresnel_type _f = pdfQuery.orientedFresnel; diff --git a/include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl b/include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl index 2c5f0c819c..a79eb65f55 100644 --- a/include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl @@ -226,8 +226,10 @@ struct GGX enable_if_t createDG1Query(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { dg1_query_type dg1_query; - bool dummy; - dg1_query.ndf = __ndf_base.template D(cache, dummy); + bool isInfinity; + dg1_query.ndf = __ndf_base.template D(cache, isInfinity); + if (isInfinity) + return dg1_query; scalar_type clampedNdotV = interaction.getNdotV(BxDFClampMode::BCM_ABS); dg1_query.G1_over_2NdotV = G1_wo_numerator(clampedNdotV, __ndf_base.devsh_part(interaction.getNdotV2())); return dg1_query; @@ -244,8 +246,10 @@ struct GGX enable_if_t createDG1Query(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { dg1_query_type dg1_query; - bool dummy; - dg1_query.ndf = __ndf_base.template D(cache, dummy); + bool isInfinity; + dg1_query.ndf = __ndf_base.template D(cache, isInfinity); + if (isInfinity) + return dg1_query; scalar_type clampedNdotV = interaction.getNdotV(BxDFClampMode::BCM_ABS); dg1_query.G1_over_2NdotV = G1_wo_numerator(clampedNdotV, __ndf_base.devsh_part(interaction.getTdotV2(), interaction.getBdotV2(), interaction.getNdotV2())); return dg1_query; From d8271b978d5f8fb0e95719f6085c5953f6ef5270 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 27 Mar 2026 16:07:31 +0700 Subject: [PATCH 24/35] regular bxdfs also have eval that don't need cache as input param --- .../hlsl/bxdf/base/cook_torrance_base.hlsl | 12 ++++++++---- .../nbl/builtin/hlsl/bxdf/base/lambertian.hlsl | 10 ++++++++++ .../nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl | 12 +++++++++++- include/nbl/builtin/hlsl/bxdf/common.hlsl | 4 ++-- .../hlsl/bxdf/reflection/delta_distribution.hlsl | 8 ++++++++ .../bxdf/transmission/delta_distribution.hlsl | 8 ++++++++ .../bxdf/transmission/smooth_dielectric.hlsl | 16 ++++++++++++++++ 7 files changed, 63 insertions(+), 7 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 0159e15b55..9bcb8d03a3 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -409,14 +409,18 @@ struct SCookTorrance { PdfQuery pdfQuery = __forwardPdf(_sample, interaction, cache); scalar_type _pdf = pdfQuery.pdf; - if (_pdf == scalar_type(0.0) || hlsl::isinf(_pdf)) + if (_pdf == scalar_type(0.0)) return quotient_weight_type::create(scalar_type(0.0), scalar_type(0.0)); fresnel_type _f = pdfQuery.orientedFresnel; - using g2g1_query_type = typename N::g2g1_query_type; - g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); - scalar_type G2_over_G1 = ndf.template G2_over_G1(gq, _sample, interaction, cache); + scalar_type G2_over_G1 = scalar_type(1.0); + if (_pdf < bit_cast(numeric_limits::infinity)) + { + using g2g1_query_type = typename N::g2g1_query_type; + g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); + G2_over_G1 = ndf.template G2_over_G1(gq, _sample, interaction, cache); + } spectral_type quo; NBL_IF_CONSTEXPR(IsBSDF) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 39e24c3ac2..a50d58b922 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -39,6 +39,16 @@ struct SLambertianBase { return evalAndWeight(_sample, interaction.isotropic, _cache); } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + Cache dummy; + return evalAndWeight(_sample, interaction.isotropic, dummy); + } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + Cache dummy; + return evalAndWeight(_sample, interaction.isotropic, dummy); + } template > enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index 0ea8c95584..f77e92d485 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -71,7 +71,17 @@ struct SOrenNayarBase } value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return evalAndWeight(_sample, interaction.isotropic, _cache); + return evalAndWeight(_sample, interaction.isotropic, _cache); + } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + Cache dummy; + return evalAndWeight(_sample, interaction.isotropic, dummy); + } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + Cache dummy; + return evalAndWeight(_sample, interaction.isotropic, dummy); } template > diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 7980d11793..eb4a0c1d01 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -928,6 +928,7 @@ NBL_CONCEPT_BEGIN(4) #define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) @@ -956,6 +957,7 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) @@ -982,7 +984,6 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::cache_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, microfacetCache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ); #undef microfacetCache @@ -1008,7 +1009,6 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(iso_bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(CreatableIsotropicMicrofacetCache, typename T::isocache_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, microfacetCache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ); #undef microfacetCache diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index cfebabd5fb..ee91ebe9ea 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -38,6 +38,14 @@ struct SDeltaDistribution { return value_weight_type::create(0.0, 0.0); } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + return value_weight_type::create(0.0, 0.0); + } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + return value_weight_type::create(0.0, 0.0); + } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index d1b221560e..f4a915bbed 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -38,6 +38,14 @@ struct SDeltaDistribution { return value_weight_type::create(0.0, 0.0); } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + return value_weight_type::create(0.0, 0.0); + } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + return value_weight_type::create(0.0, 0.0); + } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const random_type u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index 673bc42472..a89108e6b8 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -40,6 +40,14 @@ struct SSmoothDielectric { return value_weight_type::create(0.0, 0.0); } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + return value_weight_type::create(0.0, 0.0); + } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + return value_weight_type::create(0.0, 0.0); + } sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(random_type) u, NBL_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { @@ -114,6 +122,14 @@ struct SThinSmoothDielectric { return value_weight_type::create(0.0, 0.0); } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + return value_weight_type::create(0.0, 0.0); + } + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC + { + return value_weight_type::create(0.0, 0.0); + } // usually `luminosityContributionHint` would be the Rec.709 luma coefficients (the Y row of the RGB to CIE XYZ matrix) // its basically a set of weights that determine From e4a8319e2ad529ecde0fa4cc1f3689ac2c85859a Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 27 Mar 2026 16:53:56 +0700 Subject: [PATCH 25/35] regular bxdfs don't take cache for eval --- .../nbl/builtin/hlsl/bxdf/base/lambertian.hlsl | 14 ++------------ .../nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl | 14 ++------------ include/nbl/builtin/hlsl/bxdf/common.hlsl | 15 +++++++++++---- .../hlsl/bxdf/reflection/delta_distribution.hlsl | 8 -------- .../bxdf/transmission/delta_distribution.hlsl | 8 -------- .../bxdf/transmission/smooth_dielectric.hlsl | 16 ---------------- 6 files changed, 15 insertions(+), 60 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index a50d58b922..d6a3e7a8c5 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -30,24 +30,14 @@ struct SLambertianBase NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value::value; - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); return value_weight_type::create(quo, forwardPdf(_sample, interaction)); } value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC { - return evalAndWeight(_sample, interaction.isotropic, _cache); - } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC - { - Cache dummy; - return evalAndWeight(_sample, interaction.isotropic, dummy); - } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC - { - Cache dummy; - return evalAndWeight(_sample, interaction.isotropic, dummy); + return evalAndWeight(_sample, interaction.isotropic); } template > diff --git a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl index f77e92d485..1225cd9fb3 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -63,25 +63,15 @@ struct SOrenNayarBase return hlsl::promote(NdotL * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF) * __rec_pi_factored_out_wo_clamps(query.getVdotL(), NdotL, interaction.getNdotV(_clamp))); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); return value_weight_type::create(__eval(query, _sample, interaction), forwardPdf(_sample, interaction)); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return evalAndWeight(_sample, interaction.isotropic, _cache); - } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC - { - Cache dummy; - return evalAndWeight(_sample, interaction.isotropic, dummy); - } value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { - Cache dummy; - return evalAndWeight(_sample, interaction.isotropic, dummy); + return evalAndWeight(_sample, interaction.isotropic); } template > diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index eb4a0c1d01..54e4a1b145 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -929,7 +929,6 @@ NBL_CONCEPT_BEGIN(4) NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common_typdefs, T)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(LightSample, typename T::sample_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointLikeVectorial, typename T::spectral_type)) @@ -958,7 +957,6 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotientAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(surface_interactions::Isotropic, typename T::isotropic_interaction_type)) ); @@ -975,17 +973,21 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) #define NBL_CONCEPT_PARAM_2 (aniso, typename T::anisotropic_interaction_type) #define NBL_CONCEPT_PARAM_3 (microfacetCache, typename T::cache_type) -NBL_CONCEPT_BEGIN(4) +#define NBL_CONCEPT_PARAM_4 (anisocache, typename T::anisocache_type) +NBL_CONCEPT_BEGIN(5) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define microfacetCache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +#define anisocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_4 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::cache_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, microfacetCache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ); +#undef anisocache #undef microfacetCache #undef aniso #undef _sample @@ -999,18 +1001,23 @@ NBL_CONCEPT_END( #define NBL_CONCEPT_PARAM_1 (_sample, typename T::sample_type) #define NBL_CONCEPT_PARAM_2 (iso, typename T::isotropic_interaction_type) #define NBL_CONCEPT_PARAM_3 (microfacetCache, typename T::cache_type) -NBL_CONCEPT_BEGIN(4) +#define NBL_CONCEPT_PARAM_4 (isocache, typename T::isocache_type) +NBL_CONCEPT_BEGIN(5) #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 #define iso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 #define microfacetCache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 +#define isocache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_4 NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_TYPE)(T::cache_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(iso_bxdf_common, T)) + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(microfacet_bxdf_common, T)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(CreatableIsotropicMicrofacetCache, typename T::isocache_type)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, microfacetCache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) ); +#undef isocache #undef microfacetCache #undef iso #undef _sample diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index ee91ebe9ea..3ca10587d3 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -30,14 +30,6 @@ struct SDeltaDistribution NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_MAX; - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return value_weight_type::create(0.0, 0.0); - } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return value_weight_type::create(0.0, 0.0); - } value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl index f4a915bbed..59b58bfedf 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -30,14 +30,6 @@ struct SDeltaDistribution NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return value_weight_type::create(0.0, 0.0); - } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return value_weight_type::create(0.0, 0.0); - } value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); diff --git a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl index a89108e6b8..bb70e46805 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -32,14 +32,6 @@ struct SSmoothDielectric NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = BxDFClampMode::BCM_ABS; // eval and weight return 0 because smooth dielectric/conductor BxDFs are dirac delta distributions, model perfectly specular objects that scatter light to only one outgoing direction - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return value_weight_type::create(0.0, 0.0); - } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return value_weight_type::create(0.0, 0.0); - } value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); @@ -114,14 +106,6 @@ struct SThinSmoothDielectric return retval; } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return value_weight_type::create(0.0, 0.0); - } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC - { - return value_weight_type::create(0.0, 0.0); - } value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return value_weight_type::create(0.0, 0.0); From 920c44a8c3f360196229558a623ec59b525c9a9c Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 27 Mar 2026 16:55:37 +0700 Subject: [PATCH 26/35] latest example --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index ee0c4ab29d..5d64bab814 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit ee0c4ab29d0b48d09df420a0d4ddd68f07182376 +Subproject commit 5d64bab814a35f7fbf02f5cbf6030cfbe537a7cf From 52228cac93263021598b072eed6cb6fc5351ad2f Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 31 Mar 2026 10:38:32 +0700 Subject: [PATCH 27/35] use isinf because don't need to look out for NaNs --- include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 9bcb8d03a3..8254c090e0 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -415,7 +415,7 @@ struct SCookTorrance fresnel_type _f = pdfQuery.orientedFresnel; scalar_type G2_over_G1 = scalar_type(1.0); - if (_pdf < bit_cast(numeric_limits::infinity)) + if (!hlsl::isinf(_pdf)) { using g2g1_query_type = typename N::g2g1_query_type; g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); From f11902b041ce0ac6ece246096586fb21984ce40b Mon Sep 17 00:00:00 2001 From: devshgraphicsprogramming Date: Mon, 30 Mar 2026 23:19:00 +0200 Subject: [PATCH 28/35] there was a bug in `decode_before_scramble_helper` fix make `OwenSampler` be able to generate dimensions in parallel --- .../hlsl/sampling/quantized_sequence.hlsl | 16 +- include/nbl/core/sampling/OwenSampler.h | 146 +++++++++--------- include/nbl/core/sampling/SobolSampler.h | 2 +- 3 files changed, 82 insertions(+), 82 deletions(-) diff --git a/include/nbl/builtin/hlsl/sampling/quantized_sequence.hlsl b/include/nbl/builtin/hlsl/sampling/quantized_sequence.hlsl index 64573ac85f..db575e0250 100644 --- a/include/nbl/builtin/hlsl/sampling/quantized_sequence.hlsl +++ b/include/nbl/builtin/hlsl/sampling/quantized_sequence.hlsl @@ -79,7 +79,7 @@ struct decode_before_scramble_helper { uvec_type seqVal; NBL_UNROLL for(uint16_t i = 0; i < Dim; i++) - seqVal[i] = val.get(i); + seqVal[i] = val.get(i) << Q::DiscardBits; // restore high bits seqVal ^= scrambleKey; return return_type(seqVal) * bit_cast >(UNormConstant); } @@ -122,6 +122,7 @@ struct QuantizedSequence::scalar_type; NBL_CONSTEXPR_STATIC_INLINE uint16_t BitsPerComponent = 8u*size_of_v; + NBL_CONSTEXPR_STATIC_INLINE uint16_t DiscardBits = uint16_t(0u); NBL_CONSTEXPR_STATIC_INLINE uint16_t Dimension = uint16_t(1u); static this_t create(const store_type value) @@ -223,6 +224,7 @@ struct QuantizedSequence::scalar_type; NBL_CONSTEXPR_STATIC_INLINE uint16_t BitsPerComponent = 8u*size_of_v; + NBL_CONSTEXPR_STATIC_INLINE uint16_t DiscardBits = uint16_t(0u); NBL_CONSTEXPR_STATIC_INLINE uint16_t Dimension = Dim; static this_t create(const store_type value) @@ -288,11 +290,11 @@ struct QuantizedSequence && Di else if (idx == 1) // y { scalar_type y = glsl::bitfieldExtract(data[0], BitsPerComponent, DiscardBits); - y |= glsl::bitfieldExtract(data[1], 0u, DiscardBits - 1u) << DiscardBits; + y |= glsl::bitfieldExtract(data[1], 0u, BitsPerComponent - DiscardBits) << DiscardBits; return y; } else // z - return glsl::bitfieldExtract(data[1], DiscardBits - 1u, BitsPerComponent); + return glsl::bitfieldExtract(data[1], BitsPerComponent - DiscardBits, BitsPerComponent); } void set(const uint16_t idx, const scalar_type value) @@ -304,10 +306,10 @@ struct QuantizedSequence && Di else if (idx == 1) // y { data[0] = glsl::bitfieldInsert(data[0], trunc_val, BitsPerComponent, DiscardBits); - data[1] = glsl::bitfieldInsert(data[1], trunc_val >> DiscardBits, 0u, DiscardBits - 1u); + data[1] = glsl::bitfieldInsert(data[1], trunc_val >> DiscardBits, 0u, BitsPerComponent - DiscardBits); } else // z - data[1] = glsl::bitfieldInsert(data[1], trunc_val, DiscardBits - 1u, BitsPerComponent); + data[1] = glsl::bitfieldInsert(data[1], trunc_val, BitsPerComponent - DiscardBits, BitsPerComponent); } template @@ -317,14 +319,14 @@ struct QuantizedSequence && Di } template - vector decode(const vector,Dimension> scrambleKey) + vector decode(const vector,Dimension> scrambleKey) NBL_CONST_MEMBER_FUNC { impl::decode_before_scramble_helper helper; helper.val.data = data; return helper(scrambleKey); } template - vector decode(NBL_CONST_REF_ARG(this_t) scrambleKey) + vector decode(NBL_CONST_REF_ARG(this_t) scrambleKey) NBL_CONST_MEMBER_FUNC { impl::decode_after_scramble_helper helper; helper.val.data = data; diff --git a/include/nbl/core/sampling/OwenSampler.h b/include/nbl/core/sampling/OwenSampler.h index b218647314..7f35b015e3 100644 --- a/include/nbl/core/sampling/OwenSampler.h +++ b/include/nbl/core/sampling/OwenSampler.h @@ -12,92 +12,90 @@ namespace nbl::core //! TODO: make the tree sampler/generator configurable and let RandomSampler be default template -class OwenSampler : protected SequenceSampler +class OwenSampler final : protected SequenceSampler { + // if we don't limit the sample count, then due to IEEE754 precision, we'll get duplicate sample coordinate values, ruining the net property + constexpr static inline uint32_t OUT_BITS = sizeof(uint32_t)*8u; + constexpr static inline uint32_t MAX_SAMPLES_LOG2 = 24u; + constexpr static inline uint32_t MAX_SAMPLES = 0x1u<lastDim) - resetDimensionCounter(dim); - else if (dim>hlsl::findMSB(sampleNum))) == 0u); - else - assert(oldsample == 0u); - #endif - constexpr uint32_t lastLevelStart = MAX_SAMPLES/2u-1u; - uint32_t index = oldsample>>(OUT_BITS+1u - MAX_SAMPLES_LOG2); - index += lastLevelStart; + inline uint32_t sample(uint32_t sampleNum) const + { + const uint32_t oldsample = sampler.sample(dimension,sampleNum); + #ifdef _NBL_DEBUG + assert(sampleNum>hlsl::findMSB(sampleNum))) == 0u); + else + assert(oldsample == 0u); + #endif + constexpr uint32_t lastLevelStart = MAX_SAMPLES/2u-1u; + uint32_t index = oldsample>>(OUT_BITS+1u - MAX_SAMPLES_LOG2); + index += lastLevelStart; - return oldsample^cachedFlip[index]; - } + return oldsample^cachedFlip[index]; + } - //! - inline void resetDimensionCounter(uint32_t dimension) - { - /** NOTES: - - For 64k samples, we can store their positions in uint16_t - - The last leves of Owen Tree can be collapsed to a single node (because trailing bits are always 00000.....) - - The above can be stored in 1x array of sample count uint16_t/uint32_t per Dimension - - We should store samples as uint32_t always because the total amount of memory to fetch is always the same - **/ - for (uint32_t i=0u; i>getTreeDepth(i)); - } - for (uint32_t i=1u; i>1u)]; - #ifdef _NBL_DEBUG - for (uint32_t j=0u; j()((uint64_t(_dimension)<<32)|seed)) { - const uint32_t highBitMask = 0xffffffffu<<(OUT_BITS-i); - uint32_t left = cachedFlip[currentLevelStart+j]; - uint32_t right = cachedFlip[currentLevelStart+j+1]; - assert(((left^right)&highBitMask)==0u); - assert((left&right&highBitMask)==cachedFlip[previousLevelStart+(j>>1u)]); + cachedFlip.resize(MAX_SAMPLES-1u); + /** NOTES: + - For 64k samples, we can store their positions in uint16_t + - The last leves of Owen Tree can be collapsed to a single node (because trailing bits are always 00000.....) + - The above can be stored in 1x array of sample count uint16_t/uint32_t per Dimension + - We should store samples as uint32_t always because the total amount of memory to fetch is always the same + **/ + for (uint32_t i=0u; i>getTreeDepth(i)); + } + for (uint32_t i=1u; i>1u)]; + #ifdef _NBL_DEBUG + for (uint32_t j=0u; j>1u)]); + } + #endif + } + } + inline uint32_t getTreeDepth(uint32_t sampleNum) + { + return hlsl::findMSB(sampleNum+1u); } - #endif - } - lastDim = dimension; - } - - protected: - // if we don't limit the sample count, then due to IEEE754 precision, we'll get duplicate sample coordinate values, ruining the net property - _NBL_STATIC_INLINE_CONSTEXPR uint32_t OUT_BITS = sizeof(uint32_t)*8u; - _NBL_STATIC_INLINE_CONSTEXPR uint32_t MAX_SAMPLES_LOG2 = 24u; - _NBL_STATIC_INLINE_CONSTEXPR uint32_t MAX_SAMPLES = 0x1u< cachedFlip; + const uint32_t dimension; + }; + inline SDimensionSampler prepareDimension(const uint64_t dim) const { - return hlsl::findMSB(sampleNum+1u); + return SDimensionSampler(*this,seed,dim); } - std::mt19937 mersenneTwister; - uint32_t lastDim; - core::vector cachedFlip; - }; + private: + uint32_t seed; +}; } diff --git a/include/nbl/core/sampling/SobolSampler.h b/include/nbl/core/sampling/SobolSampler.h index 8d0c65e431..31d397168b 100644 --- a/include/nbl/core/sampling/SobolSampler.h +++ b/include/nbl/core/sampling/SobolSampler.h @@ -77,7 +77,7 @@ class SobolSampler } // Idea for optimization, do PoT samples per pass, then can precompute most of the `retval` - inline uint32_t sample(uint32_t dim, uint32_t sampleNum) + inline uint32_t sample(uint32_t dim, uint32_t sampleNum) const { #ifdef _DEBUG assert(dim Date: Wed, 1 Apr 2026 16:18:33 +0700 Subject: [PATCH 29/35] check pdf for NaN as well to reduce BSDF flickering, still not entirely solved --- include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 8254c090e0..5f3e53b903 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -167,7 +167,7 @@ struct SCookTorrance { PdfQuery pdfQuery = __forwardPdf(_sample, interaction, cache); scalar_type _pdf = pdfQuery.pdf; - if (_pdf == scalar_type(0.0) || hlsl::isinf(_pdf)) + if (_pdf == scalar_type(0.0) || _pdf >= bit_cast(numeric_limits::infinity)) return value_weight_type::create(scalar_type(0.0), scalar_type(0.0)); fresnel_type _f = pdfQuery.orientedFresnel; @@ -361,6 +361,8 @@ struct SCookTorrance template PdfQuery __forwardPdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { + // MicrofacetCache cache = _cache; + // cache.VdotH = 0.5; PdfQuery query; query.pdf = scalar_type(0.0); query.orientedFresnel = __getOrientedFresnel(fresnel, interaction.getNdotV()); @@ -415,7 +417,7 @@ struct SCookTorrance fresnel_type _f = pdfQuery.orientedFresnel; scalar_type G2_over_G1 = scalar_type(1.0); - if (!hlsl::isinf(_pdf)) + if (_pdf < bit_cast(numeric_limits::infinity)) { using g2g1_query_type = typename N::g2g1_query_type; g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); From 3082d9e6d84b92976088d5a5b3be063941f5d055 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Wed, 1 Apr 2026 17:01:19 +0700 Subject: [PATCH 30/35] latest example --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 5d64bab814..b72cc0f355 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 5d64bab814a35f7fbf02f5cbf6030cfbe537a7cf +Subproject commit b72cc0f355e8581681a007a64fca1a9102ee63b4 From 9076efbee0112ad31cd7118adc836aeb6e0d25e0 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 2 Apr 2026 16:05:19 +0700 Subject: [PATCH 31/35] fix fresnel iridescent not doing transmission --- include/nbl/builtin/hlsl/bxdf/fresnel.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl b/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl index 23e5ff327e..44ba941bfe 100644 --- a/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl @@ -667,7 +667,7 @@ struct iridescent_base template T __call(const vector_type iork3, const vector_type etak23, const scalar_type clampedCosTheta) NBL_CONST_MEMBER_FUNC { - return impl::iridescent_helper::template __call(D, ior1, ior2, ior3, iork3, + return impl::iridescent_helper::template __call(D, ior1, ior2, ior3, iork3, eta12, eta23, etak23, clampedCosTheta); } From 6c49c9970c4856a9db699cbb487a844fa559c985 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 3 Apr 2026 14:27:55 +0700 Subject: [PATCH 32/35] check for nan not required after fixing path tracer --- include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl index 5f3e53b903..f5a4fbf5c6 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -167,7 +167,7 @@ struct SCookTorrance { PdfQuery pdfQuery = __forwardPdf(_sample, interaction, cache); scalar_type _pdf = pdfQuery.pdf; - if (_pdf == scalar_type(0.0) || _pdf >= bit_cast(numeric_limits::infinity)) + if (_pdf == scalar_type(0.0) || hlsl::isinf(_pdf)) return value_weight_type::create(scalar_type(0.0), scalar_type(0.0)); fresnel_type _f = pdfQuery.orientedFresnel; @@ -417,7 +417,7 @@ struct SCookTorrance fresnel_type _f = pdfQuery.orientedFresnel; scalar_type G2_over_G1 = scalar_type(1.0); - if (_pdf < bit_cast(numeric_limits::infinity)) + if (!hlsl::isinf(_pdf)) { using g2g1_query_type = typename N::g2g1_query_type; g2g1_query_type gq = ndf.template createG2G1Query(_sample, interaction); From ff9321eeb30b50697b27f7559186b4abcf7dbfcb Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 6 Apr 2026 14:05:19 +0700 Subject: [PATCH 33/35] removed cache from lambertian eval that forgot to remove --- include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index d6a3e7a8c5..378035e67d 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -35,7 +35,7 @@ struct SLambertianBase const spectral_type quo = hlsl::promote(_sample.getNdotL(_clamp) * numbers::inv_pi * hlsl::mix(1.0, 0.5, IsBSDF)); return value_weight_type::create(quo, forwardPdf(_sample, interaction)); } - value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC + value_weight_type evalAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return evalAndWeight(_sample, interaction.isotropic); } From bb63a41242127f880f185619f2a544635bc239f3 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 17 Apr 2026 11:32:24 +0700 Subject: [PATCH 34/35] update submodules that was incorrectly regressed --- 3rdparty/Vulkan-Headers | 2 +- 3rdparty/dxc/dxc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/3rdparty/Vulkan-Headers b/3rdparty/Vulkan-Headers index 3dda5a1a87..f6a6f7ab16 160000 --- a/3rdparty/Vulkan-Headers +++ b/3rdparty/Vulkan-Headers @@ -1 +1 @@ -Subproject commit 3dda5a1a87b62fdf3baf4680edc41c00e85a7a22 +Subproject commit f6a6f7ab165cedbfa2a7d0c93fe27a2d01ce09c8 diff --git a/3rdparty/dxc/dxc b/3rdparty/dxc/dxc index d76c7890b1..ef98b9792c 160000 --- a/3rdparty/dxc/dxc +++ b/3rdparty/dxc/dxc @@ -1 +1 @@ -Subproject commit d76c7890b19ce0b344ee0ce116dbc1c92220ccea +Subproject commit ef98b9792c4adf476e4deaa21a536172a25fbfba From b31b8b6768660a5ec3efcddc7ab934c859e2acd3 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 17 Apr 2026 12:02:57 +0700 Subject: [PATCH 35/35] fix to lambertian quotient_weight using wrong pdf --- include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 89d62b81d2..08c3f967b6 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -76,15 +76,12 @@ struct SLambertianBase quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_CONST_REF_ARG(isocache_type) _cache) NBL_CONST_MEMBER_FUNC { - // only z component matters: ProjectedHemisphere::forwardPdf reads v.z - const vector3_type L = vector3_type(0, 0, _sample.getNdotL(_clamp)); - typename sampling::ProjectedHemisphere::cache_type cache; scalar_type p; NBL_IF_CONSTEXPR (IsBSDF) - p = sampling::ProjectedSphere::forwardPdf(L, cache); + p = sampling::ProjectedSphere::backwardPdf(vector(0, 0, _sample.getNdotL(_clamp))); else - p = sampling::ProjectedHemisphere::forwardPdf(L, cache); - return quotient_pdf_type::create(scalar_type(1.0), p); + p = sampling::ProjectedHemisphere::backwardPdf(vector(0, 0, _sample.getNdotL(_clamp))); + return quotient_weight_type::create(scalar_type(1.0), p); } quotient_weight_type quotientAndWeight(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_CONST_REF_ARG(anisocache_type) _cache) NBL_CONST_MEMBER_FUNC {