shadow.glslf 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. #ifndef SHADOW_GLSLF
  2. #define SHADOW_GLSLF
  3. // #import u_csm_center_dists u_pcf_blur_radii
  4. // #import u_shadow_map0 u_shadow_map1 u_shadow_map2 u_shadow_map3 u_shadow_mask
  5. // #import v_shadow_coord0 v_shadow_coord1 v_shadow_coord2 v_shadow_coord3 \
  6. // v_tex_pos_clip v_pos_view
  7. /*==============================================================================
  8. VARS
  9. ==============================================================================*/
  10. #var PRECISION highp
  11. #var SHADOW_TEX_RES 2048.0
  12. #var CSM_FADE_LAST_CASCADE 0
  13. #var CSM_BLEND_BETWEEN_CASCADES 0
  14. #var SHADOW_USAGE NO_SHADOWS
  15. #var NUM_CAST_LAMPS 0
  16. #var CSM_SECTION1 0
  17. #var CSM_SECTION2 0
  18. #var CSM_SECTION3 0
  19. #var COMPARED_MODE 0
  20. #var POISSON_DISK_NUM NO_SOFT_SHADOWS
  21. /*============================================================================*/
  22. #include <std.glsl>
  23. #if SHADOW_USAGE == SHADOW_MASK_GENERATION || SHADOW_USAGE == SHADOW_MAPPING_BLEND
  24. #include <procedural.glslf>
  25. #endif
  26. #if SHADOW_USAGE == SHADOW_MASK_GENERATION || SHADOW_USAGE == SHADOW_MAPPING_BLEND
  27. const float SHADOW_BLUR_OFFSET = 0.1;
  28. const float SHADOW_FADE_OFFSET = 0.1;
  29. const float SINGLE_CASCADE_BORDER_INDENT = -0.01;
  30. const float FIRST_CASCADE_BLUR_INDENT = 0.05;
  31. // Poisson disk
  32. // NOTE: use many vec4's to prevent firefox crash on mobile devices
  33. # if POISSON_DISK_NUM == POISSON_X_16
  34. vec4 POISSON_DISK_X_0 = vec4(0.14383161, 0.34495938, -0.38277543, -0.26496911);
  35. vec4 POISSON_DISK_X_1 = vec4(0.53742981, 0.19984126, 0.79197514, -0.094184101);
  36. vec4 POISSON_DISK_X_2 = vec4(-0.94201624, -0.91588581, -0.2418884, 0.44323325);
  37. vec4 POISSON_DISK_X_3 = vec4(-0.81544232, 0.94558609, -0.81409955, 0.97484398);
  38. vec4 POISSON_DISK_Y_0 = vec4(-0.1410079, 0.2938776, 0.27676845, -0.41893023);
  39. vec4 POISSON_DISK_Y_1 = vec4(-0.4737342, 0.78641367, 0.19090188, -0.9293887);
  40. vec4 POISSON_DISK_Y_2 = vec4(-0.39906216, 0.45771432, 0.99706507, -0.97511554);
  41. vec4 POISSON_DISK_Y_3 = vec4(-0.87912464, -0.76890725, 0.9143759, 0.7564837);
  42. # elif POISSON_DISK_NUM == POISSON_X_8
  43. vec2 POISSON_DISK_X_0 = vec2(-0.37192261, 0.47109537);
  44. vec2 POISSON_DISK_X_1 = vec2(-0.6807477, 0.69048062);
  45. vec2 POISSON_DISK_X_2 = vec2(0.11615683, -0.91318524);
  46. vec2 POISSON_DISK_X_3 = vec2(0.93688596, -0.16948928);
  47. vec2 POISSON_DISK_Y_0 = vec2(-0.89699117, 0.74092316);
  48. vec2 POISSON_DISK_Y_1 = vec2(0.38263656, -0.66119884);
  49. vec2 POISSON_DISK_Y_2 = vec2(-0.08193062, -0.21275223);
  50. vec2 POISSON_DISK_Y_3 = vec2(0.05578877, 0.84225623);
  51. # elif POISSON_DISK_NUM == POISSON_X_4
  52. vec2 POISSON_DISK_X_0 = vec2(-0.51808083, 0.0);
  53. vec2 POISSON_DISK_X_1 = vec2(0.5741194, 0.0);
  54. vec2 POISSON_DISK_X_2 = vec2(-0.68048857, 0.0);
  55. vec2 POISSON_DISK_X_3 = vec2(0.82934988, 0.0);
  56. vec2 POISSON_DISK_Y_0 = vec2(0.70009436, 0.0);
  57. vec2 POISSON_DISK_Y_1 = vec2(-0.78790467, 0.0);
  58. vec2 POISSON_DISK_Y_2 = vec2(-0.58619489, 0.0);
  59. vec2 POISSON_DISK_Y_3 = vec2(0.41902178, 0.0);
  60. # endif
  61. bool is_tex_coords_inside(vec2 coords, float indent) {
  62. return all(lessThanEqual(coords, vec2(1.0 + indent)))
  63. && all(greaterThanEqual(coords, vec2(0.0 - indent)));
  64. }
  65. float calc_poisson_visibility(float poisson_disc_x, float poisson_disc_y,
  66. mat2 rotation_mat, vec3 shadow_coord, float blur_radius,
  67. PRECISION GLSL_SMPLR2D_SHDW shadow_map) {
  68. # if POISSON_DISK_NUM != NO_SOFT_SHADOWS
  69. vec2 coords, offset;
  70. offset.x = poisson_disc_x;
  71. offset.y = poisson_disc_y;
  72. offset = rotation_mat * offset;
  73. coords = shadow_coord.xy + offset * blur_radius / SHADOW_TEX_RES;
  74. # else
  75. vec2 coords = shadow_coord.xy;
  76. # endif
  77. # if !CSM_SECTION1
  78. // NOTE: fix issue with solid black border at the edge of the last cascade
  79. // caused by FIRST_CASCADE_BLUR_INDENT for single cascade scheme
  80. if (!is_tex_coords_inside(coords, SINGLE_CASCADE_BORDER_INDENT))
  81. return 1.0;
  82. # endif
  83. #if COMPARED_MODE
  84. return GLSL_TEXTURE(shadow_map, vec3(coords, shadow_coord.z));
  85. #else
  86. return step(shadow_coord.z, GLSL_TEXTURE(shadow_map, coords).r);
  87. #endif
  88. }
  89. float shadow_map_visibility(vec3 shadow_coord, PRECISION GLSL_SMPLR2D_SHDW shadow_map,
  90. float blur_radius) {
  91. float visibility = 0.0;
  92. shadow_coord.z = clamp(shadow_coord.z, 0.0, 1.0);
  93. #if POISSON_DISK_NUM != NO_SOFT_SHADOWS
  94. // Poisson disk random rotation
  95. float rnd_val = generate_dithering_tex(shadow_coord.xy).x * M_PI;
  96. float rnd_cos = cos(rnd_val);
  97. float rnd_sin = sin(rnd_val);
  98. mat2 rotation_mat = mat2(rnd_cos, rnd_sin, -rnd_sin, rnd_cos);
  99. for (int i = 0; i < POISSON_DISK_NUM; i++) {
  100. visibility += calc_poisson_visibility(POISSON_DISK_X_0[i],
  101. POISSON_DISK_Y_0[i], rotation_mat, shadow_coord,
  102. blur_radius, shadow_map);
  103. visibility += calc_poisson_visibility(POISSON_DISK_X_1[i],
  104. POISSON_DISK_Y_1[i], rotation_mat, shadow_coord,
  105. blur_radius, shadow_map);
  106. visibility += calc_poisson_visibility(POISSON_DISK_X_2[i],
  107. POISSON_DISK_Y_2[i], rotation_mat, shadow_coord,
  108. blur_radius, shadow_map);
  109. visibility += calc_poisson_visibility(POISSON_DISK_X_3[i],
  110. POISSON_DISK_Y_3[i], rotation_mat, shadow_coord,
  111. blur_radius, shadow_map);
  112. }
  113. return clamp(visibility / (float(POISSON_DISK_NUM) * 4.0), 0.0, 1.0);
  114. #else
  115. return calc_poisson_visibility(0.0, 0.0, mat2(0.0), shadow_coord,
  116. blur_radius, shadow_map);
  117. #endif
  118. }
  119. float shadow_map_visibility_overlap(vec3 shadow_coord0, PRECISION GLSL_SMPLR2D_SHDW shadow_map0,
  120. vec3 shadow_coord1, PRECISION GLSL_SMPLR2D_SHDW shadow_map1, float blur_radius0,
  121. float blur_radius1, float factor) {
  122. float vis0, vis1;
  123. shadow_coord0.z = clamp(shadow_coord0.z, 0.0, 1.0);
  124. shadow_coord1.z = clamp(shadow_coord1.z, 0.0, 1.0);
  125. vis0 = 0.0; vis1 = 0.0;
  126. #if POISSON_DISK_NUM != NO_SOFT_SHADOWS
  127. // Poisson disk random rotation
  128. float rnd_val = generate_dithering_tex(shadow_coord0.xy).x * M_PI;
  129. float rnd_cos = cos(rnd_val);
  130. float rnd_sin = sin(rnd_val);
  131. mat2 rotation_mat = mat2(rnd_cos, rnd_sin, -rnd_sin, rnd_cos);
  132. // NOTE: use different loops for sampling different shadow maps to avoid
  133. // some issues on systems with free drivers (e.g. Arch)
  134. for (int i = 0; i < POISSON_DISK_NUM; i++) {
  135. vis0 += calc_poisson_visibility(POISSON_DISK_X_0[i],
  136. POISSON_DISK_Y_0[i], rotation_mat, shadow_coord0,
  137. blur_radius0, shadow_map0);
  138. vis0 += calc_poisson_visibility(POISSON_DISK_X_1[i],
  139. POISSON_DISK_Y_1[i], rotation_mat, shadow_coord0,
  140. blur_radius0, shadow_map0);
  141. vis0 += calc_poisson_visibility(POISSON_DISK_X_2[i],
  142. POISSON_DISK_Y_2[i], rotation_mat, shadow_coord0,
  143. blur_radius0, shadow_map0);
  144. vis0 += calc_poisson_visibility(POISSON_DISK_X_3[i],
  145. POISSON_DISK_Y_3[i], rotation_mat, shadow_coord0,
  146. blur_radius0, shadow_map0);
  147. }
  148. for (int i = 0; i < POISSON_DISK_NUM; i++) {
  149. vis1 += calc_poisson_visibility(POISSON_DISK_X_0[i],
  150. POISSON_DISK_Y_0[i], rotation_mat, shadow_coord1,
  151. blur_radius1, shadow_map1);
  152. vis1 += calc_poisson_visibility(POISSON_DISK_X_1[i],
  153. POISSON_DISK_Y_1[i], rotation_mat, shadow_coord1,
  154. blur_radius1, shadow_map1);
  155. vis1 += calc_poisson_visibility(POISSON_DISK_X_2[i],
  156. POISSON_DISK_Y_2[i], rotation_mat, shadow_coord1,
  157. blur_radius1, shadow_map1);
  158. vis1 += calc_poisson_visibility(POISSON_DISK_X_3[i],
  159. POISSON_DISK_Y_3[i], rotation_mat, shadow_coord1,
  160. blur_radius1, shadow_map1);
  161. }
  162. vis0 = mix(vis0, vis1, factor);
  163. vis0 /= (float(POISSON_DISK_NUM) * 4.0);
  164. #else
  165. vis0 += calc_poisson_visibility(0.0, 0.0, mat2(0.0), shadow_coord0,
  166. blur_radius0, shadow_map0);
  167. vis1 += calc_poisson_visibility(0.0, 0.0, mat2(0.0), shadow_coord1,
  168. blur_radius1, shadow_map1);
  169. vis0 = mix(vis0, vis1, factor);
  170. #endif
  171. return clamp(vis0, 0.0, 1.0);
  172. }
  173. float get_edge_distance_tex(vec2 coords) {
  174. float a = min(coords.x, coords.y);
  175. float b = min(1.0 - coords.x, 1.0 - coords.y);
  176. return min(a, b);
  177. }
  178. float fade_shadow(float vis, float edge_dist) {
  179. if (edge_dist >= 0.0 && edge_dist <= SHADOW_FADE_OFFSET)
  180. vis = (vis - 1.0) / SHADOW_FADE_OFFSET * edge_dist + 1.0;
  181. return vis;
  182. }
  183. float get_visibility_blended(vec3 tex_coords0, vec3 tex_coords1,
  184. PRECISION GLSL_SMPLR2D_SHDW shadow_map0, PRECISION GLSL_SMPLR2D_SHDW shadow_map1,
  185. float blur_radius0, float blur_radius1, float center_dist, float depth) {
  186. float vis;
  187. # if CSM_BLEND_BETWEEN_CASCADES
  188. float edge_dist = get_edge_distance_tex(tex_coords0.xy);
  189. if (-depth > center_dist && edge_dist >= 0.0
  190. && edge_dist <= SHADOW_BLUR_OFFSET
  191. && is_tex_coords_inside(tex_coords1.xy, 0.0)) {
  192. float blend_factor = 1.0 - edge_dist / SHADOW_BLUR_OFFSET;
  193. vis = shadow_map_visibility_overlap(tex_coords0,
  194. shadow_map0, tex_coords1, shadow_map1, blur_radius0,
  195. blur_radius1, blend_factor);
  196. } else
  197. # endif
  198. vis = shadow_map_visibility(tex_coords0, shadow_map0, blur_radius0);
  199. return vis;
  200. }
  201. float get_visibility_faded(vec3 tex_coords, PRECISION GLSL_SMPLR2D_SHDW shadow_map,
  202. float blur_radius, float center_dist, float depth) {
  203. float vis = shadow_map_visibility(tex_coords, shadow_map, blur_radius);
  204. # if CSM_FADE_LAST_CASCADE
  205. if (-depth > center_dist) {
  206. float edge_dist = get_edge_distance_tex(tex_coords.xy);
  207. vis = fade_shadow(vis, edge_dist);
  208. }
  209. # endif
  210. return vis;
  211. }
  212. vec4 shadow_visibility(float depth) {
  213. float vis = 1.0;
  214. # if POISSON_DISK_NUM != NO_SOFT_SHADOWS
  215. vec4 pcf_blur_radii = u_pcf_blur_radii;
  216. # else
  217. vec4 pcf_blur_radii = vec4(0.0);
  218. # endif
  219. // NOTE: possible division by zero
  220. vec3 shadow_coord0 = v_shadow_coord0.xyz / v_shadow_coord0.w;
  221. // fix for shadow maps from perspective camera (actually works for
  222. // all cameras): no shadows behind the camera
  223. if (v_shadow_coord0.w < 0.0)
  224. shadow_coord0.z = 0.0;
  225. # if CSM_SECTION1 || NUM_CAST_LAMPS > 1
  226. vec3 shadow_coord1 = v_shadow_coord1.xyz / v_shadow_coord1.w;
  227. if (v_shadow_coord1.w < 0.0)
  228. shadow_coord1.z = 0.0;
  229. # endif
  230. # if CSM_SECTION2 || NUM_CAST_LAMPS > 2
  231. vec3 shadow_coord2 = v_shadow_coord2.xyz / v_shadow_coord2.w;
  232. if (v_shadow_coord2.w < 0.0)
  233. shadow_coord2.z = 0.0;
  234. # endif
  235. # if CSM_SECTION3 || NUM_CAST_LAMPS > 3
  236. vec3 shadow_coord3 = v_shadow_coord3.xyz / v_shadow_coord3.w;
  237. if (v_shadow_coord3.w < 0.0)
  238. shadow_coord3.z = 0.0;
  239. # endif
  240. # if CSM_SECTION1
  241. if (is_tex_coords_inside(shadow_coord0.xy, 0.0)) {
  242. vis = get_visibility_blended(shadow_coord0, shadow_coord1,
  243. u_shadow_map0, u_shadow_map1, pcf_blur_radii[0],
  244. pcf_blur_radii[1], u_csm_center_dists[0], depth);
  245. }
  246. # else
  247. // NOTE: small indent for single cascade blur (especially for non-csm scheme)
  248. if (is_tex_coords_inside(shadow_coord0.xy, FIRST_CASCADE_BLUR_INDENT)) {
  249. vis = get_visibility_faded(shadow_coord0, u_shadow_map0,
  250. pcf_blur_radii[0], u_csm_center_dists[0], depth);
  251. }
  252. # endif
  253. # if CSM_SECTION1
  254. else {
  255. if (is_tex_coords_inside(shadow_coord1.xy, 0.0)) {
  256. # if CSM_SECTION2
  257. vis = get_visibility_blended(shadow_coord1, shadow_coord2,
  258. u_shadow_map1, u_shadow_map2, pcf_blur_radii[1],
  259. pcf_blur_radii[2], u_csm_center_dists[1], depth);
  260. # else
  261. vis = get_visibility_faded(shadow_coord1, u_shadow_map1,
  262. pcf_blur_radii[1], u_csm_center_dists[1], depth);
  263. # endif
  264. }
  265. # if CSM_SECTION2
  266. else {
  267. if (is_tex_coords_inside(shadow_coord2.xy, 0.0)) {
  268. # if CSM_SECTION3
  269. vis = get_visibility_blended(shadow_coord2, shadow_coord3,
  270. u_shadow_map2, u_shadow_map3, pcf_blur_radii[2],
  271. pcf_blur_radii[3], u_csm_center_dists[2], depth);
  272. # else
  273. vis = get_visibility_faded(shadow_coord2, u_shadow_map2,
  274. pcf_blur_radii[2], u_csm_center_dists[2], depth);
  275. # endif
  276. }
  277. # if CSM_SECTION3
  278. else {
  279. if (is_tex_coords_inside(shadow_coord3.xy, 0.0))
  280. vis = get_visibility_faded(shadow_coord3, u_shadow_map3,
  281. pcf_blur_radii[3], u_csm_center_dists[3], depth);
  282. }
  283. # endif // CSM_SECTION3
  284. }
  285. # endif // CSM_SECTION2
  286. }
  287. # endif // CSM_SECTION1
  288. # if NUM_CAST_LAMPS > 1
  289. float vis_lamp_1 = shadow_map_visibility(shadow_coord1, u_shadow_map1, pcf_blur_radii[0]);
  290. # else
  291. float vis_lamp_1 = 0.0;
  292. # endif
  293. # if NUM_CAST_LAMPS > 2
  294. float vis_lamp_2 = shadow_map_visibility(shadow_coord2, u_shadow_map2, pcf_blur_radii[0]);
  295. # else
  296. float vis_lamp_2 = 0.0;
  297. # endif
  298. # if NUM_CAST_LAMPS > 3
  299. float vis_lamp_3 = shadow_map_visibility(shadow_coord3, u_shadow_map3, pcf_blur_radii[0]);
  300. # else
  301. float vis_lamp_3 = 1.0;
  302. # endif
  303. return vec4(vis, vis_lamp_1, vis_lamp_2, vis_lamp_3);
  304. }
  305. #endif // SHADOW_USAGE == SHADOW_MASK_GENERATION || SHADOW_USAGE == SHADOW_MAPPING_BLEND
  306. vec4 calc_shadow_factor(inout vec3 D) {
  307. #if SHADOW_USAGE == SHADOW_MAPPING_OPAQUE
  308. // TODO:
  309. vec4 visibility = GLSL_TEXTURE(u_shadow_mask, v_tex_pos_clip.xy / v_tex_pos_clip.z);
  310. # if NUM_CAST_LAMPS < 3
  311. D *= visibility.a;
  312. # endif
  313. return visibility;
  314. #elif SHADOW_USAGE == SHADOW_MASK_GENERATION || SHADOW_USAGE == SHADOW_MAPPING_BLEND
  315. vec4 visibility = shadow_visibility(v_pos_view.z);
  316. return visibility;
  317. #else
  318. return vec4(1.0);
  319. #endif
  320. }
  321. #endif