Skip to content

Commit 1a2f561

Browse files
committed
split iridescent fresnel by SupportsTransmission, adjusted fresnel concept, iridescent bxdf use cook torrance base
1 parent 946b050 commit 1a2f561

File tree

5 files changed

+106
-402
lines changed

5 files changed

+106
-402
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct quant_query_helper<N, F, true>
5151
template<class I, class C>
5252
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<I,C>(interaction, cache, fresnel.orientedEta.value[0]);
54+
return ndf.template createQuantQuery<I,C>(interaction, cache, fresnel.getRefractionOrientedEta());
5555
}
5656
};
5757

include/nbl/builtin/hlsl/bxdf/fresnel.hlsl

Lines changed: 99 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,9 @@ NBL_CONCEPT_BEGIN(2)
313313
NBL_CONCEPT_END(
314314
((NBL_CONCEPT_REQ_TYPE)(T::scalar_type))
315315
((NBL_CONCEPT_REQ_TYPE)(T::vector_type))
316+
((NBL_CONCEPT_REQ_TYPE)(T::eta_type))
316317
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((fresnel(cosTheta)), ::nbl::hlsl::is_same_v, typename T::vector_type))
317-
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((fresnel.getOrientedEtaRcps()), ::nbl::hlsl::is_same_v, OrientedEtaRcps<typename T::vector_type>))
318+
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((fresnel.getOrientedEtaRcps()), ::nbl::hlsl::is_same_v, OrientedEtaRcps<typename T::eta_type>))
318319
);
319320
#undef cosTheta
320321
#undef fresnel
@@ -342,6 +343,7 @@ struct Schlick
342343
{
343344
using scalar_type = typename vector_traits<T>::scalar_type;
344345
using vector_type = T;
346+
using eta_type = vector_type;
345347

346348
static Schlick<T> create(NBL_CONST_REF_ARG(T) F0)
347349
{
@@ -358,11 +360,11 @@ struct Schlick
358360
return F0 + (1.0 - F0) * x*x*x*x*x;
359361
}
360362

361-
OrientedEtaRcps<T> getOrientedEtaRcps() NBL_CONST_MEMBER_FUNC
363+
OrientedEtaRcps<eta_type> getOrientedEtaRcps() NBL_CONST_MEMBER_FUNC
362364
{
363-
const T sqrtF0 = hlsl::sqrt(F0);
364-
OrientedEtaRcps<T> rcpEta;
365-
rcpEta.value = (hlsl::promote<T>(1.0) - sqrtF0) / (hlsl::promote<T>(1.0) + sqrtF0);
365+
const eta_type sqrtF0 = hlsl::sqrt(F0);
366+
OrientedEtaRcps<eta_type> rcpEta;
367+
rcpEta.value = (hlsl::promote<eta_type>(1.0) - sqrtF0) / (hlsl::promote<eta_type>(1.0) + sqrtF0);
366368
rcpEta.value2 = rcpEta.value * rcpEta.value;
367369
return rcpEta;
368370
}
@@ -375,6 +377,7 @@ struct Conductor
375377
{
376378
using scalar_type = typename vector_traits<T>::scalar_type;
377379
using vector_type = T;
380+
using eta_type = vector_type;
378381

379382
static Conductor<T> create(NBL_CONST_REF_ARG(T) eta, NBL_CONST_REF_ARG(T) etak)
380383
{
@@ -432,10 +435,10 @@ struct Conductor
432435
return (rs2 + rp2) * hlsl::promote<T>(0.5);
433436
}
434437

435-
OrientedEtaRcps<T> getOrientedEtaRcps() NBL_CONST_MEMBER_FUNC
438+
OrientedEtaRcps<eta_type> getOrientedEtaRcps() NBL_CONST_MEMBER_FUNC
436439
{
437-
OrientedEtaRcps<T> rcpEta;
438-
rcpEta.value = hlsl::promote<T>(1.0) / eta;
440+
OrientedEtaRcps<eta_type> rcpEta;
441+
rcpEta.value = hlsl::promote<eta_type>(1.0) / eta;
439442
rcpEta.value2 = rcpEta.value * rcpEta.value;
440443
return rcpEta;
441444
}
@@ -450,6 +453,7 @@ struct Dielectric
450453
{
451454
using scalar_type = typename vector_traits<T>::scalar_type;
452455
using vector_type = T;
456+
using eta_type = vector_type;
453457

454458
static Dielectric<T> create(NBL_CONST_REF_ARG(OrientedEtas<T>) orientedEta)
455459
{
@@ -510,26 +514,16 @@ struct Dielectric
510514
};
511515

512516
// adapted from https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html
517+
template<typename T, bool SupportsTransmission NBL_STRUCT_CONSTRAINABLE>
518+
struct Iridescent;
519+
520+
namespace impl
521+
{
513522
template<typename T, bool SupportsTransmission NBL_PRIMARY_REQUIRES(concepts::FloatingPointLikeVectorial<T>)
514-
struct Iridescent
523+
struct iridescent_helper
515524
{
516-
using this_t = Iridescent<T,SupportsTransmission>;
517525
using scalar_type = typename vector_traits<T>::scalar_type;
518-
using monochrome_type = vector<scalar_type, 1>;
519-
using vector_type = T; // assert dim==3?
520-
521-
static this_t create(scalar_type Dinc, vector_type ior1, vector_type ior2, vector_type ior3, vector_type iork3)
522-
{
523-
this_t retval;
524-
retval.Dinc = Dinc;
525-
retval.thinFilmIor = ior2;
526-
retval.eta12 = ior2/ior1;
527-
retval.eta23 = ior3/ior2;
528-
retval.etak23 = scalar_type(0.0);
529-
NBL_IF_CONSTEXPR(SupportsTransmission)
530-
retval.etak23 = iork3/ior2;
531-
return retval;
532-
}
526+
using vector_type = T;
533527

534528
// returns reflectance R = (rp, rs), phi is the phase shift for each plane of polarization (p,s)
535529
static void phase_shift(const vector_type orientedEta, const vector_type orientedEtak, const vector_type cosTheta, NBL_REF_ARG(vector_type) phiS, NBL_REF_ARG(vector_type) phiP)
@@ -566,7 +560,7 @@ struct Iridescent
566560
return xyz / scalar_type(1.0685e-7);
567561
}
568562

569-
T operator()(const scalar_type clampedCosTheta /* LdotH */)
563+
T __call(const scalar_type clampedCosTheta)
570564
{
571565
const vector_type wavelengths = vector_type(colorspace::scRGB::wavelength_R, colorspace::scRGB::wavelength_G, colorspace::scRGB::wavelength_B);
572566

@@ -646,11 +640,80 @@ struct Iridescent
646640
return hlsl::max(colorspace::scRGB::FromXYZ(I), hlsl::promote<vector_type>(0.0)) * hlsl::promote<vector_type>(0.5);
647641
}
648642

649-
scalar_type getRefractionOrientedEta() NBL_CONST_MEMBER_FUNC { return eta23[0]; }
650-
OrientedEtaRcps<monochrome_type> getOrientedEtaRcps() NBL_CONST_MEMBER_FUNC
643+
scalar_type Dinc; // thickness of thin film in nanometers, rec. 100-25000nm
644+
vector_type thinFilmIor;
645+
vector_type eta12; // outside (usually air 1.0) -> thin-film IOR
646+
vector_type eta23; // thin-film -> base material IOR
647+
vector_type etak23; // thin-film -> complex component, k==0 makes dielectric
648+
};
649+
}
650+
651+
template<typename T>
652+
NBL_PARTIAL_REQ_TOP(concepts::FloatingPointLikeVectorial<T>)
653+
struct Iridescent<T, false NBL_PARTIAL_REQ_BOT(concepts::FloatingPointLikeVectorial<T>) >
654+
{
655+
using this_t = Iridescent<T,false>;
656+
using scalar_type = typename vector_traits<T>::scalar_type;
657+
using vector_type = T; // assert dim==3?
658+
using eta_type = vector_type;
659+
660+
static this_t create(scalar_type Dinc, vector_type ior1, vector_type ior2, vector_type ior3, vector_type iork3)
661+
{
662+
this_t retval;
663+
retval.helper.Dinc = Dinc;
664+
retval.helper.thinFilmIor = ior2;
665+
retval.helper.eta12 = ior2/ior1;
666+
retval.helper.eta23 = ior3/ior2;
667+
retval.helper.etak23 = iork3/ior2;
668+
return retval;
669+
}
670+
671+
T operator()(const scalar_type clampedCosTheta)
672+
{
673+
return helper.__call(clampedCosTheta);
674+
}
675+
676+
OrientedEtaRcps<eta_type> getOrientedEtaRcps() NBL_CONST_MEMBER_FUNC
677+
{
678+
OrientedEtaRcps<eta_type> rcpEta;
679+
rcpEta.value = hlsl::promote<eta_type>(1.0) / helper.eta23;
680+
rcpEta.value2 = rcpEta.value * rcpEta.value;
681+
return rcpEta;
682+
}
683+
684+
impl::iridescent_helper<T,false> helper;
685+
};
686+
687+
template<typename T>
688+
NBL_PARTIAL_REQ_TOP(concepts::FloatingPointLikeVectorial<T>)
689+
struct Iridescent<T, true NBL_PARTIAL_REQ_BOT(concepts::FloatingPointLikeVectorial<T>) >
690+
{
691+
using this_t = Iridescent<T,true>;
692+
using scalar_type = typename vector_traits<T>::scalar_type;
693+
using vector_type = T; // assert dim==3?
694+
using eta_type = vector<scalar_type, 1>;
695+
696+
static this_t create(scalar_type Dinc, vector_type ior1, vector_type ior2, vector_type ior3)
651697
{
652-
OrientedEtaRcps<monochrome_type> rcpEta;
653-
rcpEta.value = hlsl::promote<monochrome_type>(1.0) / eta23[0];
698+
this_t retval;
699+
retval.helper.Dinc = Dinc;
700+
retval.helper.thinFilmIor = ior2;
701+
retval.helper.eta12 = ior2/ior1;
702+
retval.helper.eta23 = ior3/ior2;
703+
retval.helper.etak23 = hlsl::promote<vector_type>(0.0);
704+
return retval;
705+
}
706+
707+
T operator()(const scalar_type clampedCosTheta)
708+
{
709+
return helper.__call(clampedCosTheta);
710+
}
711+
712+
scalar_type getRefractionOrientedEta() NBL_CONST_MEMBER_FUNC { return helper.eta23[0]; }
713+
OrientedEtaRcps<eta_type> getOrientedEtaRcps() NBL_CONST_MEMBER_FUNC
714+
{
715+
OrientedEtaRcps<eta_type> rcpEta;
716+
rcpEta.value = hlsl::promote<eta_type>(1.0) / helper.eta23[0];
654717
rcpEta.value2 = rcpEta.value * rcpEta.value;
655718
return rcpEta;
656719
}
@@ -659,21 +722,15 @@ struct Iridescent
659722
{
660723
const bool flip = NdotI < scalar_type(0.0);
661724
this_t orientedFresnel;
662-
orientedFresnel.Dinc = Dinc;
663-
orientedFresnel.thinFilmIor = thinFilmIor;
664-
orientedFresnel.eta12 = hlsl::mix(eta12, hlsl::promote<vector_type>(1.0)/eta12, flip);
665-
orientedFresnel.eta23 = hlsl::mix(eta23, hlsl::promote<vector_type>(1.0)/eta23, flip);
666-
orientedFresnel.etak23 = hlsl::promote<vector_type>(0.0);
667-
NBL_IF_CONSTEXPR(SupportsTransmission)
668-
orientedFresnel.etak23 = hlsl::mix(etak23, hlsl::promote<vector_type>(1.0)/etak23, flip);
725+
orientedFresnel.helper.Dinc = helper.Dinc;
726+
orientedFresnel.helper.thinFilmIor = helper.thinFilmIor;
727+
orientedFresnel.helper.eta12 = hlsl::mix(helper.eta12, hlsl::promote<vector_type>(1.0)/helper.eta12, flip);
728+
orientedFresnel.helper.eta23 = hlsl::mix(helper.eta23, hlsl::promote<vector_type>(1.0)/helper.eta23, flip);
729+
orientedFresnel.helper.etak23 = hlsl::promote<vector_type>(0.0);
669730
return orientedFresnel;
670731
}
671732

672-
scalar_type Dinc; // thickness of thin film in nanometers, rec. 100-25000nm
673-
vector_type thinFilmIor;
674-
vector_type eta12; // outside (usually air 1.0) -> thin-film IOR
675-
vector_type eta23; // thin-film -> base material IOR
676-
vector_type etak23; // thin-film -> complex component, k==0 makes dielectric
733+
impl::iridescent_helper<T,true> helper;
677734
};
678735

679736

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ struct GGXCommon<T,SupportsTransmission,false NBL_PARTIAL_REQ_BOT(concepts::Floa
9393
isInfinity = true;
9494
return bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity);
9595
}
96-
isInfinity = false;
9796
scalar_type denom = scalar_type(1.0) - one_minus_a2 * cache.getNdotH2();
9897
scalar_type ndf = a2 * numbers::inv_pi<scalar_type> / (denom * denom);
9998
isInfinity = hlsl::isinf(ndf);
@@ -124,7 +123,6 @@ struct GGXCommon<T,SupportsTransmission,true NBL_PARTIAL_REQ_BOT(concepts::Float
124123
isInfinity = true;
125124
return bit_cast<scalar_type>(numeric_limits<scalar_type>::infinity);
126125
}
127-
isInfinity = false;
128126
scalar_type denom = cache.getTdotH2() / ax2 + cache.getBdotH2() / ay2 + cache.getNdotH2();
129127
scalar_type ndf = numbers::inv_pi<scalar_type> / (a2 * denom * denom);
130128
isInfinity = hlsl::isinf(ndf);

0 commit comments

Comments
 (0)