shadow-map.chunk 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. // used for replacing cc-shadow-map-base.chunk
  2. #include <builtin/uniforms/cc-shadow>
  3. #if CC_SUPPORT_CASCADED_SHADOW_MAP
  4. #include <builtin/uniforms/cc-csm>
  5. #endif
  6. #include <common/common-define>
  7. #include <common/math/coordinates>
  8. #pragma define SHADOWMAP_FORMAT_RGBA8 1
  9. #pragma define SHADOWMAP_FORMAT_FLOAT 0
  10. #pragma define CC_DIR_LIGHT_SHADOW_NONE 0
  11. #pragma define CC_DIR_LIGHT_SHADOW_UNIFORM 1
  12. #pragma define CC_DIR_LIGHT_SHADOW_CASCADED 2
  13. #pragma define CC_DIR_LIGHT_SHADOW_VARIANCE 3
  14. #pragma define CC_SHADOW_NONE 0
  15. #pragma define CC_SHADOW_PLANAR 1
  16. #pragma define CC_SHADOW_MAP 2
  17. float CCGetLinearDepth(vec3 worldPos, float viewSpaceBias) {
  18. vec4 viewPos = cc_matLightView * vec4(worldPos.xyz, 1.0);
  19. viewPos.z += viewSpaceBias;
  20. return GetLinearDepthFromViewSpace(viewPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);
  21. }
  22. float CCGetLinearDepth(vec3 worldPos) {
  23. return CCGetLinearDepth(worldPos, 0.0);
  24. }
  25. #if CC_RECEIVE_SHADOW
  26. #include <builtin/uniforms/cc-global>
  27. #include <builtin/uniforms/cc-shadow-map>
  28. #include <common/data/packing>
  29. #include <common/shadow/native-pcf>
  30. //////////////////////////////////////////////////////////Helper Functions
  31. bool GetShadowNDCPos(out vec3 shadowNDCPos, vec4 shadowPosWithDepthBias)
  32. {
  33. shadowNDCPos = shadowPosWithDepthBias.xyz / shadowPosWithDepthBias.w * 0.5 + 0.5;
  34. if (shadowNDCPos.x < 0.0 || shadowNDCPos.x > 1.0 ||
  35. shadowNDCPos.y < 0.0 || shadowNDCPos.y > 1.0 ||
  36. shadowNDCPos.z < 0.0 || shadowNDCPos.z > 1.0) {
  37. return false;
  38. }
  39. CC_HANDLE_NDC_SAMPLE_FLIP(shadowNDCPos.xy, cc_cameraPos.w);
  40. return true;
  41. }
  42. vec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, vec3 matViewDir0, vec3 matViewDir1, vec3 matViewDir2, vec2 projScaleXY)
  43. {
  44. vec4 newShadowPos = shadowPos;
  45. if (normalBias > EPSILON_LOWP)
  46. {
  47. vec3 viewNormal = vec3(dot(matViewDir0, worldNormal), dot(matViewDir1, worldNormal), dot(matViewDir2, worldNormal));
  48. if (viewNormal.z < 0.1)
  49. newShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);
  50. }
  51. return newShadowPos;
  52. }
  53. vec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, mat4 matLightView, vec2 projScaleXY)
  54. {
  55. vec4 newShadowPos = shadowPos;
  56. if (normalBias > EPSILON_LOWP)
  57. {
  58. vec4 viewNormal = matLightView * vec4(worldNormal, 0.0);
  59. if (viewNormal.z < 0.1)
  60. newShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);
  61. }
  62. return newShadowPos;
  63. }
  64. float GetViewSpaceDepthFromNDCDepth_Orthgraphic(float NDCDepth, float projScaleZ, float projBiasZ)
  65. {
  66. return (NDCDepth - projBiasZ) / projScaleZ;
  67. }
  68. float GetViewSpaceDepthFromNDCDepth_Perspective(float NDCDepth, float homogenousDividW, float invProjScaleZ, float invProjBiasZ)
  69. {
  70. return NDCDepth * invProjScaleZ + homogenousDividW * invProjBiasZ;
  71. }
  72. vec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)
  73. {
  74. // Recover the coord in view space: cc_matLightInvProj * shadowPos
  75. vec3 viewSpacePos;
  76. viewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;
  77. viewSpacePos.z = GetViewSpaceDepthFromNDCDepth_Perspective(shadowPos.z, shadowPos.w, cc_shadowInvProjDepthInfo.x, cc_shadowInvProjDepthInfo.y);
  78. // Apply bias
  79. viewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;
  80. // Reconstuct clipspace: cc_matLightProj * viewSpacePos
  81. vec4 clipSpacePos;
  82. clipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;
  83. clipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);
  84. // enabled linear depth?
  85. #if CC_SHADOWMAP_USE_LINEAR_DEPTH
  86. clipSpacePos.z = GetLinearDepthFromViewSpace(viewSpacePos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);
  87. clipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;
  88. #endif
  89. return clipSpacePos;
  90. }
  91. // (projScaleZ, projBiasZ) = cc_shadowProjDepthInfo.xy
  92. vec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias, float projScaleZ, float projBiasZ)
  93. {
  94. float coeffA = projScaleZ;
  95. float coeffB = projBiasZ;
  96. // Recover the Z distance in view space:
  97. float viewSpacePos_z = GetViewSpaceDepthFromNDCDepth_Orthgraphic(shadowPos.z, projScaleZ, projBiasZ);
  98. // Apply bias
  99. viewSpacePos_z += viewspaceDepthBias;
  100. // Reconstuct clipspace
  101. vec4 result = shadowPos;
  102. result.z = viewSpacePos_z * coeffA + coeffB;
  103. return result;
  104. }
  105. vec4 ApplyShadowDepthBias_PerspectiveLinearDepth(vec4 shadowPos, float viewspaceDepthBias, vec3 worldPos)
  106. {
  107. // reverse operation for GetShadowNDCPos
  108. shadowPos.z = CCGetLinearDepth(worldPos, viewspaceDepthBias) * 2.0 - 1.0;
  109. shadowPos.z *= shadowPos.w;
  110. return shadowPos;
  111. }
  112. //////////////////////////////////////////////////////////Directional Light Shadow
  113. float CCGetDirLightShadowFactorHard (vec4 shadowPosWithDepthBias) {
  114. vec3 shadowNDCPos;
  115. if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {
  116. return 1.0;
  117. }
  118. return NativePCFShadowFactorHard(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);
  119. }
  120. float CCGetDirLightShadowFactorSoft (vec4 shadowPosWithDepthBias) {
  121. vec3 shadowNDCPos;
  122. if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {
  123. return 1.0;
  124. }
  125. return NativePCFShadowFactorSoft(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);
  126. }
  127. float CCGetDirLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias) {
  128. vec3 shadowNDCPos;
  129. if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {
  130. return 1.0;
  131. }
  132. return NativePCFShadowFactorSoft3X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);
  133. }
  134. float CCGetDirLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias) {
  135. vec3 shadowNDCPos;
  136. if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {
  137. return 1.0;
  138. }
  139. return NativePCFShadowFactorSoft5X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);
  140. }
  141. //////////////////////////////////////////////////////////Spot Light Shadow
  142. float CCGetSpotLightShadowFactorHard (vec4 shadowPosWithDepthBias, vec3 worldPos) {
  143. vec3 shadowNDCPos;
  144. if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {
  145. return 1.0;
  146. }
  147. return NativePCFShadowFactorHard(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);
  148. }
  149. float CCGetSpotLightShadowFactorSoft (vec4 shadowPosWithDepthBias, vec3 worldPos) {
  150. vec3 shadowNDCPos;
  151. if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {
  152. return 1.0;
  153. }
  154. return NativePCFShadowFactorSoft(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);
  155. }
  156. float CCGetSpotLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias, vec3 worldPos) {
  157. vec3 shadowNDCPos;
  158. if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {
  159. return 1.0;
  160. }
  161. return NativePCFShadowFactorSoft3X(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);
  162. }
  163. float CCGetSpotLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias, vec3 worldPos) {
  164. vec3 shadowNDCPos;
  165. if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {
  166. return 1.0;
  167. }
  168. return NativePCFShadowFactorSoft5X(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);
  169. }
  170. //////////////////////////////////////////////////////////Main Functions
  171. float CCSpotShadowFactorBase(out vec4 shadowPosWithDepthBias, vec4 shadowPos, vec3 worldPos, vec2 shadowBias)
  172. {
  173. float pcf = cc_shadowWHPBInfo.z;
  174. vec4 pos = vec4(1.0);
  175. #if CC_SHADOWMAP_USE_LINEAR_DEPTH
  176. pos = ApplyShadowDepthBias_PerspectiveLinearDepth(shadowPos, shadowBias.x, worldPos);
  177. #else
  178. pos = ApplyShadowDepthBias_Perspective(shadowPos, shadowBias.x);
  179. #endif
  180. float realtimeShadow = 1.0;
  181. if (pcf > 2.9) {
  182. realtimeShadow = CCGetSpotLightShadowFactorSoft5X(pos, worldPos);
  183. }else if (pcf > 1.9) {
  184. realtimeShadow = CCGetSpotLightShadowFactorSoft3X(pos, worldPos);
  185. }else if (pcf > 0.9) {
  186. realtimeShadow = CCGetSpotLightShadowFactorSoft(pos, worldPos);
  187. }else {
  188. realtimeShadow = CCGetSpotLightShadowFactorHard(pos, worldPos);
  189. }
  190. shadowPosWithDepthBias = pos;
  191. return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);
  192. }
  193. float CCShadowFactorBase(out vec4 shadowPosWithDepthBias, vec4 shadowPos, vec3 N, vec2 shadowBias)
  194. {
  195. vec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y, cc_matLightView, cc_shadowProjInfo.xy);
  196. pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y);
  197. float realtimeShadow = 1.0;
  198. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_5X
  199. realtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);
  200. #endif
  201. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_3X
  202. realtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);
  203. #endif
  204. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT
  205. realtimeShadow = CCGetDirLightShadowFactorSoft(pos);
  206. #endif
  207. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_HARD
  208. realtimeShadow = CCGetDirLightShadowFactorHard(pos);
  209. #endif
  210. shadowPosWithDepthBias = pos;
  211. return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);
  212. }
  213. #if CC_SUPPORT_CASCADED_SHADOW_MAP
  214. bool CCGetCSMLevelWithTransition(out highp float ratio, vec3 clipPos) {
  215. highp float maxRange = 1.0 - cc_csmSplitsInfo.x;
  216. highp float minRange = cc_csmSplitsInfo.x;
  217. highp float thresholdInvert = 1.0 / cc_csmSplitsInfo.x;
  218. ratio = 0.0;
  219. if (clipPos.x <= minRange) {
  220. ratio = clipPos.x * thresholdInvert;
  221. return true;
  222. }
  223. if (clipPos.x >= maxRange) {
  224. ratio = 1.0 - (clipPos.x - maxRange) * thresholdInvert;
  225. return true;
  226. }
  227. if (clipPos.y <= minRange) {
  228. ratio = clipPos.y * thresholdInvert;
  229. return true;
  230. }
  231. if (clipPos.y >= maxRange) {
  232. ratio = 1.0 - (clipPos.y - maxRange) * thresholdInvert;
  233. return true;
  234. }
  235. return false;
  236. }
  237. bool CCHasCSMLevel(int level, vec3 worldPos) {
  238. highp float layerThreshold = cc_csmViewDir0[0].w;
  239. bool hasLevel = false;
  240. for (int i = 0; i < NUMCASCADES; i++) {
  241. if (i == level) {
  242. vec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);
  243. vec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;
  244. if (clipPos.x >= layerThreshold && clipPos.x <= (1.0 - layerThreshold) &&
  245. clipPos.y >= layerThreshold && clipPos.y <= (1.0 - layerThreshold) &&
  246. clipPos.z >= 0.0 && clipPos.z <= 1.0) {
  247. hasLevel = true;
  248. }
  249. }
  250. }
  251. return hasLevel;
  252. }
  253. void CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos, int level) {
  254. highp float layerThreshold = cc_csmViewDir0[0].w;
  255. for (int i = 0; i < NUMCASCADES; i++) {
  256. vec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);
  257. vec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;
  258. if (clipPos.x >= layerThreshold && clipPos.x <= (1.0 - layerThreshold) &&
  259. clipPos.y >= layerThreshold && clipPos.y <= (1.0 - layerThreshold) &&
  260. clipPos.z >= 0.0 && clipPos.z <= 1.0 && i == level) {
  261. csmPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);
  262. csmPos.xy = csmPos.xy * cc_csmAtlas[i].xy + cc_csmAtlas[i].zw;
  263. shadowProjDepthInfo = cc_csmProjDepthInfo[i];
  264. shadowProjInfo = cc_csmProjInfo[i];
  265. shadowViewDir0 = cc_csmViewDir0[i].xyz;
  266. shadowViewDir1 = cc_csmViewDir1[i].xyz;
  267. shadowViewDir2 = cc_csmViewDir2[i].xyz;
  268. }
  269. }
  270. }
  271. int CCGetCSMLevel(out bool isTransitionArea, out highp float transitionRatio, out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos)
  272. {
  273. int level = -1;
  274. highp float layerThreshold = cc_csmViewDir0[0].w;
  275. for (int i = 0; i < NUMCASCADES; i++) {
  276. vec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);
  277. vec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;
  278. if (clipPos.x >= layerThreshold && clipPos.x <= (1.0 - layerThreshold) &&
  279. clipPos.y >= layerThreshold && clipPos.y <= (1.0 - layerThreshold) &&
  280. clipPos.z >= 0.0 && clipPos.z <= 1.0 && level < 0) {
  281. #if CC_CASCADED_LAYERS_TRANSITION
  282. isTransitionArea = CCGetCSMLevelWithTransition(transitionRatio, clipPos);
  283. #endif
  284. csmPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);
  285. csmPos.xy = csmPos.xy * cc_csmAtlas[i].xy + cc_csmAtlas[i].zw;
  286. shadowProjDepthInfo = cc_csmProjDepthInfo[i];
  287. shadowProjInfo = cc_csmProjInfo[i];
  288. shadowViewDir0 = cc_csmViewDir0[i].xyz;
  289. shadowViewDir1 = cc_csmViewDir1[i].xyz;
  290. shadowViewDir2 = cc_csmViewDir2[i].xyz;
  291. level = i;
  292. }
  293. }
  294. return level;
  295. }
  296. int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos)
  297. {
  298. bool isTransitionArea = false;
  299. highp float transitionRatio = 0.0;
  300. return CCGetCSMLevel(isTransitionArea, transitionRatio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos);
  301. }
  302. // output csmPos is non-biased position that can be used for sampling shadow map after homogeneous divid
  303. float CCCSMFactorBase(out vec4 csmPos, out vec4 csmPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias)
  304. {
  305. bool isTransitionArea = false;
  306. highp float ratio = 0.0;
  307. csmPos = vec4(1.0);
  308. vec4 shadowProjDepthInfo, shadowProjInfo;
  309. vec3 shadowViewDir0, shadowViewDir1, shadowViewDir2;
  310. int level = -1;
  311. #if CC_CASCADED_LAYERS_TRANSITION
  312. level = CCGetCSMLevel(isTransitionArea, ratio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos);
  313. #else
  314. level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos);
  315. #endif
  316. if (level < 0) { return 1.0; }
  317. vec4 pos = ApplyShadowDepthBias_FaceNormal(csmPos, N, shadowBias.y, shadowViewDir0, shadowViewDir1, shadowViewDir2, shadowProjInfo.xy);
  318. pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, shadowProjDepthInfo.x, shadowProjDepthInfo.y);
  319. csmPosWithBias = pos;
  320. float realtimeShadow = 1.0;
  321. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_5X
  322. realtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);
  323. #endif
  324. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_3X
  325. realtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);
  326. #endif
  327. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT
  328. realtimeShadow = CCGetDirLightShadowFactorSoft(pos);
  329. #endif
  330. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_HARD
  331. realtimeShadow = CCGetDirLightShadowFactorHard(pos);
  332. #endif
  333. #if CC_CASCADED_LAYERS_TRANSITION
  334. vec4 nextCSMPos = vec4(1.0);
  335. vec4 nextShadowProjDepthInfo, nextShadowProjInfo;
  336. vec3 nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2;
  337. float nextRealtimeShadow = 1.0;
  338. CCGetCSMLevel(nextCSMPos, nextShadowProjDepthInfo, nextShadowProjInfo, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, worldPos, level + 1);
  339. bool hasNextLevel = CCHasCSMLevel(level + 1, worldPos);
  340. if (hasNextLevel && isTransitionArea) {
  341. vec4 nexPos = ApplyShadowDepthBias_FaceNormal(nextCSMPos, N, shadowBias.y, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, nextShadowProjInfo.xy);
  342. nexPos = ApplyShadowDepthBias_Orthographic(nexPos, shadowBias.x, nextShadowProjDepthInfo.x, nextShadowProjDepthInfo.y);
  343. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_5X
  344. nextRealtimeShadow = CCGetDirLightShadowFactorSoft5X(nexPos);
  345. #endif
  346. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT_3X
  347. nextRealtimeShadow = CCGetDirLightShadowFactorSoft3X(nexPos);
  348. #endif
  349. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_SOFT
  350. nextRealtimeShadow = CCGetDirLightShadowFactorSoft(nexPos);
  351. #endif
  352. #if CC_DIR_SHADOW_PCF_TYPE == CC_SHADOW_PCF_HARD
  353. nextRealtimeShadow = CCGetDirLightShadowFactorHard(nexPos);
  354. #endif
  355. return mix(mix(nextRealtimeShadow, realtimeShadow, ratio), 1.0, cc_shadowNFLSInfo.w);
  356. }
  357. return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);
  358. #else
  359. return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);
  360. #endif
  361. }
  362. #else
  363. int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos) {
  364. return -1;
  365. }
  366. float CCCSMFactorBase(out vec4 csmPos, out vec4 csmPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias) {
  367. csmPos = cc_matLightViewProj * vec4(worldPos, 1.0);
  368. return CCShadowFactorBase(csmPosWithBias, csmPos, N, shadowBias);
  369. }
  370. #endif
  371. // compatible version
  372. float CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias) {
  373. vec4 shadowPosWithDepthBias;
  374. return CCShadowFactorBase(shadowPosWithDepthBias, shadowPos, N, shadowBias);
  375. }
  376. float CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias) {
  377. vec4 csmPos, csmPosWithBias;
  378. return CCCSMFactorBase(csmPos, csmPosWithBias, worldPos, N, shadowBias);
  379. }
  380. float CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)
  381. {
  382. vec4 shadowPosWithDepthBias;
  383. return CCSpotShadowFactorBase(shadowPosWithDepthBias, shadowPos, worldPos, shadowBias);
  384. }
  385. #endif