PBR.glsl 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "BRDF.glsl"
  2. #ifdef COMPILEPS
  3. vec3 SphereLight(vec3 worldPos, vec3 lightVec, vec3 normal, vec3 toCamera, float roughness, vec3 specColor, out float ndl)
  4. {
  5. vec3 pos = (cLightPosPS.xyz - worldPos);
  6. float radius = cLightRad;
  7. vec3 reflectVec = reflect(-toCamera, normal);
  8. vec3 centreToRay = dot(pos, reflectVec) * reflectVec - pos;
  9. vec3 closestPoint = pos + centreToRay * clamp(radius / length(centreToRay), 0.0, 1.0);
  10. vec3 l = normalize(closestPoint);
  11. vec3 h = normalize(toCamera + l);
  12. ndl = clamp(dot(normal, l), 0.0, 1.0);
  13. float hdn = clamp(dot(h, normal), 0.0, 1.0);
  14. float hdv = dot(h, toCamera);
  15. float ndv = clamp(dot(normal, toCamera), 0.0, 1.0);
  16. float distL = length(pos);
  17. float alpha = roughness * roughness;
  18. float alphaPrime = clamp(radius / (distL * 2.0) + alpha, 0.0, 1.0);
  19. vec3 fresnelTerm = Fresnel(specColor, hdv) ;
  20. float distTerm = Distribution(hdn, alphaPrime);
  21. float visTerm = Visibility(ndl, ndv, roughness);
  22. return distTerm * visTerm * fresnelTerm ;
  23. }
  24. vec3 TubeLight(vec3 worldPos, vec3 lightVec, vec3 normal, vec3 toCamera, float roughness, vec3 specColor, out float ndl)
  25. {
  26. float radius = cLightRad;
  27. float len = cLightLength;
  28. vec3 pos = (cLightPosPS.xyz - worldPos);
  29. vec3 reflectVec = reflect(-toCamera, normal);
  30. vec3 L01 = cLightDirPS * len;
  31. vec3 L0 = pos - 0.5 * L01;
  32. vec3 L1 = pos + 0.5 * L01;
  33. vec3 ld = L1 - L0;
  34. float distL0 = length( L0 );
  35. float distL1 = length( L1 );
  36. float NoL0 = dot( L0, normal ) / ( 2.0 * distL0 );
  37. float NoL1 = dot( L1, normal ) / ( 2.0 * distL1 );
  38. ndl = ( 2.0 * clamp( NoL0 + NoL1, 0.0, 1.0 ) )
  39. / ( distL0 * distL1 + dot( L0, L1 ) + 2.0 );
  40. float a = len * len;
  41. float b = dot( reflectVec, L01 );
  42. float t = clamp( dot( L0, b * reflectVec - L01 ) / (a - b*b), 0.0, 1.0 );
  43. vec3 closestPoint = L0 + ld * clamp(t, 0.0, 1.0);
  44. vec3 centreToRay = dot( closestPoint, reflectVec ) * reflectVec - closestPoint;
  45. closestPoint = closestPoint + centreToRay * clamp(radius / length(centreToRay), 0.0, 1.0);
  46. vec3 l = normalize(closestPoint);
  47. vec3 h = normalize(toCamera + l);
  48. ndl = clamp(dot(normal, lightVec), 0.0, 1.0);
  49. float hdn = clamp(dot(h, normal), 0.0, 1.0);
  50. float hdv = dot(h, toCamera);
  51. float ndv = clamp(dot(normal, toCamera), 0.0 ,1.0);
  52. float distL = length(closestPoint);
  53. float alpha = roughness * roughness;
  54. float alphaPrime = clamp(radius / (distL * 2.0) + alpha, 0.0, 1.0);
  55. vec3 fresnelTerm = Fresnel(specColor, hdv) ;
  56. float distTerm = Distribution(hdn, alphaPrime);
  57. float visTerm = Visibility(ndl, ndv, roughness);
  58. return distTerm * visTerm * fresnelTerm ;
  59. }
  60. //Return the PBR BRDF value
  61. // lightDir = the vector to the light
  62. // lightVev = normalised lightDir
  63. // toCamera = vector to the camera
  64. // normal = surface normal of the pixel
  65. // roughness = roughness of the pixel
  66. // diffColor = the rgb color of the pixel
  67. // specColor = the rgb specular color of the pixel
  68. vec3 GetBRDF(vec3 worldPos, vec3 lightDir, vec3 lightVec, vec3 toCamera, vec3 normal, float roughness, vec3 diffColor, vec3 specColor)
  69. {
  70. vec3 Hn = normalize(toCamera + lightDir);
  71. float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
  72. float ndh = clamp((dot(normal, Hn)), M_EPSILON, 1.0);
  73. float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
  74. float ndv = clamp((dot(normal, toCamera)), M_EPSILON, 1.0);
  75. vec3 diffuseFactor = Diffuse(diffColor, roughness, ndv, ndl, vdh);
  76. vec3 specularFactor = vec3(0.0, 0.0, 0.0);
  77. #ifdef SPECULAR
  78. if(cLightRad > 0.0)
  79. {
  80. if(cLightLength > 0.0)
  81. {
  82. specularFactor = TubeLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
  83. specularFactor *= ndl;
  84. }
  85. else
  86. {
  87. specularFactor = SphereLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
  88. specularFactor *= ndl;
  89. }
  90. }
  91. else
  92. {
  93. vec3 fresnelTerm = Fresnel(specColor, vdh) ;
  94. float distTerm = Distribution(ndh, roughness);
  95. float visTerm = Visibility(ndl, ndv, roughness);
  96. specularFactor = fresnelTerm * distTerm * visTerm / M_PI;
  97. }
  98. #endif
  99. return diffuseFactor + specularFactor;
  100. }
  101. #endif