BRDF.glsl 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. //Get Fresnel
  22. //specular = the rgb specular color value of the pixel
  23. //VdotH = the dot product of the camera view direction and the half vector
  24. vec3 Fresnel(vec3 specular, float VdotH)
  25. {
  26. return SchlickFresnel(specular, VdotH);
  27. }
  28. // Smith GGX corrected Visibility
  29. // NdotL = the dot product of the normal and direction to the light
  30. // NdotV = the dot product of the normal and the camera view direction
  31. // roughness = the roughness of the pixel
  32. float SmithGGXSchlickVisibility(float NdotL, float NdotV, float roughness)
  33. {
  34. float rough2 = roughness * roughness;
  35. float lambdaV = NdotL * sqrt((-NdotV * rough2 + NdotV) * NdotV + rough2);
  36. float lambdaL = NdotV * sqrt((-NdotL * rough2 + NdotL) * NdotL + rough2);
  37. return 0.5 / (lambdaV + lambdaL);
  38. }
  39. // Get Visibility
  40. // NdotL = the dot product of the normal and direction to the light
  41. // NdotV = the dot product of the normal and the camera view direction
  42. // roughness = the roughness of the pixel
  43. float Visibility(float NdotL, float NdotV, float roughness)
  44. {
  45. return SmithGGXSchlickVisibility(NdotL, NdotV, roughness);
  46. }
  47. // Blinn Distribution
  48. // NdotH = the dot product of the normal and the half vector
  49. // roughness = the roughness of the pixel
  50. float BlinnPhongDistribution(in float NdotH, in float roughness)
  51. {
  52. float specPower = max((2.0 / (roughness * roughness)) - 2.0, 1e-4); // Calculate specular power from roughness
  53. return pow(clamp(NdotH, 0.0, 1.0), specPower);
  54. }
  55. // Beckmann Distribution
  56. // NdotH = the dot product of the normal and the half vector
  57. // roughness = the roughness of the pixel
  58. float BeckmannDistribution(in float NdotH, in float roughness)
  59. {
  60. float rough2 = roughness * roughness;
  61. float roughnessA = 1.0 / (4.0 * rough2 * pow(NdotH, 4.0));
  62. float roughnessB = NdotH * NdotH - 1.0;
  63. float roughnessC = rough2 * NdotH * NdotH;
  64. return roughnessA * exp(roughnessB / roughnessC);
  65. }
  66. // GGX Distribution
  67. // NdotH = the dot product of the normal and the half vector
  68. // roughness = the roughness of the pixel
  69. float GGXDistribution(float NdotH, float roughness)
  70. {
  71. float rough2 = roughness * roughness;
  72. float tmp = (NdotH * rough2 - NdotH) * NdotH + 1.0;
  73. return rough2 / (tmp * tmp);
  74. }
  75. // Get Distribution
  76. // NdotH = the dot product of the normal and the half vector
  77. // roughness = the roughness of the pixel
  78. float Distribution(float NdotH, float roughness)
  79. {
  80. return GGXDistribution(NdotH, roughness);
  81. }
  82. // Lambertian Diffuse
  83. // diffuseColor = the rgb color value of the pixel
  84. // roughness = the roughness of the pixel
  85. // NdotV = the normal dot with the camera view direction
  86. // NdotL = the normal dot with the light direction
  87. // VdotH = the camera view direction dot with the half vector
  88. vec3 LambertianDiffuse(vec3 diffuseColor, float NdotL)
  89. {
  90. return diffuseColor * NdotL;
  91. }
  92. // Burley Diffuse
  93. // diffuseColor = the rgb color value of the pixel
  94. // roughness = the roughness of the pixel
  95. // NdotV = the normal dot with the camera view direction
  96. // NdotL = the normal dot with the light direction
  97. // VdotH = the camera view direction dot with the half vector
  98. vec3 BurleyDiffuse(vec3 diffuseColor, float roughness, float NdotV, float NdotL, float VdotH)
  99. {
  100. float energyBias = mix(roughness, 0.0, 0.5);
  101. float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
  102. float fd90 = energyBias + 2.0 * VdotH * VdotH * roughness;
  103. float f0 = 1.0;
  104. float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NdotL, 5.0);
  105. float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NdotV, 5.0);
  106. return diffuseColor * lightScatter * viewScatter * energyFactor;
  107. }
  108. //Get Diffuse
  109. // diffuseColor = the rgb color value of the pixel
  110. // roughness = the roughness of the pixel
  111. // NdotV = the normal dot with the camera view direction
  112. // NdotL = the normal dot with the light direction
  113. // VdotH = the camera view direction dot with the half vector
  114. vec3 Diffuse(vec3 diffuseColor, float roughness, float NdotV, float NdotL, float VdotH)
  115. {
  116. //return LambertianDiffuse(diffuseColor, NdotL);
  117. return BurleyDiffuse(diffuseColor, roughness, NdotV, NdotL, VdotH);
  118. }
  119. #endif
  120. #endif