-
Notifications
You must be signed in to change notification settings - Fork 69
Resampled Importance Sampling bxdfs #1027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: sampler-concepts
Are you sure you want to change the base?
Changes from all commits
5def0b4
f93f430
1a7bf02
0dc31aa
8aff0f7
1b0b6f3
6a4e8df
0c1e045
850536c
011e7f0
2b34047
2d3719f
ad0cf8d
5d2568b
c86f8e1
4871e24
1f73d6a
e4df2b2
66da590
f830a47
00017ad
83e30e4
067d107
fc6deb8
c292f41
1a3d26a
0afd2fa
f2e2265
0708859
b609179
63cd4df
59e090e
a877934
64ce3ba
2539522
148b9bd
95a3862
946c9c7
4f4421d
a70f420
dab4a18
fb878a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -83,7 +83,9 @@ 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<IsBSDF, vector3_type, vector2_type>; | ||
| NBL_HLSL_BXDF_ANISOTROPIC_COND_DECLS(IsAnisotropic); | ||
| using evalcache_type = conditional_t<IsAnisotropic,anisocache_type,isocache_type>; | ||
|
|
||
| // utility functions | ||
| template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>, | ||
|
|
@@ -156,19 +158,21 @@ struct SCookTorrance | |
| template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>, | ||
| class MicrofacetCache=conditional_t<IsAnisotropic,anisocache_type,isocache_type> | ||
| NBL_FUNC_REQUIRES(RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>) | ||
| 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<Interaction, MicrofacetCache>(_f, _sample, interaction, cache)) | ||
| return hlsl::promote<spectral_type>(0.0); | ||
| return quotient_pdf_type::create(scalar_type(0.0), scalar_type(0.0)); | ||
|
|
||
| bool isInfinity; | ||
| scalar_type _pdf = __forwardPdf<Interaction, MicrofacetCache>(_sample, interaction, cache, isInfinity); | ||
|
|
||
| using quant_query_type = typename ndf_type::quant_query_type; | ||
| quant_query_type qq = impl::quant_query_helper<ndf_type, fresnel_type, IsBSDF>::template __call<Interaction, MicrofacetCache>(ndf, _f, interaction, cache); | ||
|
|
||
| using g2g1_query_type = typename ndf_type::g2g1_query_type; | ||
| g2g1_query_type gq = ndf.template createG2G1Query<sample_type, Interaction>(_sample, interaction); | ||
|
|
||
| bool isInfinity; | ||
| quant_type D = ndf.template D<sample_type, Interaction, MicrofacetCache>(qq, _sample, interaction, cache, isInfinity); | ||
| scalar_type DG = D.projectedLightMeasure; | ||
| if (!isInfinity) | ||
|
|
@@ -179,19 +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 hlsl::promote<spectral_type>(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); | ||
|
Comment on lines
188
to
190
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you only need this to call which we already would have had
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it doesn't compute it for you in the BRDF case, but you don't ened to have this whole tempvar and clamp it then |
||
|
|
||
| spectral_type quo; | ||
| NBL_IF_CONSTEXPR(IsBSDF) | ||
| { | ||
| const spectral_type reflectance = impl::__implicit_promote<spectral_type, typename fresnel_type::vector_type>::__call(_f(clampedVdotH)); | ||
| return hlsl::mix(reflectance, hlsl::promote<spectral_type>(1.0) - reflectance, cache.isTransmission()) * DG; | ||
| quo = hlsl::mix(reflectance, hlsl::promote<spectral_type>(1.0) - reflectance, cache.isTransmission()) * DG; | ||
| } | ||
| else | ||
| return impl::__implicit_promote<spectral_type, typename fresnel_type::vector_type>::__call(_f(clampedVdotH)) * DG; | ||
| quo = impl::__implicit_promote<spectral_type, typename fresnel_type::vector_type>::__call(_f(clampedVdotH)) * DG; | ||
|
|
||
| return quotient_pdf_type::create(quo, _pdf); | ||
| } | ||
|
|
||
|
Comment on lines
191
to
196
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in combination with previous comment it would simplify to NBL_IF_CONSTEXPR(fresnel_type::IsBSDF)
{
NBL_IF_CONSTEXPR(fresnel_type::ReturnsMonochrome)
{
quo = pdfRetval.reflectance;
}
else
{
quo = mix(pdfRetval.reflectance,hlsl::promote<spectral_type>(1.0) - pdfRetval.reflectance, cache.isTransmission();
}
}
else
quo =impl::__implicit_promote<spectral_type, typename fresnel_type::vector_type>::__call( _f(cache.getVdotH()));
quo *= DG;with |
||
| sample_type __generate_common(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type localH, | ||
|
|
@@ -245,7 +252,7 @@ struct SCookTorrance | |
| return sample_type::create(L, T, B, NdotL); | ||
| } | ||
| template<typename C=bool_constant<!IsBSDF> 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<scalar_type>::min) | ||
|
|
@@ -275,7 +282,7 @@ struct SCookTorrance | |
| return s; | ||
| } | ||
| template<typename C=bool_constant<IsBSDF> 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; | ||
|
|
@@ -332,7 +339,7 @@ struct SCookTorrance | |
| return s; | ||
| } | ||
| template<typename C=bool_constant<!IsAnisotropic> NBL_FUNC_REQUIRES(C::value && !IsAnisotropic) | ||
| sample_type generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const conditional_t<IsBSDF, vector3_type, vector2_type> 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); | ||
|
|
@@ -341,7 +348,7 @@ struct SCookTorrance | |
| } | ||
|
|
||
| template<class Interaction, class MicrofacetCache> | ||
| 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; | ||
|
|
@@ -366,27 +373,27 @@ struct SCookTorrance | |
| template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>, | ||
| class MicrofacetCache=conditional_t<IsAnisotropic,anisocache_type,isocache_type> | ||
| NBL_FUNC_REQUIRES(RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>) | ||
| 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<Interaction, MicrofacetCache>(_f, _sample, interaction, cache)) | ||
| return scalar_type(0.0); | ||
|
|
||
| bool isInfinity; | ||
| scalar_type _pdf = __pdf<Interaction, MicrofacetCache>(_sample, interaction, cache, isInfinity); | ||
| scalar_type _pdf = __forwardPdf<Interaction, MicrofacetCache>(_sample, interaction, cache, isInfinity); | ||
| return hlsl::mix(_pdf, scalar_type(0.0), isInfinity); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is incorrect, it should return INF for forward, it was only backward when it was not meant to (hence why I asked for the distinction) |
||
| } | ||
|
|
||
| template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>, | ||
| class MicrofacetCache=conditional_t<IsAnisotropic,anisocache_type,isocache_type> | ||
| NBL_FUNC_REQUIRES(RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>) | ||
| 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 | ||
|
|
||
| bool isInfinity; | ||
| scalar_type _pdf = __pdf<Interaction, MicrofacetCache>(_sample, interaction, cache, isInfinity); | ||
| scalar_type _pdf = __forwardPdf<Interaction, MicrofacetCache>(_sample, interaction, cache, isInfinity); | ||
| fresnel_type _f = __getOrientedFresnel(fresnel, interaction.getNdotV()); | ||
|
|
||
| const bool valid = __checkValid<Interaction, MicrofacetCache>(_f, _sample, interaction, cache); | ||
|
|
@@ -436,6 +443,7 @@ struct traits<SCookTorrance<Config,N,F> > | |
| 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; | ||
| }; | ||
|
|
||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,58 +23,59 @@ struct SLambertianBase | |
| using this_t = SLambertianBase<Config, IsBSDF>; | ||
| BXDF_CONFIG_TYPE_ALIASES(Config); | ||
|
|
||
| using random_type = conditional_t<IsBSDF, vector3_type, vector2_type>; | ||
| struct Cache {}; | ||
| using isocache_type = Cache; | ||
| using anisocache_type = Cache; | ||
| using evalcache_type = Cache; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there should be no But having an |
||
|
|
||
| NBL_CONSTEXPR_STATIC_INLINE BxDFClampMode _clamp = conditional_value<IsBSDF, BxDFClampMode, BxDFClampMode::BCM_ABS, BxDFClampMode::BCM_MAX>::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 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 hlsl::promote<spectral_type>(_sample.getNdotL(_clamp) * numbers::inv_pi<scalar_type> * hlsl::mix(1.0, 0.5, IsBSDF)); | ||
| const spectral_type quo = hlsl::promote<spectral_type>(_sample.getNdotL(_clamp) * numbers::inv_pi<scalar_type> * hlsl::mix(1.0, 0.5, IsBSDF)); | ||
| return quotient_pdf_type::create(quo, forwardPdf(_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 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 eval(_sample, interaction.isotropic); | ||
| return evalAndWeight(_sample, interaction.isotropic, _cache); | ||
| } | ||
|
|
||
| template<typename C=bool_constant<!IsBSDF> > | ||
| enable_if_t<C::value && !IsBSDF, sample_type> generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC | ||
| enable_if_t<C::value && !IsBSDF, sample_type> 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<scalar_type>::cache_type cache; | ||
| ray_dir_info_type L; | ||
| L.setDirection(sampling::ProjectedHemisphere<scalar_type>::generate(u, cache)); | ||
| return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); | ||
| } | ||
| template<typename C=bool_constant<IsBSDF> > | ||
| enable_if_t<C::value && IsBSDF, sample_type> generate(NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, const vector3_type u) NBL_CONST_MEMBER_FUNC | ||
| enable_if_t<C::value && IsBSDF, 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 | ||
| { | ||
| typename sampling::ProjectedSphere<scalar_type>::cache_type cache; | ||
| vector3_type _u = u; | ||
| ray_dir_info_type L; | ||
| L.setDirection(sampling::ProjectedSphere<scalar_type>::generate(_u, cache)); | ||
| return sample_type::createFromTangentSpace(L, interaction.getFromTangentSpace()); | ||
| } | ||
| template<typename C=bool_constant<!IsBSDF> > | ||
| enable_if_t<C::value && !IsBSDF, sample_type> generate(NBL_CONST_REF_ARG(isotropic_interaction_type) interaction, const vector2_type u) NBL_CONST_MEMBER_FUNC | ||
| { | ||
| return generate(anisotropic_interaction_type::create(interaction), u); | ||
| } | ||
| template<typename C=bool_constant<IsBSDF> > | ||
| enable_if_t<C::value && IsBSDF, 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_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 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<scalar_type>::pdf(_sample.getNdotL(_clamp)); | ||
| else | ||
| return sampling::ProjectedHemisphere<scalar_type>::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 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 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<monochrome_type, scalar_type> qp; | ||
| NBL_IF_CONSTEXPR (IsBSDF) | ||
|
|
@@ -83,9 +84,9 @@ struct SLambertianBase | |
| qp = sampling::ProjectedHemisphere<scalar_type>::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 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 quotient_and_pdf(_sample, interaction.isotropic); | ||
| return quotientAndWeight(_sample, interaction.isotropic, _cache); | ||
| } | ||
| }; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you've already computed this in
__forwardPdfUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any way to making
__forwardPdfspit this out for you?Make make
__forwardPdf<bool FromGenerator>returna structand doesn't abuse
NBL_REF_ARGto return extra thingsAlso this way this whole block of code
can replace the preludes in quotientAndWeight and evalAndWeight with just
up until the G2_over_G1 computation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or the
__overwriteDGUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the
quotient...function can just not usequantQueryits the same as using a dummy on aNBL_REF_ARG