81 lines
No EOL
2.1 KiB
Text
81 lines
No EOL
2.1 KiB
Text
include "pipelines/common.glsl"
|
|
|
|
compute_shader [[
|
|
#if defined PASS2 || defined PASS0
|
|
layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
|
|
#else
|
|
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
|
#endif
|
|
|
|
layout (binding = 0) uniform sampler2D u_image;
|
|
layout (binding = 1, std430) coherent buffer OutData {
|
|
uint b_histogram[256];
|
|
float b_accum;
|
|
};
|
|
layout(binding = 4, std140) uniform Data {
|
|
vec2 u_size;
|
|
float u_accomodation_speed;
|
|
};
|
|
|
|
shared uint histogram[256];
|
|
|
|
uint luminanceToBin(float lum, float min, float inv_range) {
|
|
if (lum < 1e-3) {
|
|
return 0;
|
|
}
|
|
float logLum = clamp((log2(lum) - min) * inv_range, 0.0, 1.0);
|
|
return uint(logLum * 254.0 + 1.0);
|
|
}
|
|
|
|
float binToLuminance(float bin, float min, float range) {
|
|
if (bin <= 1e-5) return 0;
|
|
float t = saturate((bin - 1) / 254.0);
|
|
return exp2(t * range + min);
|
|
}
|
|
|
|
void main() {
|
|
const float range = 12.0;
|
|
const float min = -6;
|
|
#ifdef PASS0
|
|
b_histogram[gl_LocalInvocationID.x] = 0;
|
|
#elif !defined PASS2
|
|
uint idx = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 16;
|
|
histogram[idx] = 0;
|
|
|
|
groupMemoryBarrier();
|
|
barrier();
|
|
|
|
if (all(lessThan(gl_GlobalInvocationID.xy, uvec2(u_size + 0.5)))) {
|
|
float luminance = luminance(texture(u_image, ivec2(gl_GlobalInvocationID.xy) / u_size).rgb);
|
|
uint bin = luminanceToBin(luminance, min, 1 / range);
|
|
atomicAdd(histogram[bin], 1);
|
|
}
|
|
|
|
groupMemoryBarrier();
|
|
barrier();
|
|
|
|
atomicAdd(b_histogram[idx], histogram[idx]);
|
|
#else
|
|
uint idx = gl_LocalInvocationID.x;
|
|
histogram[idx] = b_histogram[idx] * idx;
|
|
|
|
groupMemoryBarrier();
|
|
barrier();
|
|
|
|
|
|
for (uint offset = 256 >> 1; offset > 0; offset >>= 1) {
|
|
if (idx < offset) {
|
|
histogram[idx] += histogram[idx + offset];
|
|
}
|
|
groupMemoryBarrier();
|
|
barrier();
|
|
}
|
|
|
|
if (idx == 0) {
|
|
float avg_bin = histogram[0] / float(u_size.x * u_size.y);
|
|
float avg_lum = binToLuminance(avg_bin, min, range);
|
|
b_accum += (avg_lum - b_accum) * (1 - exp(-Global.frame_time_delta * u_accomodation_speed));
|
|
}
|
|
#endif
|
|
}
|
|
]] |