@@ -537,11 +537,15 @@ struct iridescent_helper
537537 return xyz / scalar_type (1. 0685e-7 );
538538 }
539539
540- T __call (const scalar_type clampedCosTheta)
540+ template<typename Params>
541+ static T __call (NBL_CONST_REF_ARG (Params) params, const scalar_type clampedCosTheta)
541542 {
542543 const vector_type wavelengths = vector_type (colorspace::scRGB::wavelength_R, colorspace::scRGB::wavelength_G, colorspace::scRGB::wavelength_B);
543544
544- scalar_type cosTheta_1 = clampedCosTheta;
545+ const vector_type eta12 = params.getEta12 ();
546+ const vector_type eta23 = params.getEta23 ();
547+ const vector_type etak23 = params.getEtak23 ();
548+ const scalar_type cosTheta_1 = clampedCosTheta;
545549 vector_type cosTheta_2;
546550
547551 vector_type R12p, R23p, R12s, R23s;
@@ -573,7 +577,7 @@ struct iridescent_helper
573577 vector_type T121s = hlsl::promote<vector_type>(1.0 ) - R12s;
574578
575579 // Optical Path Difference
576- const vector_type D = hlsl::promote<vector_type>(2.0 * Dinc) * thinFilmIor * cosTheta_2;
580+ const vector_type D = hlsl::promote<vector_type>(2.0 * params. getDinc ()) * params. getThinFilmIor () * cosTheta_2;
577581 const vector_type Dphi = hlsl::promote<vector_type>(2.0 * numbers::pi<scalar_type>) * D / wavelengths;
578582
579583 vector_type phi21p, phi21s, phi23p, phi23s, r123s, r123p, Rs;
@@ -622,6 +626,25 @@ struct iridescent_helper
622626
623627 return hlsl::max (colorspace::scRGB::FromXYZ (I), hlsl::promote<vector_type>(0.0 )) * hlsl::promote<vector_type>(0.5 );
624628 }
629+ };
630+
631+ template<typename T, bool SupportsTransmission NBL_PRIMARY_REQUIRES (concepts::FloatingPointLikeVectorial<T>)
632+ struct iridescent_base
633+ {
634+ using scalar_type = typename vector_traits<T>::scalar_type;
635+ using vector_type = T;
636+
637+ scalar_type getDinc () NBL_CONST_MEMBER_FUNC { return Dinc; }
638+ vector_type getThinFilmIor () NBL_CONST_MEMBER_FUNC { return thinFilmIor; }
639+ vector_type getEta12 () NBL_CONST_MEMBER_FUNC { return eta12; }
640+ vector_type getEta23 () NBL_CONST_MEMBER_FUNC { return eta23; }
641+ vector_type getEtak23 () NBL_CONST_MEMBER_FUNC
642+ {
643+ NBL_IF_CONSTEXPR (SupportsTransmission)
644+ return hlsl::promote<vector_type>(0.0 );
645+ else
646+ return etak23;
647+ }
625648
626649 scalar_type Dinc; // thickness of thin film in nanometers, rec. 100-25000nm
627650 vector_type thinFilmIor;
@@ -639,42 +662,22 @@ struct Iridescent<T, false NBL_PARTIAL_REQ_BOT(concepts::FloatingPointLikeVector
639662 using scalar_type = typename vector_traits<T>::scalar_type;
640663 using vector_type = T; // assert dim==3?
641664 using eta_type = vector_type;
642-
643- struct CreationParams
644- {
645- scalar_type Dinc;
646- vector_type ior1;
647- vector_type ior2;
648- vector_type ior3;
649- vector_type iork3;
650- };
651- using creation_params_type = CreationParams;
652-
653- static this_t create (NBL_CONST_REF_ARG (creation_params_type) params)
654- {
655- this_t retval;
656- retval.helper.Dinc = params.Dinc;
657- retval.helper.thinFilmIor = params.ior2;
658- retval.helper.eta12 = params.ior2/params.ior1;
659- retval.helper.eta23 = params.ior3/params.ior2;
660- retval.helper.etak23 = params.iork3/params.ior2;
661- return retval;
662- }
665+ using base_type = impl::iridescent_base<T, false >;
663666
664667 T operator ()(const scalar_type clampedCosTheta)
665668 {
666- return helper. __call ( clampedCosTheta);
669+ return impl::iridescent_helper<T, false >::template __call<base_type>(__base, clampedCosTheta);
667670 }
668671
669672 OrientedEtaRcps<eta_type> getOrientedEtaRcps () NBL_CONST_MEMBER_FUNC
670673 {
671674 OrientedEtaRcps<eta_type> rcpEta;
672- rcpEta.value = hlsl::promote<eta_type>(1.0 ) / helper .eta23;
675+ rcpEta.value = hlsl::promote<eta_type>(1.0 ) / __base .eta23;
673676 rcpEta.value2 = rcpEta.value * rcpEta.value;
674677 return rcpEta;
675678 }
676679
677- impl::iridescent_helper<T, false > helper ;
680+ base_type __base ;
678681};
679682
680683template<typename T>
@@ -685,37 +688,18 @@ struct Iridescent<T, true NBL_PARTIAL_REQ_BOT(concepts::FloatingPointLikeVectori
685688 using scalar_type = typename vector_traits<T>::scalar_type;
686689 using vector_type = T; // assert dim==3?
687690 using eta_type = vector <scalar_type, 1 >;
688-
689- struct CreationParams
690- {
691- scalar_type Dinc;
692- vector_type ior1;
693- vector_type ior2;
694- vector_type ior3;
695- };
696- using creation_params_type = CreationParams;
697-
698- static this_t create (NBL_CONST_REF_ARG (creation_params_type) params)
699- {
700- this_t retval;
701- retval.helper.Dinc = params.Dinc;
702- retval.helper.thinFilmIor = params.ior2;
703- retval.helper.eta12 = params.ior2/params.ior1;
704- retval.helper.eta23 = params.ior3/params.ior2;
705- retval.helper.etak23 = hlsl::promote<vector_type>(0.0 );
706- return retval;
707- }
691+ using base_type = impl::iridescent_base<T, true >;
708692
709693 T operator ()(const scalar_type clampedCosTheta)
710694 {
711- return helper. __call ( clampedCosTheta);
695+ return impl::iridescent_helper<T, true >::template __call<base_type>(__base, clampedCosTheta);
712696 }
713697
714- scalar_type getRefractionOrientedEta () NBL_CONST_MEMBER_FUNC { return helper .eta23[0 ]; }
698+ scalar_type getRefractionOrientedEta () NBL_CONST_MEMBER_FUNC { return __base .eta23[0 ]; }
715699 OrientedEtaRcps<eta_type> getOrientedEtaRcps () NBL_CONST_MEMBER_FUNC
716700 {
717701 OrientedEtaRcps<eta_type> rcpEta;
718- rcpEta.value = hlsl::promote<eta_type>(1.0 ) / helper .eta23[0 ];
702+ rcpEta.value = hlsl::promote<eta_type>(1.0 ) / __base .eta23[0 ];
719703 rcpEta.value2 = rcpEta.value * rcpEta.value;
720704 return rcpEta;
721705 }
@@ -724,15 +708,15 @@ struct Iridescent<T, true NBL_PARTIAL_REQ_BOT(concepts::FloatingPointLikeVectori
724708 {
725709 const bool flip = NdotI < scalar_type (0.0 );
726710 this_t orientedFresnel;
727- orientedFresnel.helper .Dinc = helper .Dinc;
728- orientedFresnel.helper .thinFilmIor = helper .thinFilmIor;
729- orientedFresnel.helper .eta12 = hlsl::mix (helper .eta12, hlsl::promote<vector_type>(1.0 )/helper .eta12, flip);
730- orientedFresnel.helper .eta23 = hlsl::mix (helper .eta23, hlsl::promote<vector_type>(1.0 )/helper .eta23, flip);
731- orientedFresnel.helper .etak23 = hlsl::promote<vector_type>(0.0 );
711+ orientedFresnel.__base .Dinc = __base .Dinc;
712+ orientedFresnel.__base .thinFilmIor = __base .thinFilmIor;
713+ orientedFresnel.__base .eta12 = hlsl::mix (__base .eta12, hlsl::promote<vector_type>(1.0 )/__base .eta12, flip);
714+ orientedFresnel.__base .eta23 = hlsl::mix (__base .eta23, hlsl::promote<vector_type>(1.0 )/__base .eta23, flip);
715+ orientedFresnel.__base .etak23 = hlsl::promote<vector_type>(0.0 );
732716 return orientedFresnel;
733717 }
734718
735- impl::iridescent_helper<T, true > helper ;
719+ base_type __base ;
736720};
737721
738722
0 commit comments