64 lines
1.8 KiB
GLSL
64 lines
1.8 KiB
GLSL
#type compute
|
|
#version 460 core
|
|
layout(local_size_x = 1, local_size_y = 1) in;
|
|
|
|
layout(binding = 0, std430) buffer Histogram {
|
|
uint bins[64];
|
|
};
|
|
layout(binding = 1, std430) buffer Exposure {
|
|
float exposure;
|
|
};
|
|
|
|
uniform float u_SpeedUp;
|
|
uniform float u_SpeedDown;
|
|
uniform float u_Key;
|
|
uniform float u_LowPercent;
|
|
uniform float u_HighPercent;
|
|
uniform float u_MinExposure;
|
|
uniform float u_MaxExposure;
|
|
uniform float u_DeltaTime;
|
|
uniform float u_LogMin;
|
|
uniform float u_LogMax;
|
|
|
|
void main() {
|
|
float currentExposure = exposure;
|
|
|
|
uint total = 0;
|
|
uint prefix[64];
|
|
for (int i = 0; i < 64; i++) {
|
|
total += bins[i];
|
|
prefix[i] = total;
|
|
}
|
|
|
|
float lowCount = u_LowPercent * 0.01 * total;
|
|
float highCount = u_HighPercent * 0.01 * total;
|
|
int lowBin = 0, highBin = 63;
|
|
for (int i = 0; i < 64; i++) {
|
|
if (prefix[i] < lowCount) lowBin = i + 1;
|
|
if (prefix[i] < highCount) highBin = i + 1;
|
|
}
|
|
lowBin = clamp(lowBin, 0, 63);
|
|
highBin = clamp(highBin, 0, 63);
|
|
|
|
float sumLum = 0.0;
|
|
uint count = 0;
|
|
for (int i = lowBin; i <= highBin; i++) {
|
|
float t = (float(i) + 0.5) / 64.0;
|
|
float logLum = u_LogMin + t * (u_LogMax - u_LogMin);
|
|
float lum = exp2(logLum);
|
|
sumLum += lum * float(bins[i]);
|
|
count += bins[i];
|
|
}
|
|
float avgLum = count > 0 ? sumLum / count : 0.18;
|
|
|
|
float targetExposure = u_Key / max(avgLum, 0.0001);
|
|
targetExposure = clamp(targetExposure, u_MinExposure, u_MaxExposure);
|
|
|
|
float speed = (targetExposure > currentExposure) ? u_SpeedUp : u_SpeedDown;
|
|
float adaptFactor = 1.0 - exp(-speed * u_DeltaTime);
|
|
float newExposure = mix(currentExposure, targetExposure, adaptFactor);
|
|
newExposure = clamp(newExposure, u_MinExposure, u_MaxExposure);
|
|
|
|
exposure = newExposure;
|
|
}
|