#include "common.nocompile.glsl"
layout(local_size_x = 256, local_size_y = 1) in;
layout(r16f, binding = 0) uniform image2D target_image;
// adapated from https://bruop.github.io/exposure/ and http://www.alextardif.com/HistogramLuminance.html
shared uint histogram_shared[256];
layout(std430, binding = 1) buffer HistogramBuffer {
uint histogram[];
};
layout(push_constant) uniform readonly PushConstant{
vec4 params;
void main() {
uint count_for_this_bin = histogram[gl_LocalInvocationIndex];
histogram_shared[gl_LocalInvocationIndex] = count_for_this_bin * gl_LocalInvocationIndex;
groupMemoryBarrier();
histogram[gl_LocalInvocationIndex] = 0;
for(uint cutoff = (256 >> 1); cutoff > 0; cutoff >>= 1) {
if(uint(gl_LocalInvocationIndex) < cutoff) {
histogram_shared[gl_LocalInvocationIndex] += histogram_shared[gl_LocalInvocationIndex + cutoff];
}
if(gl_LocalInvocationIndex == 0) {
float weightedLogAverage = (histogram_shared[0] / max(params.w - float(count_for_this_bin), 1.0)) - 1.0;
float weightedAvgLum = exp2(weightedLogAverage / 254.0 * params.y + params.x);
float lumLastFrame = imageLoad(target_image, ivec2(0, 0)).x;
float adaptedLum = lumLastFrame + (weightedAvgLum - lumLastFrame) * params.z;
imageStore(target_image, ivec2(0, 0), vec4(adaptedLum, 0.0, 0.0, 0.0));