Lighting.frag 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. float GetDiffuseDir(vec3 normal, vec3 lightDir)
  2. {
  3. return max(dot(normal, lightDir), 0.0);
  4. }
  5. float GetDiffuseDirVolumetric()
  6. {
  7. return 1.0;
  8. }
  9. #if defined(POINTLIGHT) || defined(SPOTLIGHT)
  10. float GetDiffusePointOrSpot(vec3 normal, vec3 lightVec, out vec3 lightDir)
  11. {
  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. }
  16. #endif
  17. #if defined(POINTLIGHT) || defined(SPOTLIGHT)
  18. float GetDiffusePointOrSpotVolumetric(vec3 lightVec)
  19. {
  20. float lightDist = length(lightVec);
  21. return texture2D(sLightRampMap, vec2(lightDist, 0.0)).r;
  22. }
  23. #endif
  24. float GetSpecular(vec3 normal, vec3 eyeVec, vec3 lightDir, float specularPower)
  25. {
  26. vec3 halfVec = normalize(normalize(eyeVec) + lightDir);
  27. return pow(max(dot(normal, halfVec), 0.0), specularPower);
  28. }
  29. float GetIntensity(vec3 color)
  30. {
  31. return dot(color, vec3(0.333));
  32. }
  33. #ifdef SHADOW
  34. float GetShadow(vec4 shadowPos)
  35. {
  36. // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
  37. #ifndef LQSHADOW
  38. // Take four samples and average them
  39. #ifndef POINTLIGHT
  40. vec2 offsets = cShadowMapInvSize * shadowPos.w;
  41. #else
  42. vec2 offsets = cShadowMapInvSize;
  43. #endif
  44. vec4 inLight = vec4(
  45. shadow2DProj(sShadowMap, shadowPos).r,
  46. shadow2DProj(sShadowMap, vec4(shadowPos.x + offsets.x, shadowPos.yzw)).r,
  47. shadow2DProj(sShadowMap, vec4(shadowPos.x, shadowPos.y + offsets.y, shadowPos.zw)).r,
  48. shadow2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r
  49. );
  50. return cShadowIntensity.y + dot(inLight, vec4(cShadowIntensity.x));
  51. #else
  52. // Take one sample
  53. float inLight = shadow2DProj(sShadowMap, shadowPos).r;
  54. return cShadowIntensity.y + cShadowIntensity.x * inLight;
  55. #endif
  56. }
  57. float GetShadowFade(float depth)
  58. {
  59. return clamp((depth - cShadowDepthFade.z) * cShadowDepthFade.w, 0.0, 1.0);
  60. }
  61. #ifdef POINTLIGHT
  62. float GetCubeShadow(vec3 lightVec)
  63. {
  64. vec3 axis = textureCube(sFaceSelectCubeMap, lightVec).rgb;
  65. float depth = abs(dot(lightVec, axis));
  66. // Expand the maximum component of the light vector to get full 0.0 - 1.0 UV range from the cube map,
  67. // and to avoid sampling across faces. Some GPU's filter across faces, while others do not, and in this
  68. // case filtering across faces is wrong
  69. const vec3 factor = vec3(1.0 / 256.0);
  70. lightVec += factor * axis * lightVec;
  71. // Read the 2D UV coordinates, adjust according to shadow map size and add face offset
  72. vec4 indirectPos = textureCube(sIndirectionCubeMap, lightVec);
  73. indirectPos.xy *= cShadowCubeAdjust.xy;
  74. indirectPos.xy += vec2(cShadowCubeAdjust.z + indirectPos.z * 0.5, cShadowCubeAdjust.w + indirectPos.w);
  75. vec4 shadowPos = vec4(indirectPos.xy, cShadowDepthFade.x + cShadowDepthFade.y / depth, 1.0);
  76. return GetShadow(shadowPos);
  77. }
  78. #endif
  79. #ifdef DIRLIGHT
  80. vec4 GetDirShadowPos(const vec4 shadowPos[4], float depth)
  81. {
  82. if (depth < cShadowSplits.x)
  83. return shadowPos[0];
  84. else if (depth < cShadowSplits.y)
  85. return shadowPos[1];
  86. else if (depth < cShadowSplits.z)
  87. return shadowPos[2];
  88. else
  89. return shadowPos[3];
  90. }
  91. vec4 GetDirShadowPosDeferred(const mat4 shadowMatrix[4], vec4 projWorldPos, float depth)
  92. {
  93. if (depth < cShadowSplits.x)
  94. return shadowMatrix[0] * projWorldPos;
  95. else if (depth < cShadowSplits.y)
  96. return shadowMatrix[1] * projWorldPos;
  97. else if (depth < cShadowSplits.z)
  98. return shadowMatrix[2] * projWorldPos;
  99. else
  100. return shadowMatrix[3] * projWorldPos;
  101. }
  102. #endif
  103. #endif