pbrDirectLightingFunctions.fx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #define CLEARCOATREFLECTANCE90 1.0
  2. // Light Results
  3. struct lightingInfo
  4. {
  5. vec3 diffuse;
  6. #ifdef SPECULARTERM
  7. vec3 specular;
  8. #endif
  9. #ifdef CLEARCOAT
  10. // xyz contains the clearcoat color.
  11. // w contains the 1 - clearcoat fresnel to ease the energy conservation computation.
  12. vec4 clearCoat;
  13. #endif
  14. #ifdef SHEEN
  15. vec3 sheen;
  16. #endif
  17. };
  18. // Simulate area (small) lights by increasing roughness
  19. float adjustRoughnessFromLightProperties(float roughness, float lightRadius, float lightDistance) {
  20. #if defined(USEPHYSICALLIGHTFALLOFF) || defined(USEGLTFLIGHTFALLOFF)
  21. // At small angle this approximation works.
  22. float lightRoughness = lightRadius / lightDistance;
  23. // Distribution can sum.
  24. float totalRoughness = saturate(lightRoughness + roughness);
  25. return totalRoughness;
  26. #else
  27. return roughness;
  28. #endif
  29. }
  30. vec3 computeHemisphericDiffuseLighting(preLightingInfo info, vec3 lightColor, vec3 groundColor) {
  31. return mix(groundColor, lightColor, info.NdotL);
  32. }
  33. vec3 computeDiffuseLighting(preLightingInfo info, vec3 lightColor) {
  34. float diffuseTerm = diffuseBRDF_Burley(info.NdotL, info.NdotV, info.VdotH, info.roughness);
  35. return diffuseTerm * info.attenuation * info.NdotL * lightColor;
  36. }
  37. vec3 computeProjectionTextureDiffuseLighting(sampler2D projectionLightSampler, mat4 textureProjectionMatrix){
  38. vec4 strq = textureProjectionMatrix * vec4(vPositionW, 1.0);
  39. strq /= strq.w;
  40. vec3 textureColor = texture2D(projectionLightSampler, strq.xy).rgb;
  41. return toLinearSpace(textureColor);
  42. }
  43. #ifdef SS_TRANSLUCENCY
  44. vec3 computeDiffuseAndTransmittedLighting(preLightingInfo info, vec3 lightColor, vec3 transmittance) {
  45. float NdotL = absEps(info.NdotLUnclamped);
  46. // Use wrap lighting to simulate SSS.
  47. float wrapNdotL = computeWrappedDiffuseNdotL(NdotL, 0.02);
  48. // Remap transmittance from tr to 1. if ndotl is negative.
  49. float trAdapt = step(0., info.NdotLUnclamped);
  50. vec3 transmittanceNdotL = mix(transmittance * wrapNdotL, vec3(wrapNdotL), trAdapt);
  51. float diffuseTerm = diffuseBRDF_Burley(NdotL, info.NdotV, info.VdotH, info.roughness);
  52. return diffuseTerm * transmittanceNdotL * info.attenuation * lightColor;
  53. }
  54. #endif
  55. #ifdef SPECULARTERM
  56. vec3 computeSpecularLighting(preLightingInfo info, vec3 N, vec3 reflectance0, vec3 reflectance90, float geometricRoughnessFactor, vec3 lightColor) {
  57. float NdotH = saturateEps(dot(N, info.H));
  58. float roughness = max(info.roughness, geometricRoughnessFactor);
  59. float alphaG = convertRoughnessToAverageSlope(roughness);
  60. vec3 fresnel = fresnelSchlickGGX(info.VdotH, reflectance0, reflectance90);
  61. float distribution = normalDistributionFunction_TrowbridgeReitzGGX(NdotH, alphaG);
  62. #ifdef BRDF_V_HEIGHT_CORRELATED
  63. float visibility = smithVisibility_GGXCorrelated(info.NdotL, info.NdotV, alphaG);
  64. #else
  65. float visibility = smithVisibility_TrowbridgeReitzGGXFast(info.NdotL, info.NdotV, alphaG);
  66. #endif
  67. vec3 specTerm = fresnel * distribution * visibility;
  68. return specTerm * info.attenuation * info.NdotL * lightColor;
  69. }
  70. #endif
  71. #ifdef ANISOTROPIC
  72. vec3 computeAnisotropicSpecularLighting(preLightingInfo info, vec3 V, vec3 N, vec3 T, vec3 B, float anisotropy, vec3 reflectance0, vec3 reflectance90, float geometricRoughnessFactor, vec3 lightColor) {
  73. float NdotH = saturateEps(dot(N, info.H));
  74. float TdotH = dot(T, info.H);
  75. float BdotH = dot(B, info.H);
  76. float TdotV = dot(T, V);
  77. float BdotV = dot(B, V);
  78. float TdotL = dot(T, info.L);
  79. float BdotL = dot(B, info.L);
  80. float alphaG = convertRoughnessToAverageSlope(info.roughness);
  81. vec2 alphaTB = getAnisotropicRoughness(alphaG, anisotropy);
  82. alphaTB = max(alphaTB, square(geometricRoughnessFactor));
  83. vec3 fresnel = fresnelSchlickGGX(info.VdotH, reflectance0, reflectance90);
  84. float distribution = normalDistributionFunction_BurleyGGX_Anisotropic(NdotH, TdotH, BdotH, alphaTB);
  85. float visibility = smithVisibility_GGXCorrelated_Anisotropic(info.NdotL, info.NdotV, TdotV, BdotV, TdotL, BdotL, alphaTB);
  86. vec3 specTerm = fresnel * distribution * visibility;
  87. return specTerm * info.attenuation * info.NdotL * lightColor;
  88. }
  89. #endif
  90. #ifdef CLEARCOAT
  91. vec4 computeClearCoatLighting(preLightingInfo info, vec3 Ncc, float geometricRoughnessFactor, float clearCoatIntensity, vec3 lightColor) {
  92. float NccdotL = saturateEps(dot(Ncc, info.L));
  93. float NccdotH = saturateEps(dot(Ncc, info.H));
  94. float clearCoatRoughness = max(info.roughness, geometricRoughnessFactor);
  95. float alphaG = convertRoughnessToAverageSlope(clearCoatRoughness);
  96. float fresnel = fresnelSchlickGGX(info.VdotH, vClearCoatRefractionParams.x, CLEARCOATREFLECTANCE90);
  97. fresnel *= clearCoatIntensity;
  98. float distribution = normalDistributionFunction_TrowbridgeReitzGGX(NccdotH, alphaG);
  99. float visibility = visibility_Kelemen(info.VdotH);
  100. float clearCoatTerm = fresnel * distribution * visibility;
  101. return vec4(
  102. clearCoatTerm * info.attenuation * NccdotL * lightColor,
  103. 1.0 - fresnel
  104. );
  105. }
  106. vec3 computeClearCoatLightingAbsorption(float NdotVRefract, vec3 L, vec3 Ncc, vec3 clearCoatColor, float clearCoatThickness, float clearCoatIntensity) {
  107. vec3 LRefract = -refract(L, Ncc, vClearCoatRefractionParams.y);
  108. float NdotLRefract = saturateEps(dot(Ncc, LRefract));
  109. vec3 absorption = computeClearCoatAbsorption(NdotVRefract, NdotLRefract, clearCoatColor, clearCoatThickness, clearCoatIntensity);
  110. return absorption;
  111. }
  112. #endif
  113. #ifdef SHEEN
  114. vec3 computeSheenLighting(preLightingInfo info, vec3 N, vec3 reflectance0, vec3 reflectance90, float geometricRoughnessFactor, vec3 lightColor) {
  115. float NdotH = saturateEps(dot(N, info.H));
  116. float roughness = max(info.roughness, geometricRoughnessFactor);
  117. float alphaG = convertRoughnessToAverageSlope(roughness);
  118. // No Fresnel Effect with sheen
  119. // vec3 fresnel = fresnelSchlickGGX(info.VdotH, reflectance0, reflectance90);
  120. vec3 fresnel = reflectance0;
  121. float distribution = normalDistributionFunction_CharlieSheen(NdotH, alphaG);
  122. float visibility = visibility_Ashikhmin(info.NdotL, info.NdotV);
  123. vec3 sheenTerm = fresnel * distribution * visibility;
  124. return sheenTerm * info.attenuation * info.NdotL * lightColor;
  125. }
  126. #endif