cluster-build.effect 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright (c) 2023 Xiamen Yaji Software Co., Ltd.
  2. CCEffect %{
  3. techniques:
  4. - name: opaque
  5. passes:
  6. - compute: cluster-main
  7. pass: cluster-build-cs
  8. }%
  9. CCProgram cluster-main %{
  10. #include <common/math/coordinates>
  11. precision highp float;
  12. #define LOCAL_SIZE_X 16u
  13. #define LOCAL_SIZE_Y 8u
  14. #define LOCAL_SIZE_Z 1u
  15. layout (local_size_x = LOCAL_SIZE_X, local_size_y = LOCAL_SIZE_Y, local_size_z = LOCAL_SIZE_Z) in;
  16. #pragma rate CCConst pass
  17. layout(std140) uniform CCConst {
  18. vec4 cc_nearFar;
  19. vec4 cc_viewPort;
  20. vec4 cc_workGroup;
  21. mat4 cc_matView;
  22. mat4 cc_matProjInv;
  23. };
  24. #pragma rate b_clustersBuffer pass
  25. layout(std430) buffer b_clustersBuffer { vec4 b_clusters[]; };
  26. vec4 screen2Eye(vec4 coord) {
  27. vec3 ndc = vec3(
  28. 2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,
  29. 2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,
  30. 2.0 * coord.z - 1.0);
  31. CC_HANDLE_SAMPLE_NDC_FLIP_STATIC(ndc.y);
  32. vec4 eye = ((cc_matProjInv) * (vec4(ndc, 1.0)));
  33. eye = eye / eye.w;
  34. return eye;
  35. }
  36. void main () {
  37. uint clusterIndex = gl_GlobalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y +
  38. gl_GlobalInvocationID.y * gl_WorkGroupSize.x +
  39. gl_GlobalInvocationID.x;
  40. float clusterSizeX = ceil(cc_viewPort.z / cc_workGroup.x);
  41. float clusterSizeY = ceil(cc_viewPort.w / cc_workGroup.y);
  42. vec4 minScreen = vec4(vec2(gl_GlobalInvocationID.xy) * vec2(clusterSizeX, clusterSizeY), 1.0, 1.0);
  43. vec4 maxScreen = vec4(vec2(gl_GlobalInvocationID.xy + uvec2(1, 1)) * vec2(clusterSizeX, clusterSizeY), 1.0, 1.0);
  44. vec3 minEye = screen2Eye(minScreen).xyz;
  45. vec3 maxEye = screen2Eye(maxScreen).xyz;
  46. float clusterNear = -cc_nearFar.x * pow(cc_nearFar.y / cc_nearFar.x, float(gl_GlobalInvocationID.z) / cc_workGroup.z);
  47. float clusterFar = -cc_nearFar.x * pow(cc_nearFar.y / cc_nearFar.x, float(gl_GlobalInvocationID.z + 1u) / cc_workGroup.z);
  48. vec3 minNear = minEye * clusterNear / minEye.z;
  49. vec3 minFar = minEye * clusterFar / minEye.z;
  50. vec3 maxNear = maxEye * clusterNear / maxEye.z;
  51. vec3 maxFar = maxEye * clusterFar / maxEye.z;
  52. vec3 minBounds = min(min(minNear, minFar), min(maxNear, maxFar));
  53. vec3 maxBounds = max(max(minNear, minFar), max(maxNear, maxFar));
  54. b_clusters[2u * clusterIndex + 0u] = vec4(minBounds, 1.0);
  55. b_clusters[2u * clusterIndex + 1u] = vec4(maxBounds, 1.0);
  56. }
  57. }%