@@ -508,25 +508,26 @@ struct iridescent_helper
508508 using scalar_type = typename vector_traits<T>::scalar_type;
509509 using vector_type = T;
510510
511- // returns reflectance R = (rp, rs), phi is the phase shift for each plane of polarization (p,s)
512- 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)
511+ // returns phi, the phase shift for each plane of polarization (p,s)
512+ static void phase_shift (const vector_type ior1 , const vector_type ior2, const vector_type iork2 , const vector_type cosTheta, NBL_REF_ARG (vector_type) phiS, NBL_REF_ARG (vector_type) phiP)
513513 {
514- vector_type cosTheta_2 = cosTheta * cosTheta;
515- vector_type sinTheta2 = hlsl::promote<vector_type>(1.0 ) - cosTheta_2;
516- const vector_type eta2 = orientedEta*orientedEta;
517- const vector_type etak2 = orientedEtak*orientedEtak;
514+ const vector_type cosTheta2 = cosTheta * cosTheta;
515+ const vector_type sinTheta2 = hlsl::promote<vector_type>(1.0 ) - cosTheta2;
516+ const vector_type ior1_2 = ior1*ior1;
517+ const vector_type ior2_2 = ior2*ior2;
518+ const vector_type iork2_2 = iork2*iork2;
518519
519- vector_type z = eta2 - etak2 - sinTheta2;
520- vector_type w = hlsl::sqrt (z * z + scalar_type (4.0 ) * eta2 * eta2 * etak2);
521- vector_type a2 = (z + w) * hlsl::promote<vector_type>(0.5 );
522- vector_type b2 = (w - z) * hlsl::promote<vector_type>(0.5 );
523- vector_type b = hlsl::sqrt (b2);
520+ const vector_type z = ior2_2 * (hlsl::promote<vector_type>(1.0 ) - iork2_2) - ior1_2 * sinTheta2;
521+ const vector_type w = hlsl::sqrt (z*z + scalar_type (4.0 ) * ior2_2 * ior2_2 * iork2_2);
522+ const vector_type a2 = hlsl::max (z + w, hlsl::promote<vector_type>(0.0 )) * hlsl::promote<vector_type>(0.5 );
523+ const vector_type b2 = hlsl::max (w - z, hlsl::promote<vector_type>(0.0 )) * hlsl::promote<vector_type>(0.5 );
524+ const vector_type a = hlsl::sqrt (a2);
525+ const vector_type b = hlsl::sqrt (b2);
524526
525- const vector_type t0 = eta2 + etak2;
526- const vector_type t1 = t0 * cosTheta_2;
527-
528- phiS = hlsl::atan2 (hlsl::promote<vector_type>(2.0 ) * b * cosTheta, a2 + b2 - cosTheta_2);
529- phiP = hlsl::atan2 (hlsl::promote<vector_type>(2.0 ) * eta2 * cosTheta * (hlsl::promote<vector_type>(2.0 ) * orientedEtak * hlsl::sqrt (a2) - etak2 * b), t1 - a2 + b2);
527+ phiS = hlsl::atan2 (scalar_type (2.0 ) * ior1 * b * cosTheta, a2 + b2 - ior1_2*cosTheta2);
528+ const vector_type k2_plus_one = hlsl::promote<vector_type>(1.0 ) + iork2_2;
529+ phiP = hlsl::atan2 (scalar_type (2.0 ) * ior1 * ior2_2 * cosTheta * (scalar_type (2.0 ) * iork2 * a - (hlsl::promote<vector_type>(1.0 ) - iork2_2) * b),
530+ ior2_2 * cosTheta2 * k2_plus_one * k2_plus_one - ior1_2*(a2+b2));
530531 }
531532
532533 // Evaluation XYZ sensitivity curves in Fourier space
@@ -544,7 +545,8 @@ struct iridescent_helper
544545 }
545546
546547 template<typename Colorspace>
547- static T __call (const vector_type _D, const vector_type eta12, const vector_type eta23, const vector_type etak23, const scalar_type clampedCosTheta)
548+ static T __call (const vector_type _D, const vector_type ior1, const vector_type ior2, const vector_type ior3, const vector_type iork3,
549+ const vector_type eta12, const vector_type eta23, const vector_type etak23, const scalar_type clampedCosTheta)
548550 {
549551 const vector_type wavelengths = vector_type (Colorspace::wavelength_R, Colorspace::wavelength_G, Colorspace::wavelength_B);
550552
@@ -593,8 +595,8 @@ struct iridescent_helper
593595 vector_type I = hlsl::promote<vector_type>(0.0 );
594596
595597 // Evaluate the phase shift
596- phase_shift (eta12, hlsl::promote<vector_type>(0.0 ), hlsl::promote<vector_type>(cosTheta_1), phi21p, phi21s );
597- phase_shift (eta23, etak23, cosTheta_2, phi23p , phi23s);
598+ phase_shift (ior1, ior2, hlsl::promote<vector_type>(0.0 ), hlsl::promote<vector_type>(cosTheta_1), phi21s, phi21p );
599+ phase_shift (ior2, ior3, iork3, cosTheta_2 , phi23s, phi23p );
598600 phi21p = hlsl::promote<vector_type>(numbers::pi<scalar_type>) - phi21p;
599601 phi21s = hlsl::promote<vector_type>(numbers::pi<scalar_type>) - phi21s;
600602
@@ -633,7 +635,7 @@ struct iridescent_helper
633635 I += Cm*Sm;
634636 }
635637
636- return hlsl::max (colorspace::scRGB::FromXYZ (I), hlsl::promote<vector_type>(0.0 )) * hlsl::promote<vector_type>(0.5 );
638+ return hlsl::max (colorspace::scRGB::FromXYZ (I) * hlsl::promote<vector_type>(0.5 ), hlsl::promote<vector_type>(0.0 ) );
637639 }
638640};
639641
@@ -643,11 +645,11 @@ struct iridescent_base
643645 using scalar_type = typename vector_traits<T>::scalar_type;
644646 using vector_type = T;
645647
646- vector_type getD () NBL_CONST_MEMBER_FUNC { return D; }
647- vector_type getEta12 () NBL_CONST_MEMBER_FUNC { return eta12; }
648- vector_type getEta23 () NBL_CONST_MEMBER_FUNC { return eta23; }
649-
650648 vector_type D;
649+ vector_type ior1;
650+ vector_type ior2;
651+ vector_type ior3;
652+ vector_type iork3;
651653 vector_type eta12; // outside (usually air 1.0) -> thin-film IOR
652654 vector_type eta23; // thin-film -> base material IOR
653655};
@@ -679,6 +681,10 @@ struct Iridescent<T, false, Colorspace NBL_PARTIAL_REQ_BOT(concepts::FloatingPoi
679681 {
680682 this_t retval;
681683 retval.D = hlsl::promote<vector_type>(2.0 * params.Dinc) * params.ior2;
684+ retval.ior1 = params.ior1;
685+ retval.ior2 = params.ior2;
686+ retval.ior3 = params.ior3;
687+ retval.iork3 = params.iork3;
682688 retval.eta12 = params.ior2/params.ior1;
683689 retval.eta23 = params.ior3/params.ior2;
684690 retval.etak23 = params.iork3/params.ior2;
@@ -687,7 +693,8 @@ struct Iridescent<T, false, Colorspace NBL_PARTIAL_REQ_BOT(concepts::FloatingPoi
687693
688694 T operator ()(const scalar_type clampedCosTheta) NBL_CONST_MEMBER_FUNC
689695 {
690- return impl::iridescent_helper<T,false >::template __call<Colorspace>(base_type::getD (), base_type::getEta12 (), base_type::getEta23 (), getEtak23 (), clampedCosTheta);
696+ return impl::iridescent_helper<T,false >::template __call<Colorspace>(base_type::D, base_type::ior1, base_type::ior2, base_type::ior3, base_type::iork3,
697+ base_type::eta12, base_type::eta23, getEtak23 (), clampedCosTheta);
691698 }
692699
693700 OrientedEtaRcps<eta_type> getOrientedEtaRcps () NBL_CONST_MEMBER_FUNC
@@ -731,14 +738,19 @@ struct Iridescent<T, true, Colorspace NBL_PARTIAL_REQ_BOT(concepts::FloatingPoin
731738 {
732739 this_t retval;
733740 retval.D = hlsl::promote<vector_type>(2.0 * params.Dinc) * params.ior2;
741+ retval.ior1 = params.ior1;
742+ retval.ior2 = params.ior2;
743+ retval.ior3 = params.ior3;
744+ retval.iork3 = params.iork3;
734745 retval.eta12 = params.ior2/params.ior1;
735746 retval.eta23 = params.ior3/params.ior2;
736747 return retval;
737748 }
738749
739750 T operator ()(const scalar_type clampedCosTheta) NBL_CONST_MEMBER_FUNC
740751 {
741- return impl::iridescent_helper<T,true >::template __call<Colorspace>(base_type::getD (), base_type::getEta12 (), base_type::getEta23 (), getEtak23 (), clampedCosTheta);
752+ return impl::iridescent_helper<T,true >::template __call<Colorspace>(base_type::D, base_type::ior1, base_type::ior2, base_type::ior3, getEtak23 (),
753+ base_type::eta12, base_type::eta23, getEtak23 (), clampedCosTheta);
742754 }
743755
744756 scalar_type getRefractionOrientedEta () NBL_CONST_MEMBER_FUNC { return base_type::eta23[0 ]; }
@@ -755,8 +767,11 @@ struct Iridescent<T, true, Colorspace NBL_PARTIAL_REQ_BOT(concepts::FloatingPoin
755767 const bool flip = NdotI < scalar_type (0.0 );
756768 this_t orientedFresnel;
757769 orientedFresnel.D = base_type::D;
758- orientedFresnel.eta12 = hlsl::mix (base_type::eta12, hlsl::promote<vector_type>(1.0 )/base_type::eta12, flip);
759- orientedFresnel.eta23 = hlsl::mix (base_type::eta23, hlsl::promote<vector_type>(1.0 )/base_type::eta23, flip);
770+ orientedFresnel.ior1 = base_type::ior3;
771+ orientedFresnel.ior2 = base_type::ior2;
772+ orientedFresnel.ior3 = base_type::ior1;
773+ orientedFresnel.eta12 = hlsl::mix (base_type::eta12, hlsl::promote<vector_type>(1.0 )/base_type::eta23, flip);
774+ orientedFresnel.eta23 = hlsl::mix (base_type::eta23, hlsl::promote<vector_type>(1.0 )/base_type::eta12, flip);
760775 return orientedFresnel;
761776 }
762777
0 commit comments