Guest User

Untitled

a guest
Oct 17th, 2025
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.49 KB | None | 0 0
  1. #version 430 core
  2. layout(local_size_x = 16, local_size_y = 9, local_size_z = 4) in;
  3.  
  4. struct PointLight{
  5. vec4 position;
  6. vec4 color;
  7. uint enabled;
  8. float intensity;
  9. float range;
  10. };
  11.  
  12. struct LightGrid{
  13. uint offset;
  14. uint count;
  15. };
  16.  
  17. struct VolumeTileAABB{
  18. vec4 minPoint;
  19. vec4 maxPoint;
  20. };
  21.  
  22. layout (std430, binding = 1) buffer clusterAABB{
  23. VolumeTileAABB cluster[ ];
  24. };
  25.  
  26. layout (std430, binding = 2) buffer screenToView{
  27. mat4 inverseProjection;
  28. uvec4 tileSizes;
  29. uvec2 screenDimensions;
  30. };
  31.  
  32. layout (std430, binding = 3) buffer lightSSBO{
  33. PointLight pointLight[];
  34. };
  35.  
  36. layout (std430, binding = 4) buffer lightIndexSSBO{
  37. uint globalLightIndexList[];
  38. };
  39.  
  40. layout (std430, binding = 5) buffer lightGridSSBO{
  41. LightGrid lightGrid[];
  42. };
  43.  
  44. layout (std430, binding = 6) buffer globalIndexCountSSBO{
  45. uint globalIndexCount;
  46. };
  47.  
  48. //Shared variables
  49. shared PointLight sharedLights[16*9*4];
  50.  
  51. uniform mat4 viewMatrix;
  52.  
  53. bool testSphereAABB(uint light, uint tile);
  54. float sqDistPointAABB(vec3 point, uint tile);
  55.  
  56. void main(){
  57. globalIndexCount = 0;
  58. uint threadCount = gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z;
  59. uint lightCount = pointLight.length();
  60. uint numBatches = (lightCount + threadCount -1) / threadCount;
  61.  
  62. uint tileIndex = gl_LocalInvocationIndex + gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z * gl_WorkGroupID.z;
  63.  
  64. uint visibleLightCount = 0;
  65. uint visibleLightIndices[100];
  66.  
  67. for( uint batch = 0; batch < numBatches; ++batch){
  68. uint lightIndex = batch * threadCount + gl_LocalInvocationIndex;
  69.  
  70. //Prevent overflow by clamping to last light which is always null
  71. lightIndex = min(lightIndex, lightCount);
  72.  
  73. //Populating shared light array
  74. sharedLights[gl_LocalInvocationIndex] = pointLight[lightIndex];
  75. barrier();
  76.  
  77. //Iterating within the current batch of lights
  78. for( uint light = 0; light < threadCount; ++light){
  79. if( sharedLights[light].enabled == 1){
  80. if( testSphereAABB(light, tileIndex) ){
  81. visibleLightIndices[visibleLightCount] = batch * threadCount + light;
  82. visibleLightCount += 1;
  83. }
  84. }
  85. }
  86. }
  87.  
  88. //We want all thread groups to have completed the light tests before continuing
  89. barrier();
  90.  
  91. uint offset = atomicAdd(globalIndexCount, visibleLightCount);
  92.  
  93. for(uint i = 0; i < visibleLightCount; ++i){
  94. globalLightIndexList[offset + i] = visibleLightIndices[i];
  95. }
  96.  
  97. lightGrid[tileIndex].offset = offset;
  98. lightGrid[tileIndex].count = visibleLightCount;
  99. }
  100.  
  101. bool testSphereAABB(uint light, uint tile){
  102. float radius = sharedLights[light].range;
  103. vec3 center = vec3(viewMatrix * sharedLights[light].position);
  104. float squaredDistance = sqDistPointAABB(center, tile);
  105.  
  106. return squaredDistance <= (radius * radius);
  107. }
  108.  
  109. float sqDistPointAABB(vec3 point, uint tile){
  110. float sqDist = 0.0;
  111. VolumeTileAABB currentCell = cluster[tile];
  112. cluster[tile].maxPoint[3] = tile;
  113. for(int i = 0; i < 3; ++i){
  114. float v = point[i];
  115. if(v < currentCell.minPoint[i]){
  116. sqDist += (currentCell.minPoint[i] - v) * (currentCell.minPoint[i] - v);
  117. }
  118. if(v > currentCell.maxPoint[i]){
  119. sqDist += (v - currentCell.maxPoint[i]) * (v - currentCell.maxPoint[i]);
  120. }
  121. }
  122.  
  123. return sqDist;
  124. }
Advertisement
Add Comment
Please, Sign In to add comment