CMWaveform.compute 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "StdLib.hlsl"
  2. RWStructuredBuffer<uint4> _WaveformBuffer;
  3. Texture2D<float4> _Source;
  4. SamplerState sampler_Source;
  5. cbuffer name
  6. {
  7. float4 _Params; // x: source width, y: source height, z: linear, w: histogramResolution
  8. };
  9. #if defined SHADER_API_GLES3
  10. #define GROUP_SIZE 128
  11. #define GROUP_SIZE_X 16
  12. #define GROUP_SIZE_Y 8
  13. #else
  14. #define GROUP_SIZE 256
  15. #define GROUP_SIZE_X 16
  16. #define GROUP_SIZE_Y 16
  17. #endif
  18. half3 LinearToSRGB(half3 c)
  19. {
  20. half3 sRGBLo = c * 12.92;
  21. half3 sRGBHi = (PositivePow(c, half3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4)) * 1.055) - 0.055;
  22. half3 sRGB = (c <= 0.0031308) ? sRGBLo : sRGBHi;
  23. return sRGB;
  24. }
  25. #pragma kernel KCMWaveformGather
  26. [numthreads(1, GROUP_SIZE, 1)]
  27. void KCMWaveformGather(uint2 dispatchThreadId : SV_DispatchThreadID)
  28. {
  29. // Gather local group histogram
  30. if (dispatchThreadId.x < uint(_Params.x) && dispatchThreadId.y < uint(_Params.y))
  31. {
  32. float3 color = _Source[dispatchThreadId].rgb;
  33. color = saturate(color);
  34. // We want a gamma-corrected histogram (like Photoshop & all)
  35. if (_Params.z > 0)
  36. color = LinearToSRGB(color);
  37. // Convert channel values to histogram bins
  38. uint3 idx = (uint3)(round(color * (_Params.w - 1)));
  39. idx += dispatchThreadId.x * _Params.w;
  40. if (idx.x > 0u) InterlockedAdd(_WaveformBuffer[idx.x].x, 1u); // Red
  41. if (idx.y > 0u) InterlockedAdd(_WaveformBuffer[idx.y].y, 1u); // Green
  42. if (idx.z > 0u) InterlockedAdd(_WaveformBuffer[idx.z].z, 1u); // Blue
  43. }
  44. }
  45. #pragma kernel KCMWaveformClear
  46. [numthreads(GROUP_SIZE_X, GROUP_SIZE_Y, 1)]
  47. void KCMWaveformClear(uint2 dispatchThreadId : SV_DispatchThreadID)
  48. {
  49. if (dispatchThreadId.x < uint(_Params.x) && dispatchThreadId.y < uint(_Params.w))
  50. _WaveformBuffer[dispatchThreadId.y * uint(_Params.x) + dispatchThreadId.x] = uint4(0u, 0u, 0u, 0u);
  51. }