123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- {
- "__type__": "cc.EffectAsset",
- "_name": "pipeline/cluster-culling",
- "_objFlags": 0,
- "__editorExtras__": {},
- "_native": "",
- "techniques": [
- {
- "name": "opaque",
- "passes": [
- {
- "pass": "cluster-culling-cs",
- "program": "pipeline/cluster-culling|cluster-main"
- }
- ]
- }
- ],
- "shaders": [
- {
- "blocks": [],
- "samplerTextures": [],
- "samplers": [],
- "textures": [],
- "buffers": [],
- "images": [],
- "subpassInputs": [],
- "attributes": [],
- "varyings": [],
- "fragColors": [],
- "descriptors": [
- {
- "rate": 0,
- "blocks": [],
- "samplerTextures": [],
- "samplers": [],
- "textures": [],
- "buffers": [],
- "images": [],
- "subpassInputs": []
- },
- {
- "rate": 1,
- "blocks": [],
- "samplerTextures": [],
- "samplers": [],
- "textures": [],
- "buffers": [],
- "images": [],
- "subpassInputs": []
- },
- {
- "rate": 2,
- "blocks": [],
- "samplerTextures": [],
- "samplers": [],
- "textures": [],
- "buffers": [],
- "images": [],
- "subpassInputs": []
- },
- {
- "rate": 3,
- "blocks": [
- {
- "tags": {},
- "name": "CCConst",
- "members": [
- {
- "name": "cc_nearFar",
- "typename": "vec4",
- "type": 16,
- "count": 1
- },
- {
- "name": "cc_viewPort",
- "typename": "vec4",
- "type": 16,
- "count": 1
- },
- {
- "name": "cc_workGroup",
- "typename": "vec4",
- "type": 16,
- "count": 1
- },
- {
- "name": "cc_matView",
- "typename": "mat4",
- "type": 25,
- "count": 1
- },
- {
- "name": "cc_matProjInv",
- "typename": "mat4",
- "type": 25,
- "count": 1
- }
- ],
- "defines": [],
- "stageFlags": 32,
- "rate": 3
- }
- ],
- "samplerTextures": [],
- "samplers": [],
- "textures": [],
- "buffers": [
- {
- "name": "b_ccLightsBuffer",
- "memoryAccess": 1,
- "defines": [],
- "stageFlags": 32,
- "binding": 0
- },
- {
- "name": "b_clustersBuffer",
- "memoryAccess": 1,
- "defines": [],
- "stageFlags": 32,
- "binding": 1
- },
- {
- "name": "b_clusterLightIndicesBuffer",
- "memoryAccess": 3,
- "defines": [],
- "stageFlags": 32,
- "binding": 2
- },
- {
- "name": "b_clusterLightGridBuffer",
- "memoryAccess": 3,
- "defines": [],
- "stageFlags": 32,
- "binding": 3
- },
- {
- "name": "b_globalIndexBuffer",
- "memoryAccess": 3,
- "defines": [],
- "stageFlags": 32,
- "binding": 4
- }
- ],
- "images": [],
- "subpassInputs": []
- }
- ],
- "hash": 3688014143,
- "glsl4": {
- "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}"
- },
- "glsl3": {
- "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}"
- },
- "glsl1": {
- "compute": ""
- },
- "builtins": {
- "globals": {
- "blocks": [
- {
- "name": "CCConst",
- "defines": []
- }
- ],
- "samplerTextures": [],
- "buffers": [],
- "images": []
- },
- "locals": {
- "blocks": [],
- "samplerTextures": [],
- "buffers": [],
- "images": []
- },
- "statistics": {
- "CC_EFFECT_USED_COMPUTE_UNIFORM_VECTORS": 11
- }
- },
- "defines": [],
- "name": "pipeline/cluster-culling|cluster-main"
- }
- ],
- "combinations": [],
- "hideInEditor": false
- }
|