Histogram.compute 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #pragma warning(disable : 3568)
  2. #pragma exclude_renderers gles gles3 d3d11_9x
  3. #define HISTOGRAM_BINS 256
  4. #define GROUP_SIZE_X 16
  5. #define GROUP_SIZE_Y 16
  6. #include "../StdLib.hlsl"
  7. #include "../Colors.hlsl"
  8. RWStructuredBuffer<uint> _HistogramBuffer;
  9. Texture2D<float4> _Source;
  10. CBUFFER_START(Params)
  11. float4 _Params; // x: width, y: height, z: linear, w: channel
  12. CBUFFER_END
  13. groupshared uint gs_histogram[HISTOGRAM_BINS];
  14. #ifdef DISABLE_COMPUTE_SHADERS
  15. TRIVIAL_COMPUTE_KERNEL(KHistogramGather)
  16. TRIVIAL_COMPUTE_KERNEL(KHistogramClear)
  17. #else
  18. #pragma kernel KHistogramGather
  19. [numthreads(GROUP_SIZE_X, GROUP_SIZE_Y, 1)]
  20. void KHistogramGather(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID)
  21. {
  22. const uint localThreadId = groupThreadId.y * GROUP_SIZE_X + groupThreadId.x;
  23. // Clears the shared memory
  24. if (localThreadId < HISTOGRAM_BINS)
  25. gs_histogram[localThreadId] = 0u;
  26. GroupMemoryBarrierWithGroupSync();
  27. // Gather local group histogram
  28. if (dispatchThreadId.x < uint(_Params.x) && dispatchThreadId.y < uint(_Params.y))
  29. {
  30. float3 color = saturate(_Source[dispatchThreadId].xyz);
  31. // We want a gamma-corrected histogram (like Photoshop & all)
  32. if (_Params.z > 0)
  33. color = LinearToSRGB(color);
  34. // Convert channel value to histogram bin
  35. float channel;
  36. uint c = uint(_Params.w);
  37. if (c > 2) channel = Luminance(color);
  38. else channel = color[c];
  39. uint idx = (uint)(round(channel * 255.0));
  40. InterlockedAdd(gs_histogram[idx], 1u);
  41. }
  42. GroupMemoryBarrierWithGroupSync();
  43. // Merge everything
  44. if (localThreadId < HISTOGRAM_BINS)
  45. InterlockedAdd(_HistogramBuffer[localThreadId], gs_histogram[localThreadId]);
  46. }
  47. #pragma kernel KHistogramClear
  48. [numthreads(GROUP_SIZE_X, 1, 1)]
  49. void KHistogramClear(uint dispatchThreadId : SV_DispatchThreadID)
  50. {
  51. if (dispatchThreadId < HISTOGRAM_BINS)
  52. _HistogramBuffer[dispatchThreadId] = 0u;
  53. }
  54. #endif // DISABLE_COMPUTE_SHADERS