Skip to content

Commit 36c1f4b

Browse files
committed
account for non-symmetry in transmission, added PathOrigin
1 parent b01ebf7 commit 36c1f4b

File tree

5 files changed

+50
-30
lines changed

5 files changed

+50
-30
lines changed

include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ struct quant_query_helper<N, F, true>
4848
{
4949
using quant_query_type = typename N::quant_query_type;
5050

51-
template<class C>
52-
static quant_query_type __call(NBL_REF_ARG(N) ndf, NBL_CONST_REF_ARG(F) fresnel, NBL_CONST_REF_ARG(C) cache)
51+
template<class I, class C>
52+
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)
5353
{
54-
return ndf.template createQuantQuery<C>(cache, fresnel.orientedEta.value[0]);
54+
return ndf.template createQuantQuery<I,C>(interaction, cache, fresnel.orientedEta.value[0]);
5555
}
5656
};
5757

@@ -60,11 +60,11 @@ struct quant_query_helper<N, F, false>
6060
{
6161
using quant_query_type = typename N::quant_query_type;
6262

63-
template<class C>
64-
static quant_query_type __call(NBL_REF_ARG(N) ndf, NBL_CONST_REF_ARG(F) fresnel, NBL_CONST_REF_ARG(C) cache)
63+
template<class I, class C>
64+
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)
6565
{
6666
typename N::scalar_type dummy;
67-
return ndf.template createQuantQuery<C>(cache, dummy);
67+
return ndf.template createQuantQuery<I,C>(interaction, cache, dummy);
6868
}
6969
};
7070

@@ -167,7 +167,7 @@ struct SCookTorrance
167167
return hlsl::promote<spectral_type>(0.0);
168168

169169
using quant_query_type = typename ndf_type::quant_query_type;
170-
quant_query_type qq = impl::quant_query_helper<ndf_type, fresnel_type, IsBSDF>::template __call<MicrofacetCache>(ndf, _f, cache);
170+
quant_query_type qq = impl::quant_query_helper<ndf_type, fresnel_type, IsBSDF>::template __call<Interaction, MicrofacetCache>(ndf, _f, interaction, cache);
171171

172172
using g2g1_query_type = typename ndf_type::g2g1_query_type;
173173
g2g1_query_type gq = ndf.template createG2G1Query<sample_type, Interaction>(_sample, interaction);
@@ -379,7 +379,7 @@ struct SCookTorrance
379379
dg1_query_type dq = ndf.template createDG1Query<Interaction, MicrofacetCache>(interaction, cache);
380380

381381
fresnel_type _f = impl::getOrientedFresnel<fresnel_type, IsBSDF>::__call(fresnel, interaction.getNdotV());
382-
quant_query_type qq = impl::quant_query_helper<ndf_type, fresnel_type, IsBSDF>::template __call<MicrofacetCache>(ndf, _f, cache);
382+
quant_query_type qq = impl::quant_query_helper<ndf_type, fresnel_type, IsBSDF>::template __call<Interaction, MicrofacetCache>(ndf, _f, interaction, cache);
383383
quant_type DG1 = ndf.template DG1<sample_type, Interaction>(dq, qq, _sample, interaction);
384384

385385
NBL_IF_CONSTEXPR(IsBSDF)

include/nbl/builtin/hlsl/bxdf/common.hlsl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ enum BxDFClampMode : uint16_t
157157
BCM_ABS
158158
};
159159

160+
enum PathOrigin : uint16_t
161+
{
162+
PO_SENSOR = 0,
163+
PO_LIGHT
164+
};
165+
160166
template<typename T NBL_FUNC_REQUIRES(concepts::FloatingPointScalar<T>)
161167
T conditionalAbsOrMax(T x, BxDFClampMode _clamp)
162168
{
@@ -186,6 +192,7 @@ NBL_CONCEPT_END(
186192
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((iso.getN()), ::nbl::hlsl::is_same_v, typename T::vector3_type))
187193
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((iso.getNdotV(clampMode)), ::nbl::hlsl::is_same_v, typename T::scalar_type))
188194
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((iso.getNdotV2()), ::nbl::hlsl::is_same_v, typename T::scalar_type))
195+
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((iso.getPathOrigin()), ::nbl::hlsl::is_same_v, PathOrigin))
189196
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((T::create(normV,normN)), ::nbl::hlsl::is_same_v, T))
190197
((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(ray_dir_info::Basic, typename T::ray_dir_info_type))
191198
);
@@ -222,6 +229,8 @@ struct SIsotropic
222229
}
223230
scalar_type getNdotV2() NBL_CONST_MEMBER_FUNC { return NdotV2; }
224231

232+
PathOrigin getPathOrigin() NBL_CONST_MEMBER_FUNC { return PathOrigin::PO_SENSOR; }
233+
225234
RayDirInfo V;
226235
vector3_type N;
227236
scalar_type NdotV;
@@ -309,6 +318,7 @@ struct SAnisotropic
309318
vector3_type getN() NBL_CONST_MEMBER_FUNC { return isotropic.getN(); }
310319
scalar_type getNdotV(BxDFClampMode _clamp = BxDFClampMode::BCM_NONE) NBL_CONST_MEMBER_FUNC { return isotropic.getNdotV(_clamp); }
311320
scalar_type getNdotV2() NBL_CONST_MEMBER_FUNC { return isotropic.getNdotV2(); }
321+
PathOrigin getPathOrigin() NBL_CONST_MEMBER_FUNC { return isotropic.getPathOrigin(); }
312322

313323
vector3_type getT() NBL_CONST_MEMBER_FUNC { return T; }
314324
vector3_type getB() NBL_CONST_MEMBER_FUNC { return B; }

include/nbl/builtin/hlsl/bxdf/ndf/beckmann.hlsl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,18 @@ struct Beckmann
263263
return hlsl::mix<scalar_type>(scalar_type(0.0), nom / denom, c < scalar_type(1.6));
264264
}
265265

266-
template<class MicrofacetCache NBL_FUNC_REQUIRES(RequiredMicrofacetCache<MicrofacetCache>)
267-
quant_query_type createQuantQuery(NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta)
266+
template<class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES(RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
267+
quant_query_type createQuantQuery(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta)
268268
{
269269
quant_query_type quant_query; // only has members for refraction
270270
NBL_IF_CONSTEXPR(SupportsTransmission)
271271
{
272272
quant_query.VdotHLdotH = cache.getVdotHLdotH();
273-
const scalar_type VdotH_etaLdotH = cache.getVdotH() + orientedEta * cache.getLdotH();
274-
quant_query.neg_rcp2_VdotH_etaLdotH = scalar_type(-1.0) / (VdotH_etaLdotH * VdotH_etaLdotH);
273+
const scalar_type VdotH = cache.getVdotH();
274+
const scalar_type VdotH_etaLdotH = hlsl::mix(VdotH + orientedEta * cache.getLdotH(),
275+
VdotH / orientedEta + cache.getLdotH(),
276+
interaction.getPathOrigin() == PathOrigin::PO_SENSOR);
277+
quant_query.neg_rcp2_refractionDenom = scalar_type(-1.0) / (VdotH_etaLdotH * VdotH_etaLdotH);
275278
}
276279
return quant_query;
277280
}

include/nbl/builtin/hlsl/bxdf/ndf/ggx.hlsl

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,18 @@ struct GGX
206206
return scalar_type(1.0) / (NdotX + devsh_part);
207207
}
208208

209-
template<class MicrofacetCache NBL_FUNC_REQUIRES(RequiredMicrofacetCache<MicrofacetCache>)
210-
quant_query_type createQuantQuery(NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta)
209+
template<class Interaction, class MicrofacetCache NBL_FUNC_REQUIRES(RequiredInteraction<Interaction> && RequiredMicrofacetCache<MicrofacetCache>)
210+
quant_query_type createQuantQuery(NBL_CONST_REF_ARG(Interaction) interaction, NBL_CONST_REF_ARG(MicrofacetCache) cache, scalar_type orientedEta)
211211
{
212212
quant_query_type quant_query; // only has members for refraction
213-
NBL_IF_CONSTEXPR (SupportsTransmission)
213+
NBL_IF_CONSTEXPR(SupportsTransmission)
214214
{
215215
quant_query.VdotHLdotH = cache.getVdotHLdotH();
216-
const scalar_type VdotH_etaLdotH = cache.getVdotH() + orientedEta * cache.getLdotH();
217-
quant_query.neg_rcp2_VdotH_etaLdotH = scalar_type(-1.0) / (VdotH_etaLdotH * VdotH_etaLdotH);
216+
const scalar_type VdotH = cache.getVdotH();
217+
const scalar_type VdotH_etaLdotH = hlsl::mix(VdotH + orientedEta * cache.getLdotH(),
218+
VdotH / orientedEta + cache.getLdotH(),
219+
interaction.getPathOrigin() == PathOrigin::PO_SENSOR);
220+
quant_query.neg_rcp2_refractionDenom = scalar_type(-1.0) / (VdotH_etaLdotH * VdotH_etaLdotH);
218221
}
219222
return quant_query;
220223
}
@@ -278,7 +281,7 @@ struct GGX
278281
const bool transmitted = reflect_refract==MTT_REFRACT || (reflect_refract!=MTT_REFLECT && VdotHLdotH < scalar_type(0.0));
279282
dmq.projectedLightMeasure = hlsl::mix(scalar_type(0.5),scalar_type(2.0),transmitted) * dg1_over_2NdotV;
280283
if (transmitted)
281-
dmq.projectedLightMeasure *= VdotHLdotH * quant_query.getNeg_rcp2_VdotH_etaLdotH();
284+
dmq.projectedLightMeasure *= VdotHLdotH * quant_query.getNeg_rcp2_refractionDenom();
282285
}
283286
else
284287
dmq.projectedLightMeasure = scalar_type(0.5) * dg1_over_2NdotV;
@@ -319,10 +322,14 @@ struct GGX
319322
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)
320323
{
321324
scalar_type dg = __ndf_base.template D<MicrofacetCache>(cache);
322-
if (dg < bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity))
323-
dg *= correlated_wo_numerator<LS, Interaction, MicrofacetCache>(query, _sample, interaction, cache);
324-
else
325-
dg = scalar_type(0.0);
325+
if (dg >= bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity))
326+
{
327+
quant_type dmq;
328+
dmq.microfacetMeasure = scalar_type(0.0);
329+
dmq.projectedLightMeasure = scalar_type(0.0);
330+
return dmq;
331+
}
332+
dg *= correlated_wo_numerator<LS, Interaction, MicrofacetCache>(query, _sample, interaction, cache);
326333

327334
quant_type dmq;
328335
dmq.microfacetMeasure = dg;
@@ -333,7 +340,7 @@ struct GGX
333340
const bool transmitted = reflect_refract==MTT_REFRACT || (reflect_refract!=MTT_REFLECT && VdotHLdotH < scalar_type(0.0));
334341
scalar_type NdotL_over_denominator = _sample.getNdotL(BxDFClampMode::BCM_ABS);
335342
if (transmitted)
336-
NdotL_over_denominator *= scalar_type(4.0) * VdotHLdotH * quant_query.getNeg_rcp2_VdotH_etaLdotH();
343+
NdotL_over_denominator *= scalar_type(4.0) * VdotHLdotH * quant_query.getNeg_rcp2_refractionDenom();
337344
dmq.projectedLightMeasure = dg * NdotL_over_denominator;
338345
}
339346
else

include/nbl/builtin/hlsl/bxdf/ndf/microfacet_to_light_transform.hlsl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ struct DualMeasureQuantQuery
4848
// note in pbrt it's `abs(VdotH)*abs(LdotH)`
4949
// we leverage the fact that under transmission the sign must always be negative and rest of the code already accounts for that
5050
scalar_type getVdotHLdotH() NBL_CONST_MEMBER_FUNC { return VdotHLdotH; }
51-
scalar_type getNeg_rcp2_VdotH_etaLdotH () NBL_CONST_MEMBER_FUNC { return neg_rcp2_VdotH_etaLdotH ; }
51+
scalar_type getNeg_rcp2_refractionDenom() NBL_CONST_MEMBER_FUNC { return neg_rcp2_refractionDenom ; }
5252

5353
scalar_type VdotHLdotH;
54-
scalar_type neg_rcp2_VdotH_etaLdotH;
54+
scalar_type neg_rcp2_refractionDenom;
5555
};
5656

5757

@@ -71,14 +71,14 @@ struct createDualMeasureQuantity_helper
7171
{
7272
using scalar_type = typename vector_traits<T>::scalar_type;
7373

74-
static SDualMeasureQuant<T> __call(const T microfacetMeasure, scalar_type clampedNdotV, scalar_type clampedNdotL, scalar_type VdotHLdotH, scalar_type neg_rcp2_VdotH_etaLdotH)
74+
static SDualMeasureQuant<T> __call(const T microfacetMeasure, scalar_type clampedNdotV, scalar_type clampedNdotL, scalar_type VdotHLdotH, scalar_type neg_rcp2_refractionDenom)
7575
{
7676
assert(clampedNdotV >= scalar_type(0.0) && clampedNdotL >= scalar_type(0.0));
7777
SDualMeasureQuant<T> retval;
7878
retval.microfacetMeasure = microfacetMeasure;
7979
// do constexpr booleans first so optimizer picks up this and short circuits
8080
const bool transmitted = reflect_refract==MTT_REFRACT || (reflect_refract!=MTT_REFLECT && VdotHLdotH < scalar_type(0.0));
81-
retval.projectedLightMeasure = microfacetMeasure * hlsl::mix(scalar_type(0.25),VdotHLdotH*neg_rcp2_VdotH_etaLdotH,transmitted)/clampedNdotV;
81+
retval.projectedLightMeasure = microfacetMeasure * hlsl::mix(scalar_type(0.25),VdotHLdotH*neg_rcp2_refractionDenom,transmitted)/clampedNdotV;
8282
// VdotHLdotH is negative under transmission, so thats denominator is negative
8383
return retval;
8484
}
@@ -93,14 +93,14 @@ SDualMeasureQuant<T> createDualMeasureQuantity(const T specialMeasure, typename
9393
return impl::createDualMeasureQuantity_helper<T,MTT_REFLECT>::__call(specialMeasure,clampedNdotV,clampedNdotL,dummy,dummy);
9494
}
9595
template<typename T, MicrofacetTransformTypes reflect_refract>
96-
SDualMeasureQuant<T> createDualMeasureQuantity(const T specialMeasure, typename vector_traits<T>::scalar_type clampedNdotV, typename vector_traits<T>::scalar_type clampedNdotL, typename vector_traits<T>::scalar_type VdotHLdotH, typename vector_traits<T>::scalar_type neg_rcp2_VdotH_etaLdotH)
96+
SDualMeasureQuant<T> createDualMeasureQuantity(const T specialMeasure, typename vector_traits<T>::scalar_type clampedNdotV, typename vector_traits<T>::scalar_type clampedNdotL, typename vector_traits<T>::scalar_type VdotHLdotH, typename vector_traits<T>::scalar_type neg_rcp2_refractionDenom)
9797
{
98-
return impl::createDualMeasureQuantity_helper<T,reflect_refract>::__call(specialMeasure,clampedNdotV,clampedNdotL,VdotHLdotH,neg_rcp2_VdotH_etaLdotH);
98+
return impl::createDualMeasureQuantity_helper<T,reflect_refract>::__call(specialMeasure,clampedNdotV,clampedNdotL,VdotHLdotH,neg_rcp2_refractionDenom);
9999
}
100100
template<typename T, MicrofacetTransformTypes reflect_refract, class Query>
101101
SDualMeasureQuant<T> createDualMeasureQuantity(const T specialMeasure, typename vector_traits<T>::scalar_type clampedNdotV, typename vector_traits<T>::scalar_type clampedNdotL, NBL_CONST_REF_ARG(Query) query)
102102
{
103-
return impl::createDualMeasureQuantity_helper<T,reflect_refract>::__call(specialMeasure,clampedNdotV,clampedNdotL,query.getVdotHLdotH(),query.getNeg_rcp2_VdotH_etaLdotH());
103+
return impl::createDualMeasureQuantity_helper<T,reflect_refract>::__call(specialMeasure,clampedNdotV,clampedNdotL,query.getVdotHLdotH(),query.getNeg_rcp2_refractionDenom());
104104
}
105105

106106
}

0 commit comments

Comments
 (0)