diff --git a/examples_tests b/examples_tests index 587cbff28b..d6c514da26 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 587cbff28b1d0b42f2f704c3ba9b247ad0276590 +Subproject commit d6c514da2647e22c8123056bd92ca8ed965a47c4 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 d70e8823da..924c36c7e9 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl @@ -50,7 +50,7 @@ struct quant_query_helper using quant_query_type = typename N::quant_query_type; template - static quant_query_type __call(NBL_REF_ARG(N) ndf, NBL_CONST_REF_ARG(F) fresnel, NBL_CONST_REF_ARG(I) interaction, NBL_CONST_REF_ARG(C) cache) + static quant_query_type __call(NBL_CONST_REF_ARG(N) ndf, NBL_CONST_REF_ARG(F) fresnel, NBL_CONST_REF_ARG(I) interaction, NBL_CONST_REF_ARG(C) cache) { return ndf.template createQuantQuery(interaction, cache, fresnel.getRefractionOrientedEta()); } @@ -62,7 +62,7 @@ struct quant_query_helper using quant_query_type = typename N::quant_query_type; template - static quant_query_type __call(NBL_REF_ARG(N) ndf, NBL_CONST_REF_ARG(F) fresnel, NBL_CONST_REF_ARG(I) interaction, NBL_CONST_REF_ARG(C) cache) + static quant_query_type __call(NBL_CONST_REF_ARG(N) ndf, NBL_CONST_REF_ARG(F) fresnel, NBL_CONST_REF_ARG(I) interaction, NBL_CONST_REF_ARG(C) cache) { typename N::scalar_type dummy; return ndf.template createQuantQuery(interaction, cache, dummy); @@ -146,7 +146,7 @@ struct SCookTorrance return hlsl::mix(reflectance, scalar_type(1.0)-reflectance, transmitted); } - bool __dotIsValue(const vector3_type a, const vector3_type b, const scalar_type value) + bool __dotIsValue(const vector3_type a, const vector3_type b, const scalar_type value) NBL_CONST_MEMBER_FUNC { const scalar_type ab = hlsl::dot(a, b); return hlsl::max(ab, value / ab) <= scalar_type(value + 1e-3); @@ -156,7 +156,7 @@ 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) + 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 { fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); if (!__checkValid(_f, _sample, interaction, cache)) @@ -197,7 +197,7 @@ struct SCookTorrance 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, - NBL_REF_ARG(bool) valid) + NBL_REF_ARG(bool) valid) NBL_CONST_MEMBER_FUNC { // fail if samples have invalid paths const scalar_type NdotL = hlsl::mix(scalar_type(2.0) * VdotH * localH.z - NdotV, @@ -244,7 +244,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) + 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 { const scalar_type NdotV = interaction.getNdotV(); if (NdotV < numeric_limits::min) @@ -274,7 +274,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) + 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 { const vector3_type localV = interaction.getTangentSpaceV(); const scalar_type NdotV = localV.z; @@ -322,7 +322,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) + 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 { anisocache_type aniso_cache; sample_type s = generate(anisotropic_interaction_type::create(interaction), u, aniso_cache); @@ -331,7 +331,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) + 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 { using quant_query_type = typename ndf_type::quant_query_type; using dg1_query_type = typename ndf_type::dg1_query_type; @@ -356,7 +356,7 @@ 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) + 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 { fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); if (!__checkValid(_f, _sample, interaction, cache)) @@ -370,7 +370,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) + 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 { 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 diff --git a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl index 8500f5c6c5..a107921026 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/lambertian.hlsl @@ -25,24 +25,24 @@ 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) + spectral_type eval(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)); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return eval(_sample, interaction.isotropic); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC { ray_dir_info_type L; L.setDirection(sampling::ProjectedHemisphere::generate(u)); return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC { vector3_type _u = u; ray_dir_info_type L; @@ -50,29 +50,29 @@ struct SLambertianBase return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } template > - enable_if_t generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) + 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) + enable_if_t generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC { 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) + 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 pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { 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) + quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { sampling::quotient_and_pdf qp; NBL_IF_CONSTEXPR (IsBSDF) @@ -81,7 +81,7 @@ struct SLambertianBase qp = sampling::ProjectedHemisphere::template quotient_and_pdf(_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) + 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 { return quotient_and_pdf(_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 cdec22e892..d104842608 100644 --- a/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/base/oren_nayar.hlsl @@ -45,39 +45,39 @@ struct SOrenNayarBase return retval; } - scalar_type __rec_pi_factored_out_wo_clamps(scalar_type VdotL, scalar_type clampedNdotL, scalar_type clampedNdotV) + scalar_type __rec_pi_factored_out_wo_clamps(scalar_type VdotL, scalar_type clampedNdotL, scalar_type clampedNdotV) NBL_CONST_MEMBER_FUNC { scalar_type C = 1.0 / max(clampedNdotL, clampedNdotV); scalar_type cos_phi_sin_theta = max(VdotL - clampedNdotL * clampedNdotV, 0.0); return (AB.x + AB.y * cos_phi_sin_theta * C); } template - spectral_type __eval(NBL_CONST_REF_ARG(Query) query, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + spectral_type __eval(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 NdotL = _sample.getNdotL(_clamp); 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) + spectral_type eval(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); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return eval(_sample, interaction.isotropic); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC { ray_dir_info_type L; L.setDirection(sampling::ProjectedHemisphere::generate(u)); return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } template > - enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) + enable_if_t generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC { vector3_type _u = u; ray_dir_info_type L; @@ -85,42 +85,42 @@ struct SOrenNayarBase return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); } template > - enable_if_t generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) + 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) + enable_if_t generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC { 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) + 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 pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return pdf(_sample, interaction.isotropic); } 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) + 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 { 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) + 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 { SQuery query; query.VdotL = hlsl::dot(interaction.getV().getDirection(), _sample.getL().getDirection()); return __quotient_and_pdf(query, _sample, interaction); } - quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) 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 { return quotient_and_pdf(_sample, interaction.isotropic); } diff --git a/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl b/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl index 33faa79efc..76ea58de6a 100644 --- a/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/fresnel.hlsl @@ -431,14 +431,6 @@ struct Conductor return (rs2 + rp2) * hlsl::promote(0.5); } - // OrientedEtaRcps getRefractionOrientedEtaRcps() NBL_CONST_MEMBER_FUNC - // { - // OrientedEtaRcps rcpEta; - // rcpEta.value = hlsl::promote(1.0) / eta; - // rcpEta.value2 = rcpEta.value * rcpEta.value; - // return rcpEta; - // } - T eta; T etak2; T etaLen2; @@ -703,14 +695,6 @@ struct Iridescent getRefractionOrientedEtaRcps() NBL_CONST_MEMBER_FUNC - // { - // OrientedEtaRcps rcpEta; - // rcpEta.value = hlsl::promote(1.0) / base_type::eta13; - // rcpEta.value2 = rcpEta.value * rcpEta.value; - // return rcpEta; - // } - vector_type getEtak23() NBL_CONST_MEMBER_FUNC { return etak23; diff --git a/include/nbl/builtin/hlsl/bxdf/ndf/beckmann.hlsl b/include/nbl/builtin/hlsl/bxdf/ndf/beckmann.hlsl index c719bbfd4e..556292d0e8 100644 --- a/include/nbl/builtin/hlsl/bxdf/ndf/beckmann.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/ndf/beckmann.hlsl @@ -100,7 +100,7 @@ struct BeckmannCommon) - scalar_type D(NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) + scalar_type D(NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { if (a2 < numeric_limits::min) { @@ -115,7 +115,7 @@ struct BeckmannCommon= scalar_type(0.0)); return NdotX2 / (a2 * (scalar_type(1.0) - NdotX2)); @@ -131,7 +131,7 @@ struct BeckmannCommon) - scalar_type D(NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) + scalar_type D(NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { if (a2 < numeric_limits::min) { @@ -147,7 +147,7 @@ struct BeckmannCommon; using vector3_type = vector; - vector3_type __call(const vector3_type localV, const vector2_type u) + vector3_type __call(const vector3_type localV, const vector2_type u) NBL_CONST_MEMBER_FUNC { //stretch vector3_type V = nbl::hlsl::normalize(vector3_type(ax * localV.x, ay * localV.y, localV.z)); @@ -275,7 +275,7 @@ struct Beckmann } template && RequiredMicrofacetCache) - quant_query_type createQuantQuery(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta) + quant_query_type createQuantQuery(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta) NBL_CONST_MEMBER_FUNC { quant_query_type quant_query; // only has members for refraction NBL_IF_CONSTEXPR(SupportsTransmission) @@ -285,7 +285,7 @@ struct Beckmann return quant_query; } template NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - enable_if_t createDG1Query(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + 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; @@ -294,7 +294,7 @@ struct Beckmann return dg1_query; } template NBL_FUNC_REQUIRES(LightSample && RequiredInteraction) - enable_if_t createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction) + enable_if_t createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction) NBL_CONST_MEMBER_FUNC { g2g1_query_type g2_query; g2_query.lambda_L = Lambda(__ndf_base.C2(_sample.getNdotL2())); @@ -302,7 +302,7 @@ struct Beckmann return g2_query; } template NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - enable_if_t createDG1Query(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + 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; @@ -311,7 +311,7 @@ struct Beckmann return dg1_query; } template NBL_FUNC_REQUIRES(LightSample && RequiredInteraction) - enable_if_t createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction) + enable_if_t createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction) NBL_CONST_MEMBER_FUNC { g2g1_query_type g2_query; g2_query.lambda_L = Lambda(__ndf_base.C2(_sample.getTdotL2(), _sample.getBdotL2(), _sample.getNdotL2())); @@ -319,20 +319,20 @@ struct Beckmann return g2_query; } - vector3_type generateH(const vector3_type localV, const vector2_type u) + vector3_type generateH(const vector3_type localV, const vector2_type u) NBL_CONST_MEMBER_FUNC { return __generate_base.__call(localV, u); } template && RequiredInteraction && RequiredMicrofacetCache) - quant_type D(NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) + quant_type D(NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { scalar_type d = __ndf_base.template D(cache, isInfinity); return createDualMeasureQuantity(d, interaction.getNdotV(BxDFClampMode::BCM_ABS), _sample.getNdotL(BxDFClampMode::BCM_ABS), quant_query); } template && RequiredInteraction) - quant_type DG1(NBL_CONST_REF_ARG(dg1_query_type) query, NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_REF_ARG(bool) isInfinity) + quant_type DG1(NBL_CONST_REF_ARG(dg1_query_type) query, NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { scalar_type D = query.getNdf(); isInfinity = hlsl::isinf(D); @@ -348,7 +348,7 @@ struct Beckmann } template && RequiredInteraction && RequiredMicrofacetCache) - scalar_type correlated(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + scalar_type correlated(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { scalar_type onePlusLambda_V = scalar_type(1.0) + query.getLambdaV(); scalar_type lambda_L = query.getLambdaL(); @@ -356,7 +356,7 @@ struct Beckmann } template && RequiredInteraction && RequiredMicrofacetCache) - scalar_type G2_over_G1(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + scalar_type G2_over_G1(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { scalar_type onePlusLambda_V = scalar_type(1.0) + query.getLambdaV(); scalar_type lambda_L = query.getLambdaL(); diff --git a/include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl b/include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl index c64f6e3b84..2c5f0c819c 100644 --- a/include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl @@ -86,7 +86,7 @@ struct GGXCommon) - scalar_type D(NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) + scalar_type D(NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { if (a2 < numeric_limits::min) { @@ -99,7 +99,7 @@ struct GGXCommon= numeric_limits::min); return sqrt(a2 + one_minus_a2 * NdotX2); @@ -116,7 +116,7 @@ struct GGXCommon) - scalar_type D(NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) + scalar_type D(NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { if (a2 < numeric_limits::min) { @@ -131,7 +131,7 @@ struct GGXCommon= numeric_limits::min && ay2 >= numeric_limits::min); return sqrt(TdotX2 * ax2 + BdotX2 * ay2 + NdotX2); @@ -149,7 +149,7 @@ struct GGXGenerateH using vector2_type = vector; using vector3_type = vector; - vector3_type __call(const vector3_type localV, const vector2_type u) + vector3_type __call(const vector3_type localV, const vector2_type u) NBL_CONST_MEMBER_FUNC { vector3_type V = hlsl::normalize(vector3_type(ax * localV.x, ay * localV.y, localV.z));//stretch view vector so that we're sampling as if roughness=1.0 @@ -213,7 +213,7 @@ struct GGX } template && RequiredMicrofacetCache) - quant_query_type createQuantQuery(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta) + quant_query_type createQuantQuery(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta) NBL_CONST_MEMBER_FUNC { quant_query_type quant_query; // only has members for refraction NBL_IF_CONSTEXPR(SupportsTransmission) @@ -223,7 +223,7 @@ struct GGX return quant_query; } template NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - enable_if_t createDG1Query(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + 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; @@ -233,7 +233,7 @@ struct GGX return dg1_query; } template NBL_FUNC_REQUIRES(LightSample && RequiredInteraction) - enable_if_t createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction) + enable_if_t createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction) NBL_CONST_MEMBER_FUNC { g2g1_query_type g2_query; g2_query.devsh_l = __ndf_base.devsh_part(_sample.getNdotL2()); @@ -241,7 +241,7 @@ struct GGX return g2_query; } template NBL_FUNC_REQUIRES(RequiredInteraction && RequiredMicrofacetCache) - enable_if_t createDG1Query(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + 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; @@ -251,7 +251,7 @@ struct GGX return dg1_query; } template NBL_FUNC_REQUIRES(LightSample && RequiredInteraction) - enable_if_t createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction) + enable_if_t createG2G1Query(NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction) NBL_CONST_MEMBER_FUNC { g2g1_query_type g2_query; g2_query.devsh_l = __ndf_base.devsh_part(_sample.getTdotL2(), _sample.getBdotL2(), _sample.getNdotL2()); @@ -259,20 +259,20 @@ struct GGX return g2_query; } - vector3_type generateH(const vector3_type localV, const vector2_type u) + vector3_type generateH(const vector3_type localV, const vector2_type u) NBL_CONST_MEMBER_FUNC { return __generate_base.__call(localV, u); } template && RequiredInteraction && RequiredMicrofacetCache) - quant_type D(NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) + quant_type D(NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { scalar_type d = __ndf_base.template D(cache, isInfinity); return createDualMeasureQuantity(d, interaction.getNdotV(BxDFClampMode::BCM_ABS), _sample.getNdotL(BxDFClampMode::BCM_ABS), quant_query); } template && RequiredInteraction) - quant_type DG1(NBL_CONST_REF_ARG(dg1_query_type) query, NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_REF_ARG(bool) isInfinity) + quant_type DG1(NBL_CONST_REF_ARG(dg1_query_type) query, NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { scalar_type D = query.getNdfwoNumerator(); isInfinity = hlsl::isinf(D); @@ -301,7 +301,7 @@ struct GGX } template && RequiredInteraction && RequiredMicrofacetCache) - scalar_type correlated_wo_numerator(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + scalar_type correlated_wo_numerator(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { scalar_type NdotV = interaction.getNdotV(BxDFClampMode::BCM_ABS); scalar_type NdotL = _sample.getNdotL(BxDFClampMode::BCM_ABS); @@ -325,13 +325,13 @@ struct GGX } template && RequiredInteraction && RequiredMicrofacetCache) - scalar_type correlated(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + scalar_type correlated(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { return scalar_type(4.0) * interaction.getNdotV(BxDFClampMode::BCM_ABS) * _sample.getNdotL(BxDFClampMode::BCM_ABS) * correlated_wo_numerator(query, _sample, interaction, cache); } template && RequiredInteraction && RequiredMicrofacetCache) - quant_type Dcorrelated(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) + quant_type Dcorrelated(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(quant_query_type) quant_query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, NBL_REF_ARG(bool) isInfinity) NBL_CONST_MEMBER_FUNC { scalar_type dg = __ndf_base.template D(cache, isInfinity); if (isInfinity) @@ -361,7 +361,7 @@ struct GGX } template && RequiredInteraction && RequiredMicrofacetCache) - scalar_type G2_over_G1(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) + scalar_type G2_over_G1(NBL_CONST_REF_ARG(g2g1_query_type) query, NBL_CONST_REF_ARG(LS) _sample, NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache) NBL_CONST_MEMBER_FUNC { scalar_type G2_over_G1; scalar_type NdotV = interaction.getNdotV(BxDFClampMode::BCM_ABS); diff --git a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl index 7a37cc3b72..9bf9e16aa9 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection/delta_distribution.hlsl @@ -25,16 +25,16 @@ 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) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return hlsl::promote(0); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return hlsl::promote(0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC { vector3_type V = interaction.getV().getDirection(); bxdf::Reflect r = bxdf::Reflect::create(V, interaction.getN()); @@ -47,26 +47,26 @@ struct SDeltaDistribution return s; } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) + sample_type 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); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + 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 pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + 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_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + 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 { 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) + 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 { return quotient_and_pdf(_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 4e247c05d8..7ec41aeed5 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/delta_distribution.hlsl @@ -25,16 +25,16 @@ 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) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return hlsl::promote(0); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return hlsl::promote(0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC { ray_dir_info_type L = interaction.getV().transmit(); sample_type s = sample_type::create(L, interaction.getN()); @@ -44,26 +44,26 @@ struct SDeltaDistribution s.NdotL2 = interaction.getNdotV2(); return s; } - sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) + sample_type 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); } - scalar_type pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + 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 pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + 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_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + 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 { 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) + 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 { return quotient_and_pdf(_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 6d5744fb49..bee202dc8d 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission/smooth_dielectric.hlsl @@ -26,16 +26,16 @@ 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) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return hlsl::promote(0); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return hlsl::promote(0); } - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(vector3_type) u) + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(vector3_type) u) NBL_CONST_MEMBER_FUNC { const scalar_type reflectance = fresnel::Dielectric::__call(orientedEta.value*orientedEta.value, interaction.getNdotV(_clamp))[0]; @@ -51,27 +51,27 @@ 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) + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, NBL_REF_ARG(vector3_type) u) NBL_CONST_MEMBER_FUNC { 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) + 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 pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + 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_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + 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 { 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) + 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 { return quotient_and_pdf(_sample, interaction.isotropic); } @@ -105,11 +105,11 @@ struct SThinSmoothDielectric return retval; } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return hlsl::promote(0); } - spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + spectral_type eval(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) NBL_CONST_MEMBER_FUNC { return hlsl::promote(0); } @@ -118,7 +118,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_pdf` - sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u, NBL_REF_ARG(spectral_type) remainderMetadata) + 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 const spectral_type reflectance = fresnel::thinDielectricInfiniteScatter(fresnel(interaction.getNdotV(_clamp))); @@ -140,27 +140,27 @@ 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) + sample_type generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_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) + sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC { 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) + 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 pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction) + 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_pdf(NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(isotropic_interaction_type) interaction) + 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 { const bool transmitted = ComputeMicrofacetNormal::isTransmissionPath(interaction.getNdotV(), _sample.getNdotL()); const spectral_type reflectance = fresnel::thinDielectricInfiniteScatter(fresnel(interaction.getNdotV(_clamp))); @@ -171,7 +171,7 @@ 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) + 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 { return quotient_and_pdf(_sample, interaction.isotropic); } diff --git a/include/nbl/builtin/hlsl/math/quadrature/adaptive_simpson.hlsl b/include/nbl/builtin/hlsl/math/quadrature/adaptive_simpson.hlsl new file mode 100644 index 0000000000..b480397057 --- /dev/null +++ b/include/nbl/builtin/hlsl/math/quadrature/adaptive_simpson.hlsl @@ -0,0 +1,171 @@ +// Copyright (C) 2018-2025 - 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_MATH_QUADRATURE_ADAPTIVE_SIMPSON_INCLUDED_ +#define _NBL_BUILTIN_HLSL_MATH_QUADRATURE_ADAPTIVE_SIMPSON_INCLUDED_ + +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace math +{ +namespace quadrature +{ + +namespace impl +{ +template // F has function __call(x) +struct integrate_helper +{ + static float_t __call(NBL_CONST_REF_ARG(F) f, float_t a, float_t b, float_t c, float_t fa, float_t fb, float_t fc, float_t I, float_t eps, NBL_REF_ARG(int) count) + { + float_t d = float_t(0.5) * (a + b); + float_t e = float_t(0.5) * (b + c); + float_t fd = f(d); + float_t fe = f(e); + + float_t h = c - a; + float_t I0 = (float_t(1.0) / float_t(12.0)) * h * (fa + float_t(4.0) * fd + fb); + float_t I1 = (float_t(1.0) / float_t(12.0)) * h * (fb + float_t(4.0) * fe + fc); + float_t Ip = I0 + I1; + count++; + + if (hlsl::abs(Ip - I) < float_t(15.0) * eps) + return Ip + (float_t(1.0) / float_t(15.0)) * (Ip - I); + + return integrate_helper::__call(f, a, d, b, fa, fd, fb, I0, float_t(0.5) * eps, count) + + integrate_helper::__call(f, b, e, c, fb, fe, fc, I1, float_t(0.5) * eps, count); + } +}; + +template +struct integrate_helper +{ + static float_t __call(NBL_CONST_REF_ARG(F) f, float_t a, float_t b, float_t c, float_t fa, float_t fb, float_t fc, float_t I, float_t eps, NBL_REF_ARG(int) count) + { + float_t d = float_t(0.5) * (a + b); + float_t e = float_t(0.5) * (b + c); + float_t fd = f(d); + float_t fe = f(e); + + float_t h = c - a; + float_t I0 = (float_t(1.0) / float_t(12.0)) * h * (fa + float_t(4.0) * fd + fb); + float_t I1 = (float_t(1.0) / float_t(12.0)) * h * (fb + float_t(4.0) * fe + fc); + float_t Ip = I0 + I1; + count++; + + return Ip + (float_t(1.0) / float_t(15.0)) * (Ip - I); + } +}; + +#define NBL_CONCEPT_NAME FuncOneArg +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename)(typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (F)(T) +#define NBL_CONCEPT_PARAM_0 (func, F) +#define NBL_CONCEPT_PARAM_1 (x, T) +NBL_CONCEPT_BEGIN(2) +#define func NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +#define x NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointScalar, T)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((func(x)), ::nbl::hlsl::is_same_v, T)) +); +#undef x +#undef func +#include +} + +template()(0)), uint32_t Depth=6 NBL_PRIMARY_REQUIRES(impl::FuncOneArg) +struct AdaptiveSimpson +{ + // eps: absolute tolerance on the integral estimate + static float_t __call(NBL_CONST_REF_ARG(F) f, float_t x0, float_t x1, float_t eps = 1e-6) + { + int count = 0; + float_t a = x0; + float_t b = float_t(0.5) * (x0 + x1); + float_t c = x1; + float_t fa = f(a); + float_t fb = f(b); + float_t fc = f(c); + float_t I = (c - a) * (float_t(1.0) / float_t(6.0)) * (fa + float_t(4.0) * fb + fc); + return impl::integrate_helper::__call(f, a, b, c, fa, fb, fc, I, eps, count); + } +}; + + +namespace impl +{ +template +struct InnerIntegrand +{ + float_t operator()(float_t x) NBL_CONST_MEMBER_FUNC + { + return f(x, y); + } + + F f; + float_t y; +}; + +template +struct OuterIntegrand +{ + float_t operator()(float_t y) NBL_CONST_MEMBER_FUNC + { + using func_t = InnerIntegrand; + func_t innerFunc; + innerFunc.f = f; + innerFunc.y = y; + return AdaptiveSimpson::__call(innerFunc, x0, x1, eps); + } + + F f; + float_t x0; + float_t x1; + float_t eps; +}; + +#define NBL_CONCEPT_NAME FuncTwoArgs +#define NBL_CONCEPT_TPLT_PRM_KINDS (typename)(typename) +#define NBL_CONCEPT_TPLT_PRM_NAMES (F)(T) +#define NBL_CONCEPT_PARAM_0 (func, F) +#define NBL_CONCEPT_PARAM_1 (x, T) +NBL_CONCEPT_BEGIN(2) +#define func NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 +#define x NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 +NBL_CONCEPT_END( + ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(concepts::FloatingPointScalar, T)) + ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((func(x,x)), ::nbl::hlsl::is_same_v, T)) +); +#undef x +#undef func +#include +} + +template()(0)), uint32_t Depth=6 NBL_PRIMARY_REQUIRES(impl::FuncTwoArgs) +struct AdaptiveSimpson2D +{ + // eps: absolute tolerance on the integral estimate + static float_t __call(NBL_CONST_REF_ARG(F) f, float32_t2 x0, float32_t2 x1, float_t eps = 1e-6) + { + using func_t = impl::OuterIntegrand; + func_t outerFunc; + outerFunc.f = f; + outerFunc.x0 = x0.x; + outerFunc.x1 = x1.x; + outerFunc.eps = eps; + return AdaptiveSimpson::__call(outerFunc, x0.y, x1.y, eps); + } +}; + +} +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/matrix_utils/transformation_matrix_utils.hlsl b/include/nbl/builtin/hlsl/matrix_utils/transformation_matrix_utils.hlsl deleted file mode 100644 index 1ad16dc28d..0000000000 --- a/include/nbl/builtin/hlsl/matrix_utils/transformation_matrix_utils.hlsl +++ /dev/null @@ -1,235 +0,0 @@ -#ifndef _NBL_BUILTIN_HLSL_TRANSFORMATION_MATRIX_UTILS_INCLUDED_ -#define _NBL_BUILTIN_HLSL_TRANSFORMATION_MATRIX_UTILS_INCLUDED_ - -#include - -namespace nbl -{ -namespace hlsl -{ -//TODO: stolen from cameraz branch, don't have epsilonEqual here, maybe uncomment when merging from imguizmo-lights branch -//// TODO: -> move somewhere else and nbl:: to implement it -//template -//bool isOrthoBase(const T& x, const T& y, const T& z, const E epsilon = 1e-6) -//{ -// auto isNormalized = [](const auto& v, const auto& epsilon) -> bool -// { -// return glm::epsilonEqual(glm::length(v), 1.0, epsilon); -// }; -// -// auto isOrthogonal = [](const auto& a, const auto& b, const auto& epsilon) -> bool -// { -// return glm::epsilonEqual(glm::dot(a, b), 0.0, epsilon); -// }; -// -// return isNormalized(x, epsilon) && isNormalized(y, epsilon) && isNormalized(z, epsilon) && -// isOrthogonal(x, y, epsilon) && isOrthogonal(x, z, epsilon) && isOrthogonal(y, z, epsilon); -//} -//// <- - -template -matrix getMatrix3x4As4x4(const matrix& mat) -{ - matrix output; - for (int i = 0; i < 3; ++i) - output[i] = mat[i]; - output[3] = float32_t4(0.0f, 0.0f, 0.0f, 1.0f); - - return output; -} - -template -matrix getMatrix3x3As4x4(const matrix& mat) -{ - matrix output; - for (int i = 0; i < 3; ++i) - output[i] = float32_t4(mat[i], 1.0f); - output[3] = float32_t4(0.0f, 0.0f, 0.0f, 1.0f); - - return output; -} - -template -inline vector getCastedVector(const vector& in) -{ - vector out; - - for (int i = 0; i < N; ++i) - out[i] = (Tout)(in[i]); - - return out; -} - -template -inline matrix getCastedMatrix(const matrix& in) -{ - matrix out; - - for (int i = 0; i < N; ++i) - out[i] = getCastedVector(in[i]); - - return out; -} - -// TODO: use portable_float when merged -//! multiplies matrices a and b, 3x4 matrices are treated as 4x4 matrices with 4th row set to (0, 0, 0 ,1) -template -inline matrix concatenateBFollowedByA(const matrix& a, const matrix& b) -{ - const auto a4x4 = getMatrix3x4As4x4(a); - const auto b4x4 = getMatrix3x4As4x4(b); - return matrix(mul(a4x4, b4x4)); -} - -// /Arek: glm:: for normalize till dot product is fixed (ambiguity with glm namespace + linker issues) - -template -inline matrix buildCameraLookAtMatrixLH( - const vector& position, - const vector& target, - const vector& upVector) -{ - const vector zaxis = glm::normalize(target - position); - const vector xaxis = glm::normalize(hlsl::cross(upVector, zaxis)); - const vector yaxis = hlsl::cross(zaxis, xaxis); - - matrix r; - r[0] = vector(xaxis, -hlsl::dot(xaxis, position)); - r[1] = vector(yaxis, -hlsl::dot(yaxis, position)); - r[2] = vector(zaxis, -hlsl::dot(zaxis, position)); - - return r; -} - -template -inline matrix buildCameraLookAtMatrixRH( - const vector& position, - const vector& target, - const vector& upVector) -{ - const vector zaxis = glm::normalize(position - target); - const vector xaxis = glm::normalize(hlsl::cross(upVector, zaxis)); - const vector yaxis = hlsl::cross(zaxis, xaxis); - - matrix r; - r[0] = vector(xaxis, -hlsl::dot(xaxis, position)); - r[1] = vector(yaxis, -hlsl::dot(yaxis, position)); - r[2] = vector(zaxis, -hlsl::dot(zaxis, position)); - - return r; -} - -// TODO: test, check if there is better implementation -// TODO: move quaternion to nbl::hlsl -// TODO: why NBL_REF_ARG(MatType) doesn't work????? - -//! Replaces curent rocation and scale by rotation represented by quaternion `quat`, leaves 4th row and 4th colum unchanged -template -inline void setRotation(matrix& outMat, NBL_CONST_REF_ARG(core::quaternion) quat) -{ - static_assert(N == 3 || N == 4); - - outMat[0] = vector( - 1 - 2 * (quat.y * quat.y + quat.z * quat.z), - 2 * (quat.x * quat.y - quat.z * quat.w), - 2 * (quat.x * quat.z + quat.y * quat.w), - outMat[0][3] - ); - - outMat[1] = vector( - 2 * (quat.x * quat.y + quat.z * quat.w), - 1 - 2 * (quat.x * quat.x + quat.z * quat.z), - 2 * (quat.y * quat.z - quat.x * quat.w), - outMat[1][3] - ); - - outMat[2] = vector( - 2 * (quat.x * quat.z - quat.y * quat.w), - 2 * (quat.y * quat.z + quat.x * quat.w), - 1 - 2 * (quat.x * quat.x + quat.y * quat.y), - outMat[2][3] - ); -} - -template -inline void setTranslation(matrix& outMat, NBL_CONST_REF_ARG(vector) translation) -{ - static_assert(N == 3 || N == 4); - - outMat[0].w = translation.x; - outMat[1].w = translation.y; - outMat[2].w = translation.z; -} - - -template -inline matrix buildProjectionMatrixPerspectiveFovRH(float fieldOfViewRadians, float aspectRatio, float zNear, float zFar) -{ - const float h = core::reciprocal(tanf(fieldOfViewRadians * 0.5f)); - _NBL_DEBUG_BREAK_IF(aspectRatio == 0.f); //division by zero - const float w = h / aspectRatio; - - _NBL_DEBUG_BREAK_IF(zNear == zFar); //division by zero - - matrix m; - m[0] = vector(w, 0.f, 0.f, 0.f); - m[1] = vector(0.f, -h, 0.f, 0.f); - m[2] = vector(0.f, 0.f, -zFar / (zFar - zNear), -zNear * zFar / (zFar - zNear)); - m[3] = vector(0.f, 0.f, -1.f, 0.f); - - return m; -} -template -inline matrix buildProjectionMatrixPerspectiveFovLH(float fieldOfViewRadians, float aspectRatio, float zNear, float zFar) -{ - const float h = core::reciprocal(tanf(fieldOfViewRadians * 0.5f)); - _NBL_DEBUG_BREAK_IF(aspectRatio == 0.f); //division by zero - const float w = h / aspectRatio; - - _NBL_DEBUG_BREAK_IF(zNear == zFar); //division by zero - - matrix m; - m[0] = vector(w, 0.f, 0.f, 0.f); - m[1] = vector(0.f, -h, 0.f, 0.f); - m[2] = vector(0.f, 0.f, zFar / (zFar - zNear), -zNear * zFar / (zFar - zNear)); - m[3] = vector(0.f, 0.f, 1.f, 0.f); - - return m; -} - -template -inline matrix buildProjectionMatrixOrthoRH(float widthOfViewVolume, float heightOfViewVolume, float zNear, float zFar) -{ - _NBL_DEBUG_BREAK_IF(widthOfViewVolume == 0.f); //division by zero - _NBL_DEBUG_BREAK_IF(heightOfViewVolume == 0.f); //division by zero - _NBL_DEBUG_BREAK_IF(zNear == zFar); //division by zero - - matrix m; - m[0] = vector(2.f / widthOfViewVolume, 0.f, 0.f, 0.f); - m[1] = vector(0.f, -2.f / heightOfViewVolume, 0.f, 0.f); - m[2] = vector(0.f, 0.f, -1.f / (zFar - zNear), -zNear / (zFar - zNear)); - m[3] = vector(0.f, 0.f, 0.f, 1.f); - - return m; -} - -template -inline matrix buildProjectionMatrixOrthoLH(float widthOfViewVolume, float heightOfViewVolume, float zNear, float zFar) -{ - _NBL_DEBUG_BREAK_IF(widthOfViewVolume == 0.f); //division by zero - _NBL_DEBUG_BREAK_IF(heightOfViewVolume == 0.f); //division by zero - _NBL_DEBUG_BREAK_IF(zNear == zFar); //division by zero - - matrix m; - m[0] = vector(2.f / widthOfViewVolume, 0.f, 0.f, 0.f); - m[1] = vector(0.f, -2.f / heightOfViewVolume, 0.f, 0.f); - m[2] = vector(0.f, 0.f, 1.f / (zFar - zNear), -zNear / (zFar - zNear)); - m[3] = vector(0.f, 0.f, 0.f, 1.f); - - return m; -} - -} -} - -#endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/random/dim_adaptor_recursive.hlsl b/include/nbl/builtin/hlsl/random/dim_adaptor_recursive.hlsl index cb0b522e68..cc933daa6c 100644 --- a/include/nbl/builtin/hlsl/random/dim_adaptor_recursive.hlsl +++ b/include/nbl/builtin/hlsl/random/dim_adaptor_recursive.hlsl @@ -18,14 +18,7 @@ struct DimAdaptorRecursive using rng_type = RNG; using return_type = vector; - static DimAdaptorRecursive construct(NBL_REF_ARG(rng_type) rng) - { - DimAdaptorRecursive retval; - retval.rng = rng; - return retval; - } - - return_type operator()() + static return_type __call(NBL_REF_ARG(rng_type) rng) { array_set setter; @@ -34,8 +27,6 @@ struct DimAdaptorRecursive setter(retval, i, rng()); return retval; } - - rng_type rng; }; } diff --git a/include/nbl/builtin/hlsl/tgmath.hlsl b/include/nbl/builtin/hlsl/tgmath.hlsl index 04765f3ba7..c569d34f85 100644 --- a/include/nbl/builtin/hlsl/tgmath.hlsl +++ b/include/nbl/builtin/hlsl/tgmath.hlsl @@ -249,6 +249,12 @@ inline T beta(NBL_CONST_REF_ARG(T) v1, NBL_CONST_REF_ARG(T) v2) return tgmath_impl::beta_helper::__call(v1, v2)/tgmath_impl::beta_helper::__call(T(1.0), T(1.0)); // ensure beta(1,1)==1 } +template +inline T gamma(NBL_CONST_REF_ARG(T) a, NBL_CONST_REF_ARG(T) x) +{ + return tgmath_impl::gamma_helper::__call(a, x); +} + } } diff --git a/include/nbl/builtin/hlsl/tgmath/impl.hlsl b/include/nbl/builtin/hlsl/tgmath/impl.hlsl index 93cbf0db13..4d1a30c757 100644 --- a/include/nbl/builtin/hlsl/tgmath/impl.hlsl +++ b/include/nbl/builtin/hlsl/tgmath/impl.hlsl @@ -98,6 +98,8 @@ template struct lgamma_helper; template struct beta_helper; +template +struct gamma_helper; #ifdef __HLSL_VERSION @@ -606,6 +608,88 @@ struct beta_helper) > } }; +// incomplete gamma function +template +NBL_PARTIAL_REQ_TOP(concepts::FloatingPointScalar) +struct gamma_helper) > +{ + NBL_CONSTEXPR_STATIC_INLINE T epsilon = 1e-15; + NBL_CONSTEXPR_STATIC_INLINE T big = 4503599627370496.0; + NBL_CONSTEXPR_STATIC_INLINE T bigInv = 2.22044604925031308085e-16; + + static T __call(T a, T x) + { + assert(a >= T(0.0) && x >= T(0.0)); + + if (x == T(0.0)) + return T(0.0); + + T ax = (a * log_helper::__call(x)) - x - lgamma_helper::__call(a); + if (ax < T(-709.78271289338399)) + return hlsl::mix(T(0.0), T(1.0), a < x); + + if (x <= T(1.0) || x <= a) + { + T r2 = a; + T c2 = T(1.0); + T ans2 = T(1.0); + + do { + r2 = r2 + T(1.0); + c2 = c2 * x / r2; + ans2 += c2; + } while ((c2 / ans2) > epsilon); + + return exp_helper::__call(ax) * ans2 / a; + } + + int c = 0; + T y = T(1.0) - a; + T z = x + y + T(1.0); + T p3 = T(1.0); + T q3 = x; + T p2 = x + T(1.0); + T q2 = z * x; + T ans = p2 / q2; + T error; + + do { + c++; + y += T(1.0); + z += T(2.0); + T yc = y * c; + T p = (p2 * z) - (p3 * yc); + T q = (q2 * z) - (q3 * yc); + + if (q != T(0.0)) + { + T nextans = p / q; + error = abs_helper::__call((ans - nextans) / nextans); + ans = nextans; + } + else + { + error = 1; + } + + p3 = p2; + p2 = p; + q3 = q2; + q2 = q; + + if (abs_helper::__call(p) > big) + { + p3 *= bigInv; + p2 *= bigInv; + q3 *= bigInv; + q2 *= bigInv; + } + } while (error > epsilon); + + return T(1.0) - (exp_helper::__call(ax) * ans); + } +}; + #ifdef __HLSL_VERSION // SPIR-V already defines specializations for builtin vector types #define VECTOR_SPECIALIZATION_CONCEPT concepts::Vectorial && !is_vector_v diff --git a/include/nbl/builtin/hlsl/visualization/turbo.hlsl b/include/nbl/builtin/hlsl/visualization/turbo.hlsl new file mode 100644 index 0000000000..d8ab2a8df6 --- /dev/null +++ b/include/nbl/builtin/hlsl/visualization/turbo.hlsl @@ -0,0 +1,294 @@ +// Copyright (C) 2018-2025 - 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_VISUALIZATION_TURBO_INCLUDED_ +#define _NBL_BUILTIN_HLSL_VISUALIZATION_TURBO_INCLUDED_ + +#include + +namespace nbl +{ +namespace hlsl +{ +namespace visualization +{ + +// from Google's Turbo colormap: https://gist.github.com/mikhailov-work/6a308c20e494d9e0ccc29036b28faa7a +struct Turbo +{ + static const float32_t3 RGB_LUT[256]; + + static float32_t3 __call(float x) + { + x = hlsl::clamp(x, 0.f, 1.f); + int i = int(x * 255.f); + int j = hlsl::min(255, i+1); + float s = x * 255.f - float(i); + return RGB_LUT[i] + (RGB_LUT[j] - RGB_LUT[i]) * s; + } +}; + +NBL_CONSTEXPR_INLINE_OOL_MEMBER float32_t3 Turbo::RGB_LUT[256] = { + float32_t3(0.18995,0.07176,0.23217), + float32_t3(0.19483,0.08339,0.26149), + float32_t3(0.19956,0.09498,0.29024), + float32_t3(0.20415,0.10652,0.31844), + float32_t3(0.20860,0.11802,0.34607), + float32_t3(0.21291,0.12947,0.37314), + float32_t3(0.21708,0.14087,0.39964), + float32_t3(0.22111,0.15223,0.42558), + float32_t3(0.22500,0.16354,0.45096), + float32_t3(0.22875,0.17481,0.47578), + float32_t3(0.23236,0.18603,0.50004), + float32_t3(0.23582,0.19720,0.52373), + float32_t3(0.23915,0.20833,0.54686), + float32_t3(0.24234,0.21941,0.56942), + float32_t3(0.24539,0.23044,0.59142), + float32_t3(0.24830,0.24143,0.61286), + float32_t3(0.25107,0.25237,0.63374), + float32_t3(0.25369,0.26327,0.65406), + float32_t3(0.25618,0.27412,0.67381), + float32_t3(0.25853,0.28492,0.69300), + float32_t3(0.26074,0.29568,0.71162), + float32_t3(0.26280,0.30639,0.72968), + float32_t3(0.26473,0.31706,0.74718), + float32_t3(0.26652,0.32768,0.76412), + float32_t3(0.26816,0.33825,0.78050), + float32_t3(0.26967,0.34878,0.79631), + float32_t3(0.27103,0.35926,0.81156), + float32_t3(0.27226,0.36970,0.82624), + float32_t3(0.27334,0.38008,0.84037), + float32_t3(0.27429,0.39043,0.85393), + float32_t3(0.27509,0.40072,0.86692), + float32_t3(0.27576,0.41097,0.87936), + float32_t3(0.27628,0.42118,0.89123), + float32_t3(0.27667,0.43134,0.90254), + float32_t3(0.27691,0.44145,0.91328), + float32_t3(0.27701,0.45152,0.92347), + float32_t3(0.27698,0.46153,0.93309), + float32_t3(0.27680,0.47151,0.94214), + float32_t3(0.27648,0.48144,0.95064), + float32_t3(0.27603,0.49132,0.95857), + float32_t3(0.27543,0.50115,0.96594), + float32_t3(0.27469,0.51094,0.97275), + float32_t3(0.27381,0.52069,0.97899), + float32_t3(0.27273,0.53040,0.98461), + float32_t3(0.27106,0.54015,0.98930), + float32_t3(0.26878,0.54995,0.99303), + float32_t3(0.26592,0.55979,0.99583), + float32_t3(0.26252,0.56967,0.99773), + float32_t3(0.25862,0.57958,0.99876), + float32_t3(0.25425,0.58950,0.99896), + float32_t3(0.24946,0.59943,0.99835), + float32_t3(0.24427,0.60937,0.99697), + float32_t3(0.23874,0.61931,0.99485), + float32_t3(0.23288,0.62923,0.99202), + float32_t3(0.22676,0.63913,0.98851), + float32_t3(0.22039,0.64901,0.98436), + float32_t3(0.21382,0.65886,0.97959), + float32_t3(0.20708,0.66866,0.97423), + float32_t3(0.20021,0.67842,0.96833), + float32_t3(0.19326,0.68812,0.96190), + float32_t3(0.18625,0.69775,0.95498), + float32_t3(0.17923,0.70732,0.94761), + float32_t3(0.17223,0.71680,0.93981), + float32_t3(0.16529,0.72620,0.93161), + float32_t3(0.15844,0.73551,0.92305), + float32_t3(0.15173,0.74472,0.91416), + float32_t3(0.14519,0.75381,0.90496), + float32_t3(0.13886,0.76279,0.89550), + float32_t3(0.13278,0.77165,0.88580), + float32_t3(0.12698,0.78037,0.87590), + float32_t3(0.12151,0.78896,0.86581), + float32_t3(0.11639,0.79740,0.85559), + float32_t3(0.11167,0.80569,0.84525), + float32_t3(0.10738,0.81381,0.83484), + float32_t3(0.10357,0.82177,0.82437), + float32_t3(0.10026,0.82955,0.81389), + float32_t3(0.09750,0.83714,0.80342), + float32_t3(0.09532,0.84455,0.79299), + float32_t3(0.09377,0.85175,0.78264), + float32_t3(0.09287,0.85875,0.77240), + float32_t3(0.09267,0.86554,0.76230), + float32_t3(0.09320,0.87211,0.75237), + float32_t3(0.09451,0.87844,0.74265), + float32_t3(0.09662,0.88454,0.73316), + float32_t3(0.09958,0.89040,0.72393), + float32_t3(0.10342,0.89600,0.71500), + float32_t3(0.10815,0.90142,0.70599), + float32_t3(0.11374,0.90673,0.69651), + float32_t3(0.12014,0.91193,0.68660), + float32_t3(0.12733,0.91701,0.67627), + float32_t3(0.13526,0.92197,0.66556), + float32_t3(0.14391,0.92680,0.65448), + float32_t3(0.15323,0.93151,0.64308), + float32_t3(0.16319,0.93609,0.63137), + float32_t3(0.17377,0.94053,0.61938), + float32_t3(0.18491,0.94484,0.60713), + float32_t3(0.19659,0.94901,0.59466), + float32_t3(0.20877,0.95304,0.58199), + float32_t3(0.22142,0.95692,0.56914), + float32_t3(0.23449,0.96065,0.55614), + float32_t3(0.24797,0.96423,0.54303), + float32_t3(0.26180,0.96765,0.52981), + float32_t3(0.27597,0.97092,0.51653), + float32_t3(0.29042,0.97403,0.50321), + float32_t3(0.30513,0.97697,0.48987), + float32_t3(0.32006,0.97974,0.47654), + float32_t3(0.33517,0.98234,0.46325), + float32_t3(0.35043,0.98477,0.45002), + float32_t3(0.36581,0.98702,0.43688), + float32_t3(0.38127,0.98909,0.42386), + float32_t3(0.39678,0.99098,0.41098), + float32_t3(0.41229,0.99268,0.39826), + float32_t3(0.42778,0.99419,0.38575), + float32_t3(0.44321,0.99551,0.37345), + float32_t3(0.45854,0.99663,0.36140), + float32_t3(0.47375,0.99755,0.34963), + float32_t3(0.48879,0.99828,0.33816), + float32_t3(0.50362,0.99879,0.32701), + float32_t3(0.51822,0.99910,0.31622), + float32_t3(0.53255,0.99919,0.30581), + float32_t3(0.54658,0.99907,0.29581), + float32_t3(0.56026,0.99873,0.28623), + float32_t3(0.57357,0.99817,0.27712), + float32_t3(0.58646,0.99739,0.26849), + float32_t3(0.59891,0.99638,0.26038), + float32_t3(0.61088,0.99514,0.25280), + float32_t3(0.62233,0.99366,0.24579), + float32_t3(0.63323,0.99195,0.23937), + float32_t3(0.64362,0.98999,0.23356), + float32_t3(0.65394,0.98775,0.22835), + float32_t3(0.66428,0.98524,0.22370), + float32_t3(0.67462,0.98246,0.21960), + float32_t3(0.68494,0.97941,0.21602), + float32_t3(0.69525,0.97610,0.21294), + float32_t3(0.70553,0.97255,0.21032), + float32_t3(0.71577,0.96875,0.20815), + float32_t3(0.72596,0.96470,0.20640), + float32_t3(0.73610,0.96043,0.20504), + float32_t3(0.74617,0.95593,0.20406), + float32_t3(0.75617,0.95121,0.20343), + float32_t3(0.76608,0.94627,0.20311), + float32_t3(0.77591,0.94113,0.20310), + float32_t3(0.78563,0.93579,0.20336), + float32_t3(0.79524,0.93025,0.20386), + float32_t3(0.80473,0.92452,0.20459), + float32_t3(0.81410,0.91861,0.20552), + float32_t3(0.82333,0.91253,0.20663), + float32_t3(0.83241,0.90627,0.20788), + float32_t3(0.84133,0.89986,0.20926), + float32_t3(0.85010,0.89328,0.21074), + float32_t3(0.85868,0.88655,0.21230), + float32_t3(0.86709,0.87968,0.21391), + float32_t3(0.87530,0.87267,0.21555), + float32_t3(0.88331,0.86553,0.21719), + float32_t3(0.89112,0.85826,0.21880), + float32_t3(0.89870,0.85087,0.22038), + float32_t3(0.90605,0.84337,0.22188), + float32_t3(0.91317,0.83576,0.22328), + float32_t3(0.92004,0.82806,0.22456), + float32_t3(0.92666,0.82025,0.22570), + float32_t3(0.93301,0.81236,0.22667), + float32_t3(0.93909,0.80439,0.22744), + float32_t3(0.94489,0.79634,0.22800), + float32_t3(0.95039,0.78823,0.22831), + float32_t3(0.95560,0.78005,0.22836), + float32_t3(0.96049,0.77181,0.22811), + float32_t3(0.96507,0.76352,0.22754), + float32_t3(0.96931,0.75519,0.22663), + float32_t3(0.97323,0.74682,0.22536), + float32_t3(0.97679,0.73842,0.22369), + float32_t3(0.98000,0.73000,0.22161), + float32_t3(0.98289,0.72140,0.21918), + float32_t3(0.98549,0.71250,0.21650), + float32_t3(0.98781,0.70330,0.21358), + float32_t3(0.98986,0.69382,0.21043), + float32_t3(0.99163,0.68408,0.20706), + float32_t3(0.99314,0.67408,0.20348), + float32_t3(0.99438,0.66386,0.19971), + float32_t3(0.99535,0.65341,0.19577), + float32_t3(0.99607,0.64277,0.19165), + float32_t3(0.99654,0.63193,0.18738), + float32_t3(0.99675,0.62093,0.18297), + float32_t3(0.99672,0.60977,0.17842), + float32_t3(0.99644,0.59846,0.17376), + float32_t3(0.99593,0.58703,0.16899), + float32_t3(0.99517,0.57549,0.16412), + float32_t3(0.99419,0.56386,0.15918), + float32_t3(0.99297,0.55214,0.15417), + float32_t3(0.99153,0.54036,0.14910), + float32_t3(0.98987,0.52854,0.14398), + float32_t3(0.98799,0.51667,0.13883), + float32_t3(0.98590,0.50479,0.13367), + float32_t3(0.98360,0.49291,0.12849), + float32_t3(0.98108,0.48104,0.12332), + float32_t3(0.97837,0.46920,0.11817), + float32_t3(0.97545,0.45740,0.11305), + float32_t3(0.97234,0.44565,0.10797), + float32_t3(0.96904,0.43399,0.10294), + float32_t3(0.96555,0.42241,0.09798), + float32_t3(0.96187,0.41093,0.09310), + float32_t3(0.95801,0.39958,0.08831), + float32_t3(0.95398,0.38836,0.08362), + float32_t3(0.94977,0.37729,0.07905), + float32_t3(0.94538,0.36638,0.07461), + float32_t3(0.94084,0.35566,0.07031), + float32_t3(0.93612,0.34513,0.06616), + float32_t3(0.93125,0.33482,0.06218), + float32_t3(0.92623,0.32473,0.05837), + float32_t3(0.92105,0.31489,0.05475), + float32_t3(0.91572,0.30530,0.05134), + float32_t3(0.91024,0.29599,0.04814), + float32_t3(0.90463,0.28696,0.04516), + float32_t3(0.89888,0.27824,0.04243), + float32_t3(0.89298,0.26981,0.03993), + float32_t3(0.88691,0.26152,0.03753), + float32_t3(0.88066,0.25334,0.03521), + float32_t3(0.87422,0.24526,0.03297), + float32_t3(0.86760,0.23730,0.03082), + float32_t3(0.86079,0.22945,0.02875), + float32_t3(0.85380,0.22170,0.02677), + float32_t3(0.84662,0.21407,0.02487), + float32_t3(0.83926,0.20654,0.02305), + float32_t3(0.83172,0.19912,0.02131), + float32_t3(0.82399,0.19182,0.01966), + float32_t3(0.81608,0.18462,0.01809), + float32_t3(0.80799,0.17753,0.01660), + float32_t3(0.79971,0.17055,0.01520), + float32_t3(0.79125,0.16368,0.01387), + float32_t3(0.78260,0.15693,0.01264), + float32_t3(0.77377,0.15028,0.01148), + float32_t3(0.76476,0.14374,0.01041), + float32_t3(0.75556,0.13731,0.00942), + float32_t3(0.74617,0.13098,0.00851), + float32_t3(0.73661,0.12477,0.00769), + float32_t3(0.72686,0.11867,0.00695), + float32_t3(0.71692,0.11268,0.00629), + float32_t3(0.70680,0.10680,0.00571), + float32_t3(0.69650,0.10102,0.00522), + float32_t3(0.68602,0.09536,0.00481), + float32_t3(0.67535,0.08980,0.00449), + float32_t3(0.66449,0.08436,0.00424), + float32_t3(0.65345,0.07902,0.00408), + float32_t3(0.64223,0.07380,0.00401), + float32_t3(0.63082,0.06868,0.00401), + float32_t3(0.61923,0.06367,0.00410), + float32_t3(0.60746,0.05878,0.00427), + float32_t3(0.59550,0.05399,0.00453), + float32_t3(0.58336,0.04931,0.00486), + float32_t3(0.57103,0.04474,0.00529), + float32_t3(0.55852,0.04028,0.00579), + float32_t3(0.54583,0.03593,0.00638), + float32_t3(0.53295,0.03169,0.00705), + float32_t3(0.51989,0.02756,0.00780), + float32_t3(0.50664,0.02354,0.00863), + float32_t3(0.49321,0.01963,0.00955), + float32_t3(0.47960,0.01583,0.01055) +}; + +} +} +} + +#endif diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 9a439987b5..c8e8898534 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -237,6 +237,7 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/equations/quartic.hlsl") #extra math LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/quadrature/gauss_legendre/gauss_legendre.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/quadrature/gauss_legendre/impl.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/quadrature/adaptive_simpson.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/math/thin_lens_projection.hlsl") #acceleration structures LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/acceleration_structures.hlsl") @@ -246,6 +247,8 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace/OETF.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace/decodeCIEXYZ.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace/encodeCIEXYZ.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/colorspace.hlsl") +#visualization +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/visualization/turbo.hlsl") #barycentrics LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/barycentric/utils.hlsl") #scanning append