PssmShadows.glsllib 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #ifdef HARDWARE_SHADOWS
  2. #define SHADOWMAP sampler2DShadow
  3. #define SHADOWCOMPARE(tex,coord) shadow2DProj(tex, coord).r
  4. #else
  5. #define SHADOWMAP sampler2D
  6. #define SHADOWCOMPARE(tex,coord) step(coord.z, texture2DProj(tex, coord).r)
  7. #endif
  8. #if FILTER_MODE == 0
  9. #define GETSHADOW Shadow_DoShadowCompare
  10. #define KERNEL 1.0
  11. #elif FILTER_MODE == 1
  12. #ifdef HARDWARE_SHADOWS
  13. #define GETSHADOW Shadow_DoShadowCompare
  14. #else
  15. #define GETSHADOW Shadow_DoBilinear_2x2
  16. #endif
  17. #define KERNEL 1.0
  18. #elif FILTER_MODE == 2
  19. #define GETSHADOW Shadow_DoDither_2x2
  20. #define KERNEL 1.0
  21. #elif FILTER_MODE == 3
  22. #define GETSHADOW Shadow_DoPCF
  23. #define KERNEL 4.0
  24. #elif FILTER_MODE == 4
  25. #define GETSHADOW Shadow_DoPCFPoisson
  26. #define KERNEL 4
  27. #elif FILTER_MODE == 5
  28. #define GETSHADOW Shadow_DoPCF
  29. #define KERNEL 8.0
  30. #endif
  31. uniform SHADOWMAP m_ShadowMap0;
  32. uniform SHADOWMAP m_ShadowMap1;
  33. uniform SHADOWMAP m_ShadowMap2;
  34. uniform SHADOWMAP m_ShadowMap3;
  35. uniform vec4 m_Splits;
  36. uniform float m_ShadowIntensity;
  37. const vec2 pixSize2 = vec2(1.0 / SHADOWMAP_SIZE);
  38. float shadowBorderScale = 1.0;
  39. float Shadow_DoShadowCompareOffset(in SHADOWMAP tex, in vec4 projCoord, in vec2 offset){
  40. vec4 coord = vec4(projCoord.xy + offset.xy * pixSize2 * shadowBorderScale, projCoord.zw);
  41. return SHADOWCOMPARE(tex, coord);
  42. }
  43. float Shadow_DoShadowCompare(in SHADOWMAP tex, vec4 projCoord){
  44. return SHADOWCOMPARE(tex, projCoord);
  45. }
  46. float Shadow_BorderCheck(in vec2 coord){
  47. // Fastest, "hack" method (uses 4-5 instructions)
  48. vec4 t = vec4(coord.xy, 0.0, 1.0);
  49. t = step(t.wwxy, t.xyzz);
  50. return dot(t,t);
  51. }
  52. float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
  53. float border = Shadow_BorderCheck(projCoord.xy);
  54. if (border > 0.0)
  55. return 1.0;
  56. float shadow = 0.0;
  57. vec2 o = mod(floor(gl_FragCoord.xy), 2.0);
  58. shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, 1.5) + o);
  59. shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, 1.5) + o);
  60. shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, -0.5) + o);
  61. shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, -0.5) + o);
  62. shadow *= 0.25 ;
  63. return shadow;
  64. }
  65. float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
  66. float border = Shadow_BorderCheck(projCoord.xy);
  67. if (border > 0.0)
  68. return 1.0;
  69. vec4 gather = vec4(0.0);
  70. gather.x = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 0.0));
  71. gather.y = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 0.0));
  72. gather.z = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 1.0));
  73. gather.w = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 1.0));
  74. vec2 f = fract( projCoord.xy * SHADOWMAP_SIZE );
  75. vec2 mx = mix( gather.xz, gather.yw, f.x );
  76. return mix( mx.x, mx.y, f.y );
  77. }
  78. float Shadow_DoPCF(in SHADOWMAP tex, in vec4 projCoord){
  79. float shadow = 0.0;
  80. float border = Shadow_BorderCheck(projCoord.xy);
  81. if (border > 0.0)
  82. return 1.0;
  83. float bound = KERNEL * 0.5 - 0.5;
  84. bound *= PCFEDGE;
  85. for (float y = -bound; y <= bound; y += PCFEDGE){
  86. for (float x = -bound; x <= bound; x += PCFEDGE){
  87. shadow += clamp(Shadow_DoShadowCompareOffset(tex,projCoord,vec2(x,y)) +
  88. border,
  89. 0.0, 1.0);
  90. }
  91. }
  92. shadow = shadow / (KERNEL * KERNEL);
  93. return shadow;
  94. }
  95. //12 tap poisson disk
  96. const vec2 poissonDisk0 = vec2(-0.1711046, -0.425016);
  97. const vec2 poissonDisk1 = vec2(-0.7829809, 0.2162201);
  98. const vec2 poissonDisk2 = vec2(-0.2380269, -0.8835521);
  99. const vec2 poissonDisk3 = vec2(0.4198045, 0.1687819);
  100. const vec2 poissonDisk4 = vec2(-0.684418, -0.3186957);
  101. const vec2 poissonDisk5 = vec2(0.6026866, -0.2587841);
  102. const vec2 poissonDisk6 = vec2(-0.2412762, 0.3913516);
  103. const vec2 poissonDisk7 = vec2(0.4720655, -0.7664126);
  104. const vec2 poissonDisk8 = vec2(0.9571564, 0.2680693);
  105. const vec2 poissonDisk9 = vec2(-0.5238616, 0.802707);
  106. const vec2 poissonDisk10 = vec2(0.5653144, 0.60262);
  107. const vec2 poissonDisk11 = vec2(0.0123658, 0.8627419);
  108. float Shadow_DoPCFPoisson(in SHADOWMAP tex, in vec4 projCoord){
  109. float shadow = 0.0;
  110. float border = Shadow_BorderCheck(projCoord.xy);
  111. if (border > 0.0)
  112. return 1.0;
  113. vec2 texelSize = vec2( 4.0 * PCFEDGE * shadowBorderScale);
  114. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk0 * texelSize);
  115. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk1 * texelSize);
  116. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk2 * texelSize);
  117. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk3 * texelSize);
  118. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk4 * texelSize);
  119. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk5 * texelSize);
  120. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk6 * texelSize);
  121. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk7 * texelSize);
  122. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk8 * texelSize);
  123. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk9 * texelSize);
  124. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk10 * texelSize);
  125. shadow += Shadow_DoShadowCompareOffset(tex, projCoord , poissonDisk11 * texelSize);
  126. shadow = shadow * 0.08333333333;//this is divided by 12
  127. return shadow;
  128. }