#version 330 core 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; 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; }