44 lines
1.2 KiB
GLSL
44 lines
1.2 KiB
GLSL
|
#version 330 core
|
||
|
|
||
|
layout(location = 0) out float fragLuminance;
|
||
|
|
||
|
uniform usampler2D histogram_tex;
|
||
|
uniform sampler2D prev_lum_tex;
|
||
|
|
||
|
uniform float osg_DeltaFrameTime;
|
||
|
|
||
|
// Higher values give faster eye adaptation times
|
||
|
const float TAU = 1.1;
|
||
|
|
||
|
// histogram.glsl
|
||
|
float bin_index_to_luminance(float bin);
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
int num_bins = textureSize(histogram_tex, 0).x; // [0, 255]
|
||
|
|
||
|
uint sum = 0u;
|
||
|
uint total_pixels = 0u;
|
||
|
|
||
|
// Calculate the mean of the luminance histogram.
|
||
|
// We start indexing at 1 to ignore the first bin, which contains the
|
||
|
// luminance values that are lower than our threshold.
|
||
|
for (int i = 1; i < num_bins; ++i) {
|
||
|
uint hits = texelFetch(histogram_tex, ivec2(i, 0), 0).r;
|
||
|
sum += uint(i) * hits;
|
||
|
total_pixels += hits;
|
||
|
}
|
||
|
|
||
|
float mean = float(sum) / max(float(total_pixels), 1.0) - 1.0;
|
||
|
|
||
|
// Transform the bin index [1, 255] to an actual luminance value
|
||
|
float average_lum = bin_index_to_luminance(mean);
|
||
|
|
||
|
// Simulate smooth eye adaptation over time
|
||
|
float prev_lum = texelFetch(prev_lum_tex, ivec2(0), 0).r;
|
||
|
float adapted_lum = prev_lum + (average_lum - prev_lum) *
|
||
|
(1.0 - exp(-osg_DeltaFrameTime * TAU));
|
||
|
|
||
|
fragLuminance = adapted_lum;
|
||
|
}
|