BRDF.glsl 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #line 20001
  2. #ifdef COMPILEPS
  3. #ifdef PBR
  4. // Following BRDF methods are based upon research Frostbite EA
  5. //[Lagrade et al. 2014, "Moving Frostbite to Physically Based Rendering"]
  6. //Schlick Fresnel
  7. //specular = the rgb specular color value of the pixel
  8. //VdotH = the dot product of the camera view direction and the half vector
  9. vec3 SchlickFresnel(vec3 specular, float VdotH)
  10. {
  11. return specular + (vec3(1.0, 1.0, 1.0) - specular) * pow(1.0 - VdotH, 5.0);
  12. }
  13. //Schlick Gaussian Fresnel
  14. //specular = the rgb specular color value of the pixel
  15. //VdotH = the dot product of the camera view direction and the half vector
  16. vec3 SchlickGaussianFresnel(in vec3 specular, in float VdotH)
  17. {
  18. float sphericalGaussian = pow(2.0, (-5.55473 * VdotH - 6.98316) * VdotH);
  19. return specular + (vec3(1.0, 1.0, 1.0) - specular) * sphericalGaussian;
  20. }
  21. vec3 SchlickFresnelCustom(vec3 specular, float LdotH)
  22. {
  23. float ior = 0.25;
  24. float airIor = 1.000277;
  25. float f0 = (ior - airIor) / (ior + airIor);
  26. float max_ior = 2.5;
  27. f0 = clamp(f0 * f0, 0.0, (max_ior - airIor) / (max_ior + airIor));
  28. return specular * (f0 + (1 - f0) * pow(2, (-5.55473 * LdotH - 6.98316) * LdotH));
  29. }
  30. //Get Fresnel
  31. //specular = the rgb specular color value of the pixel
  32. //VdotH = the dot product of the camera view direction and the half vector
  33. vec3 Fresnel(vec3 specular, float VdotH, float LdotH)
  34. {
  35. return SchlickFresnelCustom(specular, LdotH);
  36. //return SchlickFresnel(specular, VdotH);
  37. }
  38. // Smith GGX corrected Visibility
  39. // NdotL = the dot product of the normal and direction to the light
  40. // NdotV = the dot product of the normal and the camera view direction
  41. // roughness = the roughness of the pixel
  42. float SmithGGXSchlickVisibility(float NdotL, float NdotV, float roughness)
  43. {
  44. float rough2 = roughness * roughness;
  45. float lambdaV = NdotL * sqrt((-NdotV * rough2 + NdotV) * NdotV + rough2);
  46. float lambdaL = NdotV * sqrt((-NdotL * rough2 + NdotL) * NdotL + rough2);
  47. return 0.5 / (lambdaV + lambdaL);
  48. }
  49. float NeumannVisibility(float NdotV, float NdotL)
  50. {
  51. return NdotL * NdotV / max(1e-7, max(NdotL, NdotV));
  52. }
  53. // Get Visibility
  54. // NdotL = the dot product of the normal and direction to the light
  55. // NdotV = the dot product of the normal and the camera view direction
  56. // roughness = the roughness of the pixel
  57. float Visibility(float NdotL, float NdotV, float roughness)
  58. {
  59. return NeumannVisibility(NdotV, NdotL);
  60. //return SmithGGXSchlickVisibility(NdotL, NdotV, roughness);
  61. }
  62. // Blinn Distribution
  63. // NdotH = the dot product of the normal and the half vector
  64. // roughness = the roughness of the pixel
  65. float BlinnPhongDistribution(in float NdotH, in float roughness)
  66. {
  67. float specPower = max((2.0 / (roughness * roughness)) - 2.0, 1e-4); // Calculate specular power from roughness
  68. return pow(clamp(NdotH, 0.0, 1.0), specPower);
  69. }
  70. // Beckmann Distribution
  71. // NdotH = the dot product of the normal and the half vector
  72. // roughness = the roughness of the pixel
  73. float BeckmannDistribution(in float NdotH, in float roughness)
  74. {
  75. float rough2 = roughness * roughness;
  76. float roughnessA = 1.0 / (4.0 * rough2 * pow(NdotH, 4.0));
  77. float roughnessB = NdotH * NdotH - 1.0;
  78. float roughnessC = rough2 * NdotH * NdotH;
  79. return roughnessA * exp(roughnessB / roughnessC);
  80. }
  81. // GGX Distribution
  82. // NdotH = the dot product of the normal and the half vector
  83. // roughness = the roughness of the pixel
  84. float GGXDistribution(float NdotH, float roughness)
  85. {
  86. float rough2 = roughness * roughness;
  87. float tmp = (NdotH * rough2 - NdotH) * NdotH + 1.0;
  88. return rough2 / (tmp * tmp);
  89. }
  90. // Get Distribution
  91. // NdotH = the dot product of the normal and the half vector
  92. // roughness = the roughness of the pixel
  93. float Distribution(float NdotH, float roughness)
  94. {
  95. return GGXDistribution(NdotH, roughness);
  96. }
  97. // Lambertian Diffuse
  98. // diffuseColor = the rgb color value of the pixel
  99. // roughness = the roughness of the pixel
  100. // NdotV = the normal dot with the camera view direction
  101. // NdotL = the normal dot with the light direction
  102. // VdotH = the camera view direction dot with the half vector
  103. vec3 LambertianDiffuse(vec3 diffuseColor)
  104. {
  105. return diffuseColor * (1.0 / M_PI) ;
  106. }
  107. // Custom Lambertian Diffuse
  108. // diffuseColor = the rgb color value of the pixel
  109. // roughness = the roughness of the pixel
  110. // NdotV = the normal dot with the camera view direction
  111. // NdotL = the normal dot with the light direction
  112. // VdotH = the camera view direction dot with the half vector
  113. vec3 CustomLambertianDiffuse(vec3 diffuseColor, float NdotV, float roughness)
  114. {
  115. return diffuseColor * (1.0 / M_PI) * pow(NdotV, 0.5 + 0.3 * roughness);
  116. }
  117. // Burley Diffuse
  118. // diffuseColor = the rgb color value of the pixel
  119. // roughness = the roughness of the pixel
  120. // NdotV = the normal dot with the camera view direction
  121. // NdotL = the normal dot with the light direction
  122. // VdotH = the camera view direction dot with the half vector
  123. vec3 BurleyDiffuse(vec3 diffuseColor, float roughness, float NdotV, float NdotL, float VdotH)
  124. {
  125. float energyBias = mix(roughness, 0.0, 0.5);
  126. float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
  127. float fd90 = energyBias + 2.0 * VdotH * VdotH * roughness;
  128. float f0 = 1.0;
  129. float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NdotL, 5.0);
  130. float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NdotV, 5.0);
  131. return diffuseColor * lightScatter * viewScatter * energyFactor;
  132. }
  133. //Get Diffuse
  134. // diffuseColor = the rgb color value of the pixel
  135. // roughness = the roughness of the pixel
  136. // NdotV = the normal dot with the camera view direction
  137. // NdotL = the normal dot with the light direction
  138. // VdotH = the camera view direction dot with the half vector
  139. vec3 Diffuse(vec3 diffuseColor, float roughness, float NdotV, float NdotL, float VdotH)
  140. {
  141. //return LambertianDiffuse(diffuseColor);
  142. return CustomLambertianDiffuse(diffuseColor, NdotV, roughness);
  143. //return BurleyDiffuse(diffuseColor, roughness, NdotV, NdotL, VdotH);
  144. }
  145. #endif
  146. #endif