ClusteredShadingFunctions.hlsl 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Shaders/LightFunctions.hlsl>
  7. // Debugging function
  8. Vec3 clusterHeatmap(Cluster cluster, U32 objectTypeMask)
  9. {
  10. U32 maxObjects = 0u;
  11. I32 count = 0;
  12. if((objectTypeMask & (1u << (U32)GpuSceneNonRenderableObjectType::kLight)) != 0u)
  13. {
  14. maxObjects += kMaxVisibleLights;
  15. count += I32(countbits(cluster.m_pointLightsMask | cluster.m_spotLightsMask));
  16. }
  17. if((objectTypeMask & (1u << (U32)GpuSceneNonRenderableObjectType::kDecal)) != 0u)
  18. {
  19. maxObjects += kMaxVisibleDecals;
  20. count += I32(countbits(cluster.m_decalsMask));
  21. }
  22. if((objectTypeMask & (1u << (U32)GpuSceneNonRenderableObjectType::kFogDensityVolume)) != 0u)
  23. {
  24. maxObjects += kMaxVisibleFogDensityVolumes;
  25. count += countbits(cluster.m_fogDensityVolumesMask);
  26. }
  27. if((objectTypeMask & (1u << (U32)GpuSceneNonRenderableObjectType::kReflectionProbe)) != 0u)
  28. {
  29. maxObjects += kMaxVisibleReflectionProbes;
  30. count += countbits(cluster.m_reflectionProbesMask);
  31. }
  32. if((objectTypeMask & (1u << (U32)GpuSceneNonRenderableObjectType::kGlobalIlluminationProbe)) != 0u)
  33. {
  34. maxObjects += kMaxVisibleGlobalIlluminationProbes;
  35. count += countbits(cluster.m_giProbesMask);
  36. }
  37. const F32 factor = min(1.0, F32(count) / F32(maxObjects));
  38. return heatmap(factor);
  39. }
  40. /// Returns the index of the zSplit or linearizeDepth(n, f, depth)*zSplitCount
  41. /// Simplifying this equation is 1/(a+b/depth) where a=(n-f)/(n*zSplitCount) and b=f/(n*zSplitCount)
  42. U32 computeZSplitClusterIndex(F32 depth, U32 zSplitCount, F32 a, F32 b)
  43. {
  44. const F32 fSplitIdx = 1.0 / (a + b / depth);
  45. return min(zSplitCount - 1u, (U32)fSplitIdx);
  46. }
  47. /// Return the tile index.
  48. U32 computeTileClusterIndexFragCoord(Vec2 fragCoord, U32 tileSize, U32 tileCountX)
  49. {
  50. const UVec2 tileXY = UVec2(fragCoord / F32(tileSize));
  51. return tileXY.y * tileCountX + tileXY.x;
  52. }
  53. /// Merge the tiles with z splits into a single cluster.
  54. Cluster mergeClusters(Cluster tileCluster, Cluster zCluster)
  55. {
  56. // #define ANKI_OR_MASKS(x) subgroupOr(x)
  57. #define ANKI_OR_MASKS(x) (x)
  58. Cluster outCluster;
  59. outCluster.m_pointLightsMask = ANKI_OR_MASKS(tileCluster.m_pointLightsMask & zCluster.m_pointLightsMask);
  60. outCluster.m_spotLightsMask = ANKI_OR_MASKS(tileCluster.m_spotLightsMask & zCluster.m_spotLightsMask);
  61. outCluster.m_decalsMask = ANKI_OR_MASKS(tileCluster.m_decalsMask & zCluster.m_decalsMask);
  62. outCluster.m_fogDensityVolumesMask = ANKI_OR_MASKS(tileCluster.m_fogDensityVolumesMask & zCluster.m_fogDensityVolumesMask);
  63. outCluster.m_reflectionProbesMask = ANKI_OR_MASKS(tileCluster.m_reflectionProbesMask & zCluster.m_reflectionProbesMask);
  64. outCluster.m_giProbesMask = ANKI_OR_MASKS(tileCluster.m_giProbesMask & zCluster.m_giProbesMask);
  65. #undef ANKI_OR_MASKS
  66. return outCluster;
  67. }
  68. /// Get the final cluster after ORing and ANDing the masks.
  69. Cluster getClusterFragCoord(StructuredBuffer<Cluster> clusters, Vec3 fragCoord, U32 tileSize, UVec2 tileCounts, U32 zSplitCount, F32 a, F32 b)
  70. {
  71. const Cluster tileCluster = clusters[computeTileClusterIndexFragCoord(fragCoord.xy, tileSize, tileCounts.x)];
  72. const Cluster zCluster = clusters[computeZSplitClusterIndex(fragCoord.z, zSplitCount, a, b) + tileCounts.x * tileCounts.y];
  73. return mergeClusters(tileCluster, zCluster);
  74. }
  75. Cluster getClusterFragCoord(StructuredBuffer<Cluster> clusters, ClusteredShadingUniforms unis, Vec3 fragCoord)
  76. {
  77. return getClusterFragCoord(clusters, fragCoord, unis.m_tileSize, unis.m_tileCounts, unis.m_zSplitCount, unis.m_zSplitMagic.x,
  78. unis.m_zSplitMagic.y);
  79. }