pbrBRDFFunctions.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Do not edit.
  2. import { ShaderStore } from "../../Engines/shaderStore.js";
  3. const name = "pbrBRDFFunctions";
  4. const shader = `#define FRESNEL_MAXIMUM_ON_ROUGH 0.25
  5. #ifdef MS_BRDF_ENERGY_CONSERVATION
  6. vec3 getEnergyConservationFactor(const vec3 specularEnvironmentR0,const vec3 environmentBrdf) {return 1.0+specularEnvironmentR0*(1.0/environmentBrdf.y-1.0);}
  7. #endif
  8. #ifdef ENVIRONMENTBRDF
  9. vec3 getBRDFLookup(float NdotV,float perceptualRoughness) {vec2 UV=vec2(NdotV,perceptualRoughness);vec4 brdfLookup=texture2D(environmentBrdfSampler,UV);
  10. #ifdef ENVIRONMENTBRDF_RGBD
  11. brdfLookup.rgb=fromRGBD(brdfLookup.rgba);
  12. #endif
  13. return brdfLookup.rgb;}
  14. vec3 getReflectanceFromBRDFLookup(const vec3 specularEnvironmentR0,const vec3 specularEnvironmentR90,const vec3 environmentBrdf) {
  15. #ifdef BRDF_V_HEIGHT_CORRELATED
  16. vec3 reflectance=(specularEnvironmentR90-specularEnvironmentR0)*environmentBrdf.x+specularEnvironmentR0*environmentBrdf.y;
  17. #else
  18. vec3 reflectance=specularEnvironmentR0*environmentBrdf.x+specularEnvironmentR90*environmentBrdf.y;
  19. #endif
  20. return reflectance;}
  21. vec3 getReflectanceFromBRDFLookup(const vec3 specularEnvironmentR0,const vec3 environmentBrdf) {
  22. #ifdef BRDF_V_HEIGHT_CORRELATED
  23. vec3 reflectance=mix(environmentBrdf.xxx,environmentBrdf.yyy,specularEnvironmentR0);
  24. #else
  25. vec3 reflectance=specularEnvironmentR0*environmentBrdf.x+environmentBrdf.y;
  26. #endif
  27. return reflectance;}
  28. #endif
  29. /* NOT USED
  30. #if defined(SHEEN) && defined(SHEEN_SOFTER)
  31. float getBRDFLookupCharlieSheen(float NdotV,float perceptualRoughness)
  32. {float c=1.0-NdotV;float c3=c*c*c;return 0.65584461*c3+1.0/(4.16526551+exp(-7.97291361*perceptualRoughness+6.33516894));}
  33. #endif
  34. */
  35. #if !defined(ENVIRONMENTBRDF) || defined(REFLECTIONMAP_SKYBOX) || defined(ALPHAFRESNEL)
  36. vec3 getReflectanceFromAnalyticalBRDFLookup_Jones(float VdotN,vec3 reflectance0,vec3 reflectance90,float smoothness)
  37. {float weight=mix(FRESNEL_MAXIMUM_ON_ROUGH,1.0,smoothness);return reflectance0+weight*(reflectance90-reflectance0)*pow5(saturate(1.0-VdotN));}
  38. #endif
  39. #if defined(SHEEN) && defined(ENVIRONMENTBRDF)
  40. /**
  41. * The sheen BRDF not containing F can be easily stored in the blue channel of the BRDF texture.
  42. * The blue channel contains DCharlie*VAshikhmin*NdotL as a lokkup table
  43. */
  44. vec3 getSheenReflectanceFromBRDFLookup(const vec3 reflectance0,const vec3 environmentBrdf) {vec3 sheenEnvironmentReflectance=reflectance0*environmentBrdf.b;return sheenEnvironmentReflectance;}
  45. #endif
  46. vec3 fresnelSchlickGGX(float VdotH,vec3 reflectance0,vec3 reflectance90)
  47. {return reflectance0+(reflectance90-reflectance0)*pow5(1.0-VdotH);}
  48. float fresnelSchlickGGX(float VdotH,float reflectance0,float reflectance90)
  49. {return reflectance0+(reflectance90-reflectance0)*pow5(1.0-VdotH);}
  50. #ifdef CLEARCOAT
  51. vec3 getR0RemappedForClearCoat(vec3 f0) {
  52. #ifdef CLEARCOAT_DEFAULTIOR
  53. #ifdef MOBILE
  54. return saturate(f0*(f0*0.526868+0.529324)-0.0482256);
  55. #else
  56. return saturate(f0*(f0*(0.941892-0.263008*f0)+0.346479)-0.0285998);
  57. #endif
  58. #else
  59. vec3 s=sqrt(f0);vec3 t=(vClearCoatRefractionParams.z+vClearCoatRefractionParams.w*s)/(vClearCoatRefractionParams.w+vClearCoatRefractionParams.z*s);return square(t);
  60. #endif
  61. }
  62. #endif
  63. #ifdef IRIDESCENCE
  64. const mat3 XYZ_TO_REC709=mat3(
  65. 3.2404542,-0.9692660, 0.0556434,
  66. -1.5371385, 1.8760108,-0.2040259,
  67. -0.4985314, 0.0415560, 1.0572252
  68. );vec3 getIORTfromAirToSurfaceR0(vec3 f0) {vec3 sqrtF0=sqrt(f0);return (1.+sqrtF0)/(1.-sqrtF0);}
  69. vec3 getR0fromIORs(vec3 iorT,float iorI) {return square((iorT-vec3(iorI))/(iorT+vec3(iorI)));}
  70. float getR0fromIORs(float iorT,float iorI) {return square((iorT-iorI)/(iorT+iorI));}
  71. vec3 evalSensitivity(float opd,vec3 shift) {float phase=2.0*PI*opd*1.0e-9;const vec3 val=vec3(5.4856e-13,4.4201e-13,5.2481e-13);const vec3 pos=vec3(1.6810e+06,1.7953e+06,2.2084e+06);const vec3 var=vec3(4.3278e+09,9.3046e+09,6.6121e+09);vec3 xyz=val*sqrt(2.0*PI*var)*cos(pos*phase+shift)*exp(-square(phase)*var);xyz.x+=9.7470e-14*sqrt(2.0*PI*4.5282e+09)*cos(2.2399e+06*phase+shift[0])*exp(-4.5282e+09*square(phase));xyz/=1.0685e-7;vec3 srgb=XYZ_TO_REC709*xyz;return srgb;}
  72. vec3 evalIridescence(float outsideIOR,float eta2,float cosTheta1,float thinFilmThickness,vec3 baseF0) {vec3 I=vec3(1.0);float iridescenceIOR=mix(outsideIOR,eta2,smoothstep(0.0,0.03,thinFilmThickness));float sinTheta2Sq=square(outsideIOR/iridescenceIOR)*(1.0-square(cosTheta1));float cosTheta2Sq=1.0-sinTheta2Sq;if (cosTheta2Sq<0.0) {return I;}
  73. float cosTheta2=sqrt(cosTheta2Sq);float R0=getR0fromIORs(iridescenceIOR,outsideIOR);float R12=fresnelSchlickGGX(cosTheta1,R0,1.);float R21=R12;float T121=1.0-R12;float phi12=0.0;if (iridescenceIOR<outsideIOR) phi12=PI;float phi21=PI-phi12;vec3 baseIOR=getIORTfromAirToSurfaceR0(clamp(baseF0,0.0,0.9999));
  74. vec3 R1=getR0fromIORs(baseIOR,iridescenceIOR);vec3 R23=fresnelSchlickGGX(cosTheta2,R1,vec3(1.));vec3 phi23=vec3(0.0);if (baseIOR[0]<iridescenceIOR) phi23[0]=PI;if (baseIOR[1]<iridescenceIOR) phi23[1]=PI;if (baseIOR[2]<iridescenceIOR) phi23[2]=PI;float opd=2.0*iridescenceIOR*thinFilmThickness*cosTheta2;vec3 phi=vec3(phi21)+phi23;vec3 R123=clamp(R12*R23,1e-5,0.9999);vec3 r123=sqrt(R123);vec3 Rs=square(T121)*R23/(vec3(1.0)-R123);vec3 C0=R12+Rs;I=C0;vec3 Cm=Rs-T121;for (int m=1; m<=2; ++m)
  75. {Cm*=r123;vec3 Sm=2.0*evalSensitivity(float(m)*opd,float(m)*phi);I+=Cm*Sm;}
  76. return max(I,vec3(0.0));}
  77. #endif
  78. float normalDistributionFunction_TrowbridgeReitzGGX(float NdotH,float alphaG)
  79. {float a2=square(alphaG);float d=NdotH*NdotH*(a2-1.0)+1.0;return a2/(PI*d*d);}
  80. #ifdef SHEEN
  81. float normalDistributionFunction_CharlieSheen(float NdotH,float alphaG)
  82. {float invR=1./alphaG;float cos2h=NdotH*NdotH;float sin2h=1.-cos2h;return (2.+invR)*pow(sin2h,invR*.5)/(2.*PI);}
  83. #endif
  84. #ifdef ANISOTROPIC
  85. float normalDistributionFunction_BurleyGGX_Anisotropic(float NdotH,float TdotH,float BdotH,const vec2 alphaTB) {float a2=alphaTB.x*alphaTB.y;vec3 v=vec3(alphaTB.y*TdotH,alphaTB.x *BdotH,a2*NdotH);float v2=dot(v,v);float w2=a2/v2;return a2*w2*w2*RECIPROCAL_PI;}
  86. #endif
  87. #ifdef BRDF_V_HEIGHT_CORRELATED
  88. float smithVisibility_GGXCorrelated(float NdotL,float NdotV,float alphaG) {
  89. #ifdef MOBILE
  90. float GGXV=NdotL*(NdotV*(1.0-alphaG)+alphaG);float GGXL=NdotV*(NdotL*(1.0-alphaG)+alphaG);return 0.5/(GGXV+GGXL);
  91. #else
  92. float a2=alphaG*alphaG;float GGXV=NdotL*sqrt(NdotV*(NdotV-a2*NdotV)+a2);float GGXL=NdotV*sqrt(NdotL*(NdotL-a2*NdotL)+a2);return 0.5/(GGXV+GGXL);
  93. #endif
  94. }
  95. #else
  96. float smithVisibilityG1_TrowbridgeReitzGGXFast(float dot,float alphaG)
  97. {
  98. #ifdef MOBILE
  99. return 1.0/(dot+alphaG+(1.0-alphaG)*dot ));
  100. #else
  101. float alphaSquared=alphaG*alphaG;return 1.0/(dot+sqrt(alphaSquared+(1.0-alphaSquared)*dot*dot));
  102. #endif
  103. }
  104. float smithVisibility_TrowbridgeReitzGGXFast(float NdotL,float NdotV,float alphaG)
  105. {float visibility=smithVisibilityG1_TrowbridgeReitzGGXFast(NdotL,alphaG)*smithVisibilityG1_TrowbridgeReitzGGXFast(NdotV,alphaG);return visibility;}
  106. #endif
  107. #ifdef ANISOTROPIC
  108. float smithVisibility_GGXCorrelated_Anisotropic(float NdotL,float NdotV,float TdotV,float BdotV,float TdotL,float BdotL,const vec2 alphaTB) {float lambdaV=NdotL*length(vec3(alphaTB.x*TdotV,alphaTB.y*BdotV,NdotV));float lambdaL=NdotV*length(vec3(alphaTB.x*TdotL,alphaTB.y*BdotL,NdotL));float v=0.5/(lambdaV+lambdaL);return v;}
  109. #endif
  110. #ifdef CLEARCOAT
  111. float visibility_Kelemen(float VdotH) {return 0.25/(VdotH*VdotH); }
  112. #endif
  113. #ifdef SHEEN
  114. float visibility_Ashikhmin(float NdotL,float NdotV)
  115. {return 1./(4.*(NdotL+NdotV-NdotL*NdotV));}
  116. /* NOT USED
  117. #ifdef SHEEN_SOFTER
  118. float l(float x,float alphaG)
  119. {float oneMinusAlphaSq=(1.0-alphaG)*(1.0-alphaG);float a=mix(21.5473,25.3245,oneMinusAlphaSq);float b=mix(3.82987,3.32435,oneMinusAlphaSq);float c=mix(0.19823,0.16801,oneMinusAlphaSq);float d=mix(-1.97760,-1.27393,oneMinusAlphaSq);float e=mix(-4.32054,-4.85967,oneMinusAlphaSq);return a/(1.0+b*pow(x,c))+d*x+e;}
  120. float lambdaSheen(float cosTheta,float alphaG)
  121. {return abs(cosTheta)<0.5 ? exp(l(cosTheta,alphaG)) : exp(2.0*l(0.5,alphaG)-l(1.0-cosTheta,alphaG));}
  122. float visibility_CharlieSheen(float NdotL,float NdotV,float alphaG)
  123. {float G=1.0/(1.0+lambdaSheen(NdotV,alphaG)+lambdaSheen(NdotL,alphaG));return G/(4.0*NdotV*NdotL);}
  124. #endif
  125. */
  126. #endif
  127. float diffuseBRDF_Burley(float NdotL,float NdotV,float VdotH,float roughness) {float diffuseFresnelNV=pow5(saturateEps(1.0-NdotL));float diffuseFresnelNL=pow5(saturateEps(1.0-NdotV));float diffuseFresnel90=0.5+2.0*VdotH*VdotH*roughness;float fresnel =
  128. (1.0+(diffuseFresnel90-1.0)*diffuseFresnelNL) *
  129. (1.0+(diffuseFresnel90-1.0)*diffuseFresnelNV);return fresnel/PI;}
  130. #ifdef SS_TRANSLUCENCY
  131. vec3 transmittanceBRDF_Burley(const vec3 tintColor,const vec3 diffusionDistance,float thickness) {vec3 S=1./maxEps(diffusionDistance);vec3 temp=exp((-0.333333333*thickness)*S);return tintColor.rgb*0.25*(temp*temp*temp+3.0*temp);}
  132. float computeWrappedDiffuseNdotL(float NdotL,float w) {float t=1.0+w;float invt2=1.0/square(t);return saturate((NdotL+w)*invt2);}
  133. #endif
  134. `;
  135. // Sideeffect
  136. ShaderStore.IncludesShadersStore[name] = shader;
  137. /** @internal */
  138. export const pbrBRDFFunctions = { name, shader };
  139. //# sourceMappingURL=pbrBRDFFunctions.js.map