SpotShadow.hx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package h3d.shader;
  2. class SpotShadow extends hxsl.Shader {
  3. static var SRC = {
  4. @const var enable : Bool;
  5. // ESM
  6. @const var USE_ESM : Bool;
  7. @param var shadowPower : Float;
  8. // PCF
  9. @const var USE_PCF : Bool;
  10. @const var pcfQuality : Int;
  11. @param var pcfScale : Float;
  12. @param var shadowRes : Vec2;
  13. @param var shadowMap : Channel;
  14. @param var shadowProj : Mat4;
  15. @param var shadowBias : Float;
  16. var transformedPosition : Vec3;
  17. var shadow : Float;
  18. @param var poissonDiskLow : Array<Vec4,4>;
  19. @param var poissonDiskHigh : Array<Vec4,12>;
  20. @param var poissonDiskVeryHigh : Array<Vec4,64>;
  21. function rand( v : Float ) : Float {
  22. var dp = dot(vec4(v), vec4(12.9898,78.233,45.164,94.673));
  23. return fract(sin(dp) * 43758.5453);
  24. }
  25. function fragment() {
  26. if( enable ) {
  27. if( USE_PCF ) {
  28. shadow = 1.0;
  29. var texelSize = 1.0/shadowRes;
  30. var shadowPos = vec4(transformedPosition, 1.0) * shadowProj;
  31. shadowPos.xyz = shadowPos.xyz / shadowPos.w;
  32. var shadowUv = screenToUv(shadowPos.xy);
  33. var zMax = shadowPos.z;
  34. var rot = rand(transformedPosition.x + transformedPosition.y + transformedPosition.z) * 3.14 * 2;
  35. switch( pcfQuality ) {
  36. case 1:
  37. var sampleStrength = 1.0 / 4.0;
  38. for( i in 0 ... 4 ) {
  39. var offset = poissonDiskLow[i].xy * texelSize * pcfScale;
  40. offset = vec2(cos(rot) * offset.x - sin(rot) * offset.y, cos(rot) * offset.y + sin(rot) * offset.x);
  41. var depth = shadowMap.getLod(shadowUv + offset, 0);
  42. if( zMax - shadowBias > depth )
  43. shadow -= sampleStrength;
  44. }
  45. case 2:
  46. var sampleStrength = 1.0 / 12.0;
  47. for( i in 0 ... 12 ) {
  48. var offset = poissonDiskHigh[i].xy * texelSize * pcfScale;
  49. offset = vec2(cos(rot) * offset.x - sin(rot) * offset.y, cos(rot) * offset.y + sin(rot) * offset.x);
  50. var depth = shadowMap.getLod(shadowUv + offset, 0);
  51. if( zMax - shadowBias > depth )
  52. shadow -= sampleStrength;
  53. }
  54. case 3:
  55. var sampleStrength = 1.0 / 64.0;
  56. for( i in 0 ... 64 ) {
  57. var offset = poissonDiskHigh[i].xy * texelSize * pcfScale;
  58. offset = vec2(cos(rot) * offset.x - sin(rot) * offset.y, cos(rot) * offset.y + sin(rot) * offset.x);
  59. var depth = shadowMap.getLod(shadowUv + offset, 0);
  60. if( zMax - shadowBias > depth )
  61. shadow -= sampleStrength;
  62. }
  63. }
  64. }
  65. else if ( USE_ESM) {
  66. var shadowPos = vec4(transformedPosition, 1.0) * shadowProj;
  67. var shadowScreenPos = shadowPos.xyz / shadowPos.w;
  68. var depth = shadowMap.get(screenToUv(shadowScreenPos.xy));
  69. var zMax = shadowScreenPos.z.saturate();
  70. var delta = (depth + shadowBias).min(zMax) - zMax;
  71. shadow = exp(shadowPower * delta).saturate();
  72. }
  73. else {
  74. var shadowPos = vec4(transformedPosition, 1.0) * shadowProj;
  75. shadowPos.xyz = shadowPos.xyz / shadowPos.w;
  76. var shadowUv = screenToUv(shadowPos.xy);
  77. var depth = shadowMap.get(shadowUv.xy);
  78. shadow = shadowPos.z - shadowBias > depth ? 0 : 1;
  79. }
  80. }
  81. }
  82. }
  83. public function new() {
  84. super();
  85. poissonDiskLow = [ new h3d.Vector4(-0.942,-0.399 ),
  86. new h3d.Vector4( 0.945,-0.768 ),
  87. new h3d.Vector4(-0.094,-0.929 ),
  88. new h3d.Vector4( 0.344, 0.293 ) ];
  89. poissonDiskHigh = [ new h3d.Vector4(-0.326,-0.406),
  90. new h3d.Vector4(-0.840,-0.074),
  91. new h3d.Vector4(-0.696, 0.457),
  92. new h3d.Vector4(-0.203, 0.621),
  93. new h3d.Vector4( 0.962,-0.195),
  94. new h3d.Vector4( 0.473,-0.480),
  95. new h3d.Vector4( 0.519, 0.767),
  96. new h3d.Vector4( 0.185,-0.893),
  97. new h3d.Vector4( 0.507, 0.064),
  98. new h3d.Vector4( 0.896, 0.412),
  99. new h3d.Vector4(-0.322,-0.933),
  100. new h3d.Vector4(-0.792,-0.598) ];
  101. poissonDiskVeryHigh = [ new h3d.Vector4(-0.613392, 0.617481),
  102. new h3d.Vector4(0.170019, -0.040254),
  103. new h3d.Vector4(-0.299417, 0.791925),
  104. new h3d.Vector4(0.645680, 0.493210),
  105. new h3d.Vector4(-0.651784, 0.717887),
  106. new h3d.Vector4(0.421003, 0.027070),
  107. new h3d.Vector4(-0.817194, -0.271096),
  108. new h3d.Vector4(-0.705374, -0.668203),
  109. new h3d.Vector4(0.977050, -0.108615),
  110. new h3d.Vector4(0.063326, 0.142369),
  111. new h3d.Vector4(0.203528, 0.214331),
  112. new h3d.Vector4(-0.667531, 0.326090),
  113. new h3d.Vector4(-0.098422, -0.295755),
  114. new h3d.Vector4(-0.885922, 0.215369),
  115. new h3d.Vector4(0.566637, 0.605213),
  116. new h3d.Vector4(0.039766, -0.396100),
  117. new h3d.Vector4(0.751946, 0.453352),
  118. new h3d.Vector4(0.078707, -0.715323),
  119. new h3d.Vector4(-0.075838, -0.529344),
  120. new h3d.Vector4(0.724479, -0.580798),
  121. new h3d.Vector4(0.222999, -0.215125),
  122. new h3d.Vector4(-0.467574, -0.405438),
  123. new h3d.Vector4(-0.248268, -0.814753),
  124. new h3d.Vector4(0.354411, -0.887570),
  125. new h3d.Vector4(0.175817, 0.382366),
  126. new h3d.Vector4(0.487472, -0.063082),
  127. new h3d.Vector4(-0.084078, 0.898312),
  128. new h3d.Vector4(0.488876, -0.783441),
  129. new h3d.Vector4(0.470016, 0.217933),
  130. new h3d.Vector4(-0.696890, -0.549791),
  131. new h3d.Vector4(-0.149693, 0.605762),
  132. new h3d.Vector4(0.034211, 0.979980),
  133. new h3d.Vector4(0.503098, -0.308878),
  134. new h3d.Vector4(-0.016205, -0.872921),
  135. new h3d.Vector4(0.385784, -0.393902),
  136. new h3d.Vector4(-0.146886, -0.859249),
  137. new h3d.Vector4(0.643361, 0.164098),
  138. new h3d.Vector4(0.634388, -0.049471),
  139. new h3d.Vector4(-0.688894, 0.007843),
  140. new h3d.Vector4(0.464034, -0.188818),
  141. new h3d.Vector4(-0.440840, 0.137486),
  142. new h3d.Vector4(0.364483, 0.511704),
  143. new h3d.Vector4(0.034028, 0.325968),
  144. new h3d.Vector4(0.099094, -0.308023),
  145. new h3d.Vector4(0.693960, -0.366253),
  146. new h3d.Vector4(0.678884, -0.204688),
  147. new h3d.Vector4(0.001801, 0.780328),
  148. new h3d.Vector4(0.145177, -0.898984),
  149. new h3d.Vector4(0.062655, -0.611866),
  150. new h3d.Vector4(0.315226, -0.604297),
  151. new h3d.Vector4(-0.780145, 0.486251),
  152. new h3d.Vector4(-0.371868, 0.882138),
  153. new h3d.Vector4(0.200476, 0.494430),
  154. new h3d.Vector4(-0.494552, -0.711051),
  155. new h3d.Vector4(0.612476, 0.705252),
  156. new h3d.Vector4(-0.578845, -0.768792),
  157. new h3d.Vector4(-0.772454, -0.090976),
  158. new h3d.Vector4(0.504440, 0.372295),
  159. new h3d.Vector4(0.155736, 0.065157),
  160. new h3d.Vector4(0.391522, 0.849605),
  161. new h3d.Vector4(-0.620106, -0.328104),
  162. new h3d.Vector4(0.789239, -0.419965),
  163. new h3d.Vector4(-0.545396, 0.538133),
  164. new h3d.Vector4(-0.178564, -0.596057) ];
  165. }
  166. }