LightFunctions.glsl 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. // Contains functions for light calculations
  6. #ifndef ANKI_SHADERS_LIGHT_FUNCTIONS_GLSL
  7. #define ANKI_SHADERS_LIGHT_FUNCTIONS_GLSL
  8. #pragma anki include "shaders/Common.glsl"
  9. const float ATTENUATION_BOOST = 0.05;
  10. const float OMNI_LIGHT_FRUSTUM_NEAR_PLANE = 0.1 / 4.0;
  11. //==============================================================================
  12. /// Calculate the cluster split
  13. uint calcClusterSplit(float zVspace)
  14. {
  15. zVspace = -zVspace;
  16. float fk = sqrt(
  17. (zVspace - u_nearFarClustererDivisor.x) / u_nearFarClustererDivisor.z);
  18. uint k = uint(fk);
  19. return k;
  20. }
  21. //==============================================================================
  22. float computeAttenuationFactor(float lightRadius, vec3 frag2Light)
  23. {
  24. float fragLightDist = length(frag2Light);
  25. float att = (fragLightDist * lightRadius) + (1.0 + ATTENUATION_BOOST);
  26. att = max(0.0, att);
  27. att *= att;
  28. return att;
  29. }
  30. //==============================================================================
  31. // Performs BRDF specular lighting
  32. vec3 computeSpecularColorBrdf(
  33. vec3 v, // view dir
  34. vec3 l, // light dir
  35. vec3 n, // normal
  36. vec3 specCol,
  37. vec3 lightSpecCol,
  38. float a2, // rougness^2
  39. float nol) // N dot L
  40. {
  41. vec3 h = normalize(l + v);
  42. // Fresnel (Schlick)
  43. float loh = max(EPSILON, dot(l, h));
  44. vec3 f = specCol + (1.0 - specCol) * pow((1.0 + EPSILON - loh), 5.0);
  45. //float f = specColor + (1.0 - specColor)
  46. // * pow(2.0, (-5.55473 * loh - 6.98316) * loh);
  47. // NDF: GGX Trowbridge-Reitz
  48. float noh = max(EPSILON, dot(n, h));
  49. float d = a2 / (PI * pow(noh * noh * (a2 - 1.0) + 1.0, 2.0));
  50. // Visibility term: Geometric shadowing devided by BRDF denominator
  51. float nov = max(EPSILON, dot(n, v));
  52. float vv = nov + sqrt((nov - nov * a2) * nov + a2);
  53. float vl = nol + sqrt((nol - nol * a2) * nol + a2);
  54. float vis = 1.0 / (vv * vl);
  55. return f * (vis * d) * lightSpecCol;
  56. }
  57. //==============================================================================
  58. vec3 computeDiffuseColor(vec3 diffCol, vec3 lightDiffCol)
  59. {
  60. return diffCol * lightDiffCol;
  61. }
  62. //==============================================================================
  63. float computeSpotFactor(
  64. vec3 l,
  65. float outerCos,
  66. float innerCos,
  67. vec3 spotDir)
  68. {
  69. float costheta = -dot(l, spotDir);
  70. float spotFactor = smoothstep(outerCos, innerCos, costheta);
  71. return spotFactor;
  72. }
  73. //==============================================================================
  74. float computeShadowFactorSpot(mat4 lightProjectionMat, vec3 fragPos,
  75. float layer)
  76. {
  77. vec4 texCoords4 = lightProjectionMat * vec4(fragPos, 1.0);
  78. vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
  79. #if POISSON == 1
  80. const vec2 poissonDisk[4] = vec2[](
  81. vec2(-0.94201624, -0.39906216),
  82. vec2(0.94558609, -0.76890725),
  83. vec2(-0.094184101, -0.92938870),
  84. vec2(0.34495938, 0.29387760));
  85. float shadowFactor = 0.0;
  86. vec2 cordpart0 = vec2(layer, texCoords3.z);
  87. for(int i = 0; i < 4; i++)
  88. {
  89. vec2 cordpart1 = texCoords3.xy + poissonDisk[i] / (300.0);
  90. vec4 tcoord = vec4(cordpart1, cordpart0);
  91. shadowFactor += texture(u_spotMapArr, tcoord);
  92. }
  93. return shadowFactor / 4.0;
  94. #else
  95. vec4 tcoord = vec4(texCoords3.x, texCoords3.y, layer, texCoords3.z);
  96. float shadowFactor = texture(u_spotMapArr, tcoord);
  97. return shadowFactor;
  98. #endif
  99. }
  100. //==============================================================================
  101. float computeShadowFactorOmni(vec3 frag2Light, float layer, float radius)
  102. {
  103. vec3 dir = (u_viewMat * vec4(-frag2Light, 1.0)).xyz;
  104. vec3 dirabs = abs(dir);
  105. float dist = -max(dirabs.x, max(dirabs.y, dirabs.z));
  106. dir = normalize(dir);
  107. const float near = OMNI_LIGHT_FRUSTUM_NEAR_PLANE;
  108. const float far = radius;
  109. // Original code:
  110. // float g = near - far;
  111. // float z = (far + near) / g * dist + (2.0 * far * near) / g;
  112. // float w = -dist;
  113. // z /= w;
  114. // z = z * 0.5 + 0.5;
  115. // Optimized:
  116. float z = (far * (dist + near)) / (dist * (far - near));
  117. float shadowFactor = texture(u_omniMapArr, vec4(dir, layer), z).r;
  118. return shadowFactor;
  119. }
  120. #endif