84ac6f69-3086-455a-86a4-561da8ee710b.json 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. {
  2. "__type__": "cc.EffectAsset",
  3. "_name": "pipeline/cluster-culling",
  4. "_objFlags": 0,
  5. "__editorExtras__": {},
  6. "_native": "",
  7. "techniques": [
  8. {
  9. "name": "opaque",
  10. "passes": [
  11. {
  12. "pass": "cluster-culling-cs",
  13. "program": "pipeline/cluster-culling|cluster-main"
  14. }
  15. ]
  16. }
  17. ],
  18. "shaders": [
  19. {
  20. "blocks": [],
  21. "samplerTextures": [],
  22. "samplers": [],
  23. "textures": [],
  24. "buffers": [],
  25. "images": [],
  26. "subpassInputs": [],
  27. "attributes": [],
  28. "varyings": [],
  29. "fragColors": [],
  30. "descriptors": [
  31. {
  32. "rate": 0,
  33. "blocks": [],
  34. "samplerTextures": [],
  35. "samplers": [],
  36. "textures": [],
  37. "buffers": [],
  38. "images": [],
  39. "subpassInputs": []
  40. },
  41. {
  42. "rate": 1,
  43. "blocks": [],
  44. "samplerTextures": [],
  45. "samplers": [],
  46. "textures": [],
  47. "buffers": [],
  48. "images": [],
  49. "subpassInputs": []
  50. },
  51. {
  52. "rate": 2,
  53. "blocks": [],
  54. "samplerTextures": [],
  55. "samplers": [],
  56. "textures": [],
  57. "buffers": [],
  58. "images": [],
  59. "subpassInputs": []
  60. },
  61. {
  62. "rate": 3,
  63. "blocks": [
  64. {
  65. "tags": {},
  66. "name": "CCConst",
  67. "members": [
  68. {
  69. "name": "cc_nearFar",
  70. "typename": "vec4",
  71. "type": 16,
  72. "count": 1
  73. },
  74. {
  75. "name": "cc_viewPort",
  76. "typename": "vec4",
  77. "type": 16,
  78. "count": 1
  79. },
  80. {
  81. "name": "cc_workGroup",
  82. "typename": "vec4",
  83. "type": 16,
  84. "count": 1
  85. },
  86. {
  87. "name": "cc_matView",
  88. "typename": "mat4",
  89. "type": 25,
  90. "count": 1
  91. },
  92. {
  93. "name": "cc_matProjInv",
  94. "typename": "mat4",
  95. "type": 25,
  96. "count": 1
  97. }
  98. ],
  99. "defines": [],
  100. "stageFlags": 32,
  101. "rate": 3
  102. }
  103. ],
  104. "samplerTextures": [],
  105. "samplers": [],
  106. "textures": [],
  107. "buffers": [
  108. {
  109. "name": "b_ccLightsBuffer",
  110. "memoryAccess": 1,
  111. "defines": [],
  112. "stageFlags": 32,
  113. "binding": 0
  114. },
  115. {
  116. "name": "b_clustersBuffer",
  117. "memoryAccess": 1,
  118. "defines": [],
  119. "stageFlags": 32,
  120. "binding": 1
  121. },
  122. {
  123. "name": "b_clusterLightIndicesBuffer",
  124. "memoryAccess": 3,
  125. "defines": [],
  126. "stageFlags": 32,
  127. "binding": 2
  128. },
  129. {
  130. "name": "b_clusterLightGridBuffer",
  131. "memoryAccess": 3,
  132. "defines": [],
  133. "stageFlags": 32,
  134. "binding": 3
  135. },
  136. {
  137. "name": "b_globalIndexBuffer",
  138. "memoryAccess": 3,
  139. "defines": [],
  140. "stageFlags": 32,
  141. "binding": 4
  142. }
  143. ],
  144. "images": [],
  145. "subpassInputs": []
  146. }
  147. ],
  148. "hash": 3688014143,
  149. "glsl4": {
  150. "compute": "\nprecision highp float;\n#define LOCAL_SIZE_X 16u\n#define LOCAL_SIZE_Y 8u\n#define LOCAL_SIZE_Z 1u\n#define LOCAL_SIZE (LOCAL_SIZE_X * LOCAL_SIZE_Y * LOCAL_SIZE_Z)\nlayout(std140) uniform CCConst {\n vec4 cc_nearFar;\n vec4 cc_viewPort;\n vec4 cc_workGroup;\n mat4 cc_matView;\n mat4 cc_matProjInv;\n};\nlayout(std430, set = 1, binding = 0) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, set = 1, binding = 1) readonly buffer b_clustersBuffer { vec4 b_clusters[]; };\nlayout(std430, set = 1, binding = 2) buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, set = 1, binding = 3) buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nlayout(std430, set = 1, binding = 4) buffer b_globalIndexBuffer { uint b_globalIndex[]; };\nstruct CCLight {\n vec4 cc_lightPos;\n vec4 cc_lightColor;\n vec4 cc_lightSizeRangeAngle;\n vec4 cc_lightDir;\n vec4 cc_lightBoundingSizeVS;\n};\nuint ccLightCount()\n{\n return uint(b_ccLights[3].w);\n}\nCCLight getCCLight(uint i)\n{\n CCLight light;\n light.cc_lightPos = b_ccLights[5u * i + 0u];\n light.cc_lightColor = b_ccLights[5u * i + 1u];\n light.cc_lightSizeRangeAngle = b_ccLights[5u * i + 2u];\n light.cc_lightDir = b_ccLights[5u * i + 3u];\n light.cc_lightBoundingSizeVS = b_ccLights[5u * i + 4u];\n return light;\n}\nstruct Cluster {\n vec3 minBounds;\n vec3 maxBounds;\n};\nstruct LightGrid {\n uint offset;\n uint ccLights;\n};\nCluster getCluster(uint index)\n{\n Cluster cluster;\n cluster.minBounds = b_clusters[2u * index + 0u].xyz;\n cluster.maxBounds = b_clusters[2u * index + 1u].xyz;\n return cluster;\n}\nbool ccLightIntersectsCluster(CCLight light, Cluster cluster)\n{\n if (light.cc_lightPos.w > 0.0) {\n vec3 halfExtents = (cluster.maxBounds - cluster.minBounds) * 0.5;\n vec3 center = (cluster.minBounds + cluster.maxBounds) * 0.5;\n float sphereRadius = sqrt(dot(halfExtents, halfExtents));\n light.cc_lightDir = ((cc_matView) * (vec4(light.cc_lightDir.xyz, 1.0)));\n light.cc_lightDir.xyz = (light.cc_lightDir - ((cc_matView) * (vec4(0,0,0, 1.0)))).xyz;\n if (length(light.cc_lightDir.xyz) > 0.1) {\n light.cc_lightDir.xyz = normalize(light.cc_lightDir.xyz);\n }\n vec3 v = center - light.cc_lightPos.xyz;\n float lenSq = dot(v, v);\n float v1Len = dot(v, light.cc_lightDir.xyz);\n if(light.cc_lightDir.w == 1.0) {\n v1Len = sqrt(lenSq);\n return (v1Len <= sphereRadius + light.cc_lightSizeRangeAngle.y);\n }\n float cosAngle = light.cc_lightSizeRangeAngle.z;\n float sinAngle = sqrt(1.0 - cosAngle * cosAngle);\n float distanceClosestPoint = cosAngle * sqrt(lenSq - v1Len * v1Len) - v1Len * sinAngle;\n bool angleCull = distanceClosestPoint > sphereRadius;\n bool frontCull = v1Len > sphereRadius + light.cc_lightSizeRangeAngle.y;\n bool backCull = v1Len < -sphereRadius;\n return !(angleCull || frontCull || backCull);\n }\n vec3 closest = max(cluster.minBounds, min(light.cc_lightPos.xyz, cluster.maxBounds));\n vec3 dist = closest - light.cc_lightPos.xyz;\n return dot(dist, dist) <= (light.cc_lightSizeRangeAngle.y * light.cc_lightSizeRangeAngle.y);\n}\nshared CCLight lights[LOCAL_SIZE];\nlayout(local_size_x = LOCAL_SIZE_X, local_size_y = LOCAL_SIZE_Y, local_size_z = LOCAL_SIZE_Z) in;\nvoid main()\n{\n uint visibleLights[200];\n uint visibleCount = 0u;\n uint clusterIndex = gl_GlobalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y +\n gl_GlobalInvocationID.y * gl_WorkGroupSize.x +\n gl_GlobalInvocationID.x;\n Cluster cluster = getCluster(clusterIndex);\n uint lightCount = ccLightCount();\n uint lightOffset = 0u;\n while (lightOffset < lightCount) {\n uint batchSize = min(LOCAL_SIZE, lightCount - lightOffset);\n if (uint(gl_LocalInvocationIndex) < batchSize) {\n uint lightIndex = lightOffset + gl_LocalInvocationIndex;\n CCLight light = getCCLight(lightIndex);\n light.cc_lightPos.xyz = ((cc_matView) * (vec4(light.cc_lightPos.xyz, 1.0))).xyz;\n lights[gl_LocalInvocationIndex] = light;\n }\n barrier();\n for (uint i = 0u; i < batchSize; i++) {\n if (visibleCount < 200u && ccLightIntersectsCluster(lights[i], cluster)) {\n visibleLights[visibleCount] = lightOffset + i;\n visibleCount++;\n }\n }\n lightOffset += batchSize;\n }\n barrier();\n uint offset = 0u;\n offset = atomicAdd(b_globalIndex[0], visibleCount);\n for (uint i = 0u; i < visibleCount; i++) {\n b_clusterLightIndices[offset + i] = visibleLights[i];\n }\n b_clusterLightGrid[clusterIndex] = uvec4(offset, visibleCount, 0, 0);\n}"
  151. },
  152. "glsl3": {
  153. "compute": "\nprecision highp float;\n#define LOCAL_SIZE_X 16u\n#define LOCAL_SIZE_Y 8u\n#define LOCAL_SIZE_Z 1u\n#define LOCAL_SIZE (LOCAL_SIZE_X * LOCAL_SIZE_Y * LOCAL_SIZE_Z)\nlayout(std140) uniform CCConst {\n vec4 cc_nearFar;\n vec4 cc_viewPort;\n vec4 cc_workGroup;\n mat4 cc_matView;\n mat4 cc_matProjInv;\n};\nlayout(std430, binding = 0) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, binding = 1) readonly buffer b_clustersBuffer { vec4 b_clusters[]; };\nlayout(std430, binding = 2) buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, binding = 3) buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nlayout(std430, binding = 4) buffer b_globalIndexBuffer { uint b_globalIndex[]; };\nstruct CCLight {\n vec4 cc_lightPos;\n vec4 cc_lightColor;\n vec4 cc_lightSizeRangeAngle;\n vec4 cc_lightDir;\n vec4 cc_lightBoundingSizeVS;\n};\nuint ccLightCount()\n{\n return uint(b_ccLights[3].w);\n}\nCCLight getCCLight(uint i)\n{\n CCLight light;\n light.cc_lightPos = b_ccLights[5u * i + 0u];\n light.cc_lightColor = b_ccLights[5u * i + 1u];\n light.cc_lightSizeRangeAngle = b_ccLights[5u * i + 2u];\n light.cc_lightDir = b_ccLights[5u * i + 3u];\n light.cc_lightBoundingSizeVS = b_ccLights[5u * i + 4u];\n return light;\n}\nstruct Cluster {\n vec3 minBounds;\n vec3 maxBounds;\n};\nstruct LightGrid {\n uint offset;\n uint ccLights;\n};\nCluster getCluster(uint index)\n{\n Cluster cluster;\n cluster.minBounds = b_clusters[2u * index + 0u].xyz;\n cluster.maxBounds = b_clusters[2u * index + 1u].xyz;\n return cluster;\n}\nbool ccLightIntersectsCluster(CCLight light, Cluster cluster)\n{\n if (light.cc_lightPos.w > 0.0) {\n vec3 halfExtents = (cluster.maxBounds - cluster.minBounds) * 0.5;\n vec3 center = (cluster.minBounds + cluster.maxBounds) * 0.5;\n float sphereRadius = sqrt(dot(halfExtents, halfExtents));\n light.cc_lightDir = ((cc_matView) * (vec4(light.cc_lightDir.xyz, 1.0)));\n light.cc_lightDir.xyz = (light.cc_lightDir - ((cc_matView) * (vec4(0,0,0, 1.0)))).xyz;\n if (length(light.cc_lightDir.xyz) > 0.1) {\n light.cc_lightDir.xyz = normalize(light.cc_lightDir.xyz);\n }\n vec3 v = center - light.cc_lightPos.xyz;\n float lenSq = dot(v, v);\n float v1Len = dot(v, light.cc_lightDir.xyz);\n if(light.cc_lightDir.w == 1.0) {\n v1Len = sqrt(lenSq);\n return (v1Len <= sphereRadius + light.cc_lightSizeRangeAngle.y);\n }\n float cosAngle = light.cc_lightSizeRangeAngle.z;\n float sinAngle = sqrt(1.0 - cosAngle * cosAngle);\n float distanceClosestPoint = cosAngle * sqrt(lenSq - v1Len * v1Len) - v1Len * sinAngle;\n bool angleCull = distanceClosestPoint > sphereRadius;\n bool frontCull = v1Len > sphereRadius + light.cc_lightSizeRangeAngle.y;\n bool backCull = v1Len < -sphereRadius;\n return !(angleCull || frontCull || backCull);\n }\n vec3 closest = max(cluster.minBounds, min(light.cc_lightPos.xyz, cluster.maxBounds));\n vec3 dist = closest - light.cc_lightPos.xyz;\n return dot(dist, dist) <= (light.cc_lightSizeRangeAngle.y * light.cc_lightSizeRangeAngle.y);\n}\nshared CCLight lights[LOCAL_SIZE];\nlayout(local_size_x = LOCAL_SIZE_X, local_size_y = LOCAL_SIZE_Y, local_size_z = LOCAL_SIZE_Z) in;\nvoid main()\n{\n uint visibleLights[200];\n uint visibleCount = 0u;\n uint clusterIndex = gl_GlobalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y +\n gl_GlobalInvocationID.y * gl_WorkGroupSize.x +\n gl_GlobalInvocationID.x;\n Cluster cluster = getCluster(clusterIndex);\n uint lightCount = ccLightCount();\n uint lightOffset = 0u;\n while (lightOffset < lightCount) {\n uint batchSize = min(LOCAL_SIZE, lightCount - lightOffset);\n if (uint(gl_LocalInvocationIndex) < batchSize) {\n uint lightIndex = lightOffset + gl_LocalInvocationIndex;\n CCLight light = getCCLight(lightIndex);\n light.cc_lightPos.xyz = ((cc_matView) * (vec4(light.cc_lightPos.xyz, 1.0))).xyz;\n lights[gl_LocalInvocationIndex] = light;\n }\n barrier();\n for (uint i = 0u; i < batchSize; i++) {\n if (visibleCount < 200u && ccLightIntersectsCluster(lights[i], cluster)) {\n visibleLights[visibleCount] = lightOffset + i;\n visibleCount++;\n }\n }\n lightOffset += batchSize;\n }\n barrier();\n uint offset = 0u;\n offset = atomicAdd(b_globalIndex[0], visibleCount);\n for (uint i = 0u; i < visibleCount; i++) {\n b_clusterLightIndices[offset + i] = visibleLights[i];\n }\n b_clusterLightGrid[clusterIndex] = uvec4(offset, visibleCount, 0, 0);\n}"
  154. },
  155. "glsl1": {
  156. "compute": ""
  157. },
  158. "builtins": {
  159. "globals": {
  160. "blocks": [
  161. {
  162. "name": "CCConst",
  163. "defines": []
  164. }
  165. ],
  166. "samplerTextures": [],
  167. "buffers": [],
  168. "images": []
  169. },
  170. "locals": {
  171. "blocks": [],
  172. "samplerTextures": [],
  173. "buffers": [],
  174. "images": []
  175. },
  176. "statistics": {
  177. "CC_EFFECT_USED_COMPUTE_UNIFORM_VECTORS": 11
  178. }
  179. },
  180. "defines": [],
  181. "name": "pipeline/cluster-culling|cluster-main"
  182. }
  183. ],
  184. "combinations": [],
  185. "hideInEditor": false
  186. }