44 lines
1.3 KiB
GLSL
44 lines
1.3 KiB
GLSL
#version 330 core
|
|
out vec4 FragColor;
|
|
in vec2 TexCoord;
|
|
|
|
uniform sampler2D InputTexture;
|
|
uniform float exposureValue; // Expecting value in stops, e.g., -5.0 to 5.0
|
|
|
|
// Calculate perceptual luminance
|
|
float luminance(vec3 color) {
|
|
return dot(color, vec3(0.2126, 0.7152, 0.0722));
|
|
}
|
|
|
|
// Apply exposure by adjusting luminance while preserving color relationships
|
|
vec3 applyExposure(vec3 color, float exposureStops) {
|
|
// Get original luminance
|
|
float lum = luminance(color);
|
|
|
|
// Skip processing for very dark pixels to avoid division by zero
|
|
if (lum < 0.0001) return color;
|
|
|
|
// Calculate exposure factor
|
|
float exposureFactor = pow(2.0, exposureStops);
|
|
|
|
// Apply highlight compression when increasing exposure
|
|
float newLum = lum * exposureFactor;
|
|
if (exposureStops > 0.0 && newLum > 0.8) {
|
|
// Soft highlight roll-off to prevent harsh clipping
|
|
float excess = newLum - 0.8;
|
|
newLum = 0.8 + 0.2 * (1.0 - exp(-excess * 5.0));
|
|
}
|
|
|
|
// Scale RGB proportionally to maintain color relationships
|
|
return color * (newLum / lum);
|
|
}
|
|
|
|
void main() {
|
|
vec4 color = texture(InputTexture, TexCoord);
|
|
|
|
// Apply exposure adjustment
|
|
color.rgb = applyExposure(color.rgb, exposureValue);
|
|
|
|
// Ensure output is in valid range
|
|
FragColor = vec4(clamp(color.rgb, vec3(0.0), vec3(1.0)), color.a);
|
|
} |