Variable getPBRIridescenceConst
getPBRIridescence: "\n// XYZ to linear-sRGB color space\nconst XYZ_TO_REC709: mat3x3f = mat3x3f(\n 3.2404542, -0.9692660, 0.0556434,\n -1.5371385, 1.8760108, -0.2040259,\n -0.4985314, 0.0415560, 1.0572252\n);\n\n// Assume air interface for top\n// Note: We don't handle the case fresnel0 == 1\nfn Fresnel0ToIor( fresnel0: vec3f ) -> vec3f {\n let sqrtF0: vec3f = sqrt( fresnel0 );\n return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n}\n\n// Conversion FO/IOR\nfn IorToFresnel0_3( transmittedIor: vec3f, incidentIor: f32 ) -> vec3f {\n let iorToFresnel: vec3f = ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) );\n return iorToFresnel * iorToFresnel;\n}\n\n// ior is a value between 1.0 and 3.0. 1.0 is air interface\nfn IorToFresnel0( transmittedIor: f32, incidentIor: f32 ) -> f32 {\n return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n}\n\n// Fresnel equations for dielectric/dielectric interfaces.\n// Ref: https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html\n// Evaluation XYZ sensitivity curves in Fourier space\nfn evalSensitivity( OPD: f32, shift: vec3f ) -> vec3f {\n let phase: f32 = 2.0 * PI * OPD * 1.0e-9;\n let val: vec3f = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n let pos: vec3f = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n let vari: vec3f = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\n var xyz: vec3f = val * sqrt( 2.0 * PI * vari ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * vari );\n xyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n xyz /= 1.0685e-7;\n\n let rgb: vec3f = XYZ_TO_REC709 * xyz;\n return rgb;\n}\n\nfn evalIridescence( outsideIOR: f32, eta2: f32, cosTheta1: f32, thinFilmThickness: f32, baseF0: vec3f ) -> vec3f {\n var I: vec3f;\n\n // Force iridescenceIOR -> outsideIOR when thinFilmThickness -> 0.0\n let iridescenceIOR: f32 = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n // Evaluate the cosTheta on the base layer (Snell law)\n let sinTheta2Sq: f32 = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\n // Handle TIR:\n let cosTheta2Sq: f32 = 1.0 - sinTheta2Sq;\n if ( cosTheta2Sq < 0.0 ) {\n return vec3( 1.0 );\n }\n\n let cosTheta2: f32 = sqrt( cosTheta2Sq );\n\n // First interface\n let R0: f32 = IorToFresnel0( iridescenceIOR, outsideIOR );\n let R12: f32 = F_Schlick_1( R0, 1.0, cosTheta1 );\n let T121: f32 = 1.0 - R12;\n var phi12: f32 = 0.0;\n if ( iridescenceIOR < outsideIOR ) {\n phi12 = PI;\n }\n let phi21: f32 = PI - phi12;\n\n // Second interface\n let baseIOR: vec3f = Fresnel0ToIor( clamp( baseF0, vec3(0.0), vec3(0.9999) ) ); // guard against 1.0\n let R1: vec3f = IorToFresnel0_3( baseIOR, iridescenceIOR );\n let R23: vec3f = F_Schlick( R1, 1.0, cosTheta2 );\n var phi23: vec3f = vec3( 0.0 );\n if ( baseIOR[ 0 ] < iridescenceIOR ) {\n phi23[ 0 ] = PI;\n }\n if ( baseIOR[ 1 ] < iridescenceIOR ) {\n phi23[ 1 ] = PI;\n }\n if ( baseIOR[ 2 ] < iridescenceIOR ) {\n phi23[ 2 ] = PI;\n }\n\n // Phase shift\n let OPD: f32 = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n let phi: vec3f = vec3( phi21 ) + phi23;\n\n // Compound terms\n let R123: vec3f = clamp( R12 * R23, vec3(1e-5), vec3(0.9999) );\n let r123: vec3f = sqrt( R123 );\n let Rs: vec3f = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\n // Reflectance term for m = 0 (DC term amplitude)\n let C0: vec3f = R12 + Rs;\n I = C0;\n\n // Reflectance term for m > 0 (pairs of diracs)\n var Cm: vec3f = Rs - T121;\n for (var m = 1u; m <= 2; m++ ) {\n Cm *= r123;\n let Sm: vec3f = 2.0 * evalSensitivity( f32( m ) * OPD, f32( m ) * phi );\n I += Cm * Sm;\n }\n\n // Since out of gamut colors might be produced, negative color values are clamped to 0.\n return max( I, vec3( 0.0 ) );\n}" = ...
Helper WGSL functions to get the PBR direct iridescence contribution.