Lighting.frag 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. float GetDiffuse(vec3 normal, vec3 lightVec, out vec3 lightDir)
  2. {
  3. #ifdef DIRLIGHT
  4. #ifdef NORMALMAP
  5. // In normal mapped forward lighting, the tangent space light vector needs renormalization
  6. lightDir = normalize(lightVec);
  7. #else
  8. lightDir = lightVec;
  9. #endif
  10. return max(dot(normal, lightDir), 0.0);
  11. #else
  12. float lightDist = length(lightVec);
  13. lightDir = lightVec / lightDist;
  14. return max(dot(normal, lightDir), 0.0) * texture2D(sLightRampMap, vec2(lightDist, 0.0)).r;
  15. #endif
  16. }
  17. float GetDiffuseVolumetric(vec3 lightVec)
  18. {
  19. #ifdef DIRLIGHT
  20. return 1.0;
  21. #else
  22. float lightDist = length(lightVec);
  23. return texture2D(sLightRampMap, vec2(lightDist, 0.0)).r;
  24. #endif
  25. }
  26. float GetSpecular(vec3 normal, vec3 eyeVec, vec3 lightDir, float specularPower)
  27. {
  28. vec3 halfVec = normalize(normalize(eyeVec) + lightDir);
  29. return pow(max(dot(normal, halfVec), 0.0), specularPower);
  30. }
  31. float GetIntensity(vec3 color)
  32. {
  33. return dot(color, vec3(0.333));
  34. }
  35. #ifdef SHADOW
  36. #ifdef DIRLIGHT
  37. #ifndef GL_ES
  38. #define NUMCASCADES 4
  39. #else
  40. #define NUMCASCADES 2
  41. #endif
  42. #else
  43. #define NUMCASCADES 1
  44. #endif
  45. float GetShadow(vec4 shadowPos)
  46. {
  47. #ifndef GL_ES
  48. #ifndef LQSHADOW
  49. // Take four samples and average them
  50. // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
  51. #ifndef POINTLIGHT
  52. vec2 offsets = cShadowMapInvSize * shadowPos.w;
  53. #else
  54. vec2 offsets = cShadowMapInvSize;
  55. #endif
  56. vec4 inLight = vec4(
  57. shadow2DProj(sShadowMap, shadowPos).r,
  58. shadow2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r,
  59. shadow2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r,
  60. shadow2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r
  61. );
  62. return cShadowIntensity.y + dot(inLight, vec4(cShadowIntensity.x));
  63. #else
  64. // Take one sample
  65. float inLight = shadow2DProj(sShadowMap, shadowPos).r;
  66. return cShadowIntensity.y + cShadowIntensity.x * inLight;
  67. #endif
  68. #else
  69. #ifndef LQSHADOW
  70. // Take four samples and average them
  71. vec2 offsets = cShadowMapInvSize * shadowPos.w;
  72. vec4 inLight = vec4(
  73. texture2DProj(sShadowMap, shadowPos).r * shadowPos.w > shadowPos.z,
  74. texture2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r * shadowPos.w > shadowPos.z,
  75. texture2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r * shadowPos.w > shadowPos.z,
  76. texture2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r * shadowPos.w > shadowPos.z
  77. );
  78. return cShadowIntensity.y + dot(inLight, vec4(cShadowIntensity.x));
  79. #else
  80. // Take one sample
  81. return cShadowIntensity.y + (texture2DProj(sShadowMap, shadowPos).r * shadowPos.w > shadowPos.z ? cShadowIntensity.x : 0.0);
  82. #endif
  83. #endif
  84. }
  85. #ifdef POINTLIGHT
  86. float GetPointShadow(vec3 lightVec)
  87. {
  88. vec3 axis = textureCube(sFaceSelectCubeMap, lightVec).rgb;
  89. float depth = abs(dot(lightVec, axis));
  90. // Expand the maximum component of the light vector to get full 0.0 - 1.0 UV range from the cube map,
  91. // and to avoid sampling across faces. Some GPU's filter across faces, while others do not, and in this
  92. // case filtering across faces is wrong
  93. const vec3 factor = vec3(1.0 / 256.0);
  94. lightVec += factor * axis * lightVec;
  95. // Read the 2D UV coordinates, adjust according to shadow map size and add face offset
  96. vec4 indirectPos = textureCube(sIndirectionCubeMap, lightVec);
  97. indirectPos.xy *= cShadowCubeAdjust.xy;
  98. indirectPos.xy += vec2(cShadowCubeAdjust.z + indirectPos.z * 0.5, cShadowCubeAdjust.w + indirectPos.w);
  99. vec4 shadowPos = vec4(indirectPos.xy, cShadowDepthFade.x + cShadowDepthFade.y / depth, 1.0);
  100. return GetShadow(shadowPos);
  101. }
  102. #endif
  103. #ifdef DIRLIGHT
  104. float GetDirShadowFade(float inLight, float depth)
  105. {
  106. return min(inLight + max((depth - cShadowDepthFade.z) * cShadowDepthFade.w, 0.0), 1.0);
  107. }
  108. #ifndef GL_ES
  109. float GetDirShadow(const vec4 iShadowPos[NUMCASCADES], float depth)
  110. {
  111. vec4 shadowPos;
  112. if (depth < cShadowSplits.x)
  113. shadowPos = iShadowPos[0];
  114. else if (depth < cShadowSplits.y)
  115. shadowPos = iShadowPos[1];
  116. else if (depth < cShadowSplits.z)
  117. shadowPos = iShadowPos[2];
  118. else
  119. shadowPos = iShadowPos[3];
  120. return GetDirShadowFade(GetShadow(shadowPos), depth);
  121. }
  122. float GetDirShadowDeferred(vec4 projWorldPos, float depth)
  123. {
  124. vec4 shadowPos;
  125. if (depth < cShadowSplits.x)
  126. shadowPos = cLightMatricesPS[0] * projWorldPos;
  127. else if (depth < cShadowSplits.y)
  128. shadowPos = cLightMatricesPS[1] * projWorldPos;
  129. else if (depth < cShadowSplits.z)
  130. shadowPos = cLightMatricesPS[2] * projWorldPos;
  131. else
  132. shadowPos = cLightMatricesPS[3] * projWorldPos;
  133. return GetDirShadowFade(GetShadow(shadowPos), depth);
  134. }
  135. #else
  136. float GetDirShadow(const vec4 iShadowPos[NUMCASCADES], float depth)
  137. {
  138. vec4 shadowPos;
  139. if (depth < cShadowSplits.x)
  140. shadowPos = iShadowPos[0];
  141. else
  142. shadowPos = iShadowPos[1];
  143. return GetDirShadowFade(GetShadow(shadowPos), depth);
  144. }
  145. #endif
  146. #endif
  147. float GetShadow(vec4 iShadowPos[NUMCASCADES], float depth)
  148. {
  149. #if defined(DIRLIGHT)
  150. return GetDirShadow(iShadowPos, depth);
  151. #elif defined(SPOTLIGHT)
  152. return GetShadow(iShadowPos[0]);
  153. #else
  154. return GetPointShadow(iShadowPos[0].xyz);
  155. #endif
  156. }
  157. #ifndef GL_ES
  158. float GetShadowDeferred(vec4 projWorldPos, float depth)
  159. {
  160. #if defined(DIRLIGHT)
  161. return GetDirShadowDeferred(projWorldPos, depth);
  162. #elif defined(SPOTLIGHT)
  163. vec4 shadowPos = cLightMatricesPS[1] * projWorldPos;
  164. return GetShadow(shadowPos);
  165. #else
  166. vec3 shadowPos = projWorldPos.xyz - cLightPosPS.xyz;
  167. return GetPointShadow(shadowPos);
  168. #endif
  169. }
  170. #endif
  171. #endif