River Jiang
2020-10-28 8637f933a9987b4b16dd9725189a1c6ee2685118
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "UnityCG.cginc"
 
RWStructuredBuffer<uint4> _Waveform;
Texture2D<float4> _Source;
 
CBUFFER_START (Params)
    uint _IsLinear;
    uint4 _Channels;
CBUFFER_END
 
#define COLUMNS 384
 
#pragma kernel KWaveform
[numthreads(1,COLUMNS,1)]
void KWaveform(uint2 dispatchThreadId : SV_DispatchThreadID)
{
    // We want a gamma corrected colors
    float3 color = _Source[dispatchThreadId].rgb;
    if (_IsLinear > 0u)
        color = LinearToGammaSpace(color);
 
    color = saturate(color);
 
    // Convert color & luminance to histogram bins
    const float kColumnsMinusOne = COLUMNS - 1.0;
    uint3 idx_c = (uint3)(round(color * kColumnsMinusOne));
    uint idx_l = (uint)(round(dot(color.rgb, float3(0.2126, 0.7152, 0.0722)) * kColumnsMinusOne));
 
    // A lot of atomic operations will be skipped so there's no need to over-think this one.
    uint j = dispatchThreadId.x * COLUMNS;
    if (_Channels.x > 0u && idx_c.x > 0u) InterlockedAdd(_Waveform[j + idx_c.x].x, 1u); // Red
    if (_Channels.y > 0u && idx_c.y > 0u) InterlockedAdd(_Waveform[j + idx_c.y].y, 1u); // Green
    if (_Channels.z > 0u && idx_c.z > 0u) InterlockedAdd(_Waveform[j + idx_c.z].z, 1u); // Blue
    if (_Channels.w > 0u) InterlockedAdd(_Waveform[j + idx_l].w, 1u); // Luminance
}
 
#pragma kernel KWaveformClear
[numthreads(1, COLUMNS, 1)]
void KWaveformClear(uint2 dispatchThreadId : SV_DispatchThreadID)
{
    _Waveform[dispatchThreadId.x * COLUMNS + dispatchThreadId.y] = uint4(0u, 0u, 0u, 0u);
}