# How to generate a correct RGB + Luminance histogram?

I am trying to create a debug tool that would help me visualize an image RGB and luminance histogram. I have created a compute shader where I gather the histogram data

#pragma kernel Clear
#pragma kernel Gather

Texture2D<float4> Input;

struct HIST {
uint4 color;
};
RWStructuredBuffer<HIST> HistogramBuffer;

{
HistogramBuffer[id.x].color = uint4(0, 0, 0, 0);
}

{
uint4 col = uint4(255.0 * Input[id.xy]);

}


And in the c# code after I've gathered the data I create a final output texture.

using UnityEngine;
using UnityEngine.UI;

internal sealed class Histogram : MonoBehaviour
{
public const int HISTOGRAM_BINS = 256;
uint[] histogramData;

[SerializeField]
ComputeBuffer histogramBuffer;

[SerializeField] RawImage output = null;
[SerializeField] Texture2D input;

public void Start()
{
//Init kernels

//Init data
histogramBuffer = new ComputeBuffer(HISTOGRAM_BINS, sizeof(uint) * 4);
histogramData = new uint[HISTOGRAM_BINS * 4];

//Set data

shader.Dispatch(clearKernel, HISTOGRAM_BINS / 64, 1, 1);
shader.Dispatch(gatherkernel, input.width / 8, input.height / 8, 1);

//Get data
histogramBuffer.GetData(histogramData);

//Find highest value
uint highestValue = uint.MinValue;
for (int i = 0; i < histogramData.Length; i++)
{
if (histogramData[i] > highestValue)
{
highestValue = histogramData[i];
}
}

//Create final output texture
Texture2D final = new Texture2D(HISTOGRAM_BINS, input.height)
{
filterMode = FilterMode.Bilinear,
wrapMode = TextureWrapMode.Clamp
};
final.Apply();

//Init the texture pixels array
Color32[] pixels = new Color32[HISTOGRAM_BINS * input.height];

//Get all red values from the histogram data array
uint[] reds = new uint[HISTOGRAM_BINS];
for (int i = 0, h = 0; i < HISTOGRAM_BINS; i++, h += 4)
{
reds[i] = histogramData[h];
}
pixels = ComputeChannelHistogram(pixels, in reds, highestValue, new Color32(255, 0, 0, 255));

//Get all green values from the histogram data array
uint[] greens = new uint[HISTOGRAM_BINS];
for (int i = 0, h = 1; i < HISTOGRAM_BINS; i++, h += 4)
{
greens[i] = histogramData[h];
}
pixels = ComputeChannelHistogram(pixels, in greens, highestValue, new Color32(0, 255, 0, 255));

//Get all blue values from the histogram data array
uint[] blues = new uint[HISTOGRAM_BINS];
for (int i = 0, h = 2; i < HISTOGRAM_BINS; i++, h += 4)
{
blues[i] = histogramData[h];
}
pixels = ComputeChannelHistogram(pixels, in blues, highestValue, new Color32(0, 0, 255, 255));

//Get all lum values from the histogram data array
uint[] lum = new uint[HISTOGRAM_BINS];
for (int i = 0, h = 3; i < HISTOGRAM_BINS; i++, h += 4)
{
lum[i] = histogramData[h];
}
pixels = ComputeChannelHistogram(pixels, in lum, highestValue, new Color32(127, 127, 127, 255));

//Set pixels
final.SetPixels32(pixels); final.Apply();

//Set output image
output.texture = final;
}
Color32[] ComputeChannelHistogram(Color32[] pixels, in uint[] data, float max, Color32 color)
{
for (int x = 0; x < HISTOGRAM_BINS; x++)
{
float p = Mathf.InverseLerp(0F, max, data[x]);
for (int y = 0; y < input.height * p; y++)
{
int index = x + (y * HISTOGRAM_BINS);
Color32 pixelColor = pixels[index];

pixelColor.r += color.r;
pixelColor.g += color.g;
pixelColor.b += color.b;

pixels[index] = new Color32(pixelColor.r, pixelColor.g, pixelColor.b, 255);
}
}
return pixels;
}
}


However, I am getting weird results and not sure why.

E.g. input image (Figure 1)

The histogram that is generated

The histogram that is generated in Photoshop

Can someone please help me understand what am I doing wrong here and how can I fix it to have better results? I just recently started looking at histograms, I understand what they show and are, the vertical is a number of pixels and the horizontal bars that go from left to right are the tones, so left is blacks, the middle is midtones, and right is whites, but for some reason I have a difficult time creating one...

• Well, I have solved the issue with the same look graphs. The issue was that the offset was applied not to the histogram data index when the data for each channel was gathered into separate arrays. And that resulted in wrong data being stored. I have added a change in the question. The graphs look much better now, however, it still looks somewhat incorrect. Mine looks a lot more smooth, and in Photoshop, it looks a bit rougher. I have also added the new histogram output image to the question. Nov 21 at 17:03
• Nov 21 at 17:46