Files

54 lines
1.5 KiB
GLSL

// MinecraftPT — Exposure_CS
// Computes the average scene luminance and smooths the exposure over time.
// Writes the result into a 1x1 R16F image (exposureTex) read by the final pass.
#include "/Lib/Settings.glsl"
#include "/Lib/Utilities.glsl"
const ivec3 workGroups = ivec3(8, 8, 1);
layout (local_size_x = 16, local_size_y = 16) in;
layout (r16f) uniform writeonly image2D img_exposureTex;
uniform sampler2D colortex12;
shared float luminanceSum[256];
void main(){
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
// Downsample luminance from the HDR scene
float lum = 0.0;
vec2 base = vec2(texel * 4);
for (int i = 0; i < 4; i++){
for (int j = 0; j < 4; j++){
vec3 color = texelFetch(colortex12, ivec2(base + vec2(i, j)), 0).rgb;
lum += luminance(color);
}}
lum /= 16.0;
// Shared reduction
uint local = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 16u;
luminanceSum[local] = lum;
barrier();
if (local == 0u){
float avg = 0.0;
for (uint i = 0u; i < 256u; i++){
avg += luminanceSum[i];
}
avg /= 256.0;
// Target exposure (inverse of average luminance)
float targetExposure = 1.0 / max(avg, 0.001);
// Read previous exposure for temporal smoothing (single thread)
float prevExposure = imageLoad(img_exposureTex, ivec2(0, 0)).r;
if (prevExposure <= 0.0) prevExposure = 1.0;
float adapted = mix(prevExposure, targetExposure, SMOOTH_EXPOSURE);
adapted = clamp(adapted, 0.01, 100.0);
imageStore(img_exposureTex, ivec2(0, 0), vec4(adapted));
}
}