tedit/shaders/highlights_shadows.frag
2025-04-07 20:08:16 -04:00

66 lines
2.4 KiB
GLSL

#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D InputTexture;
uniform float highlightsValue; // -100 to 100
uniform float shadowsValue; // -100 to 100
// More accurate perceptual luminance (Rec. 709)
float luminance(vec3 color) {
return dot(color, vec3(0.2126, 0.7152, 0.0722));
}
// Smoothstep with better performance than quintic
float smootherStep(float edge0, float edge1, float x) {
float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
}
vec3 applyHighlightsShadows(vec3 color) {
float lum = luminance(color);
// Define threshold values similar to Lightroom
float shadowThreshold = 0.3;
float highlightThreshold = 0.7;
// Calculate adjustment weights with smoother falloff
float shadowWeight = 1.0 - smootherStep(0.0, shadowThreshold * 2.0, lum);
float highlightWeight = smootherStep(highlightThreshold, 1.0, lum);
// Calculate adaptive adjustment factors
float shadowFactor = shadowsValue > 0.0 ?
mix(1.0, 1.0 + (shadowsValue / 100.0), shadowWeight) :
mix(1.0, 1.0 + (shadowsValue / 150.0), shadowWeight);
float highlightFactor = highlightsValue > 0.0 ?
mix(1.0, 1.0 - (highlightsValue / 150.0), highlightWeight) :
mix(1.0, 1.0 - (highlightsValue / 100.0), highlightWeight);
// Apply adjustments while preserving colors
vec3 adjusted = color * shadowFactor * highlightFactor;
// Preserve some saturation characteristics like Lightroom
float newLum = luminance(adjusted);
float saturationFactor = 1.0;
// Boost saturation slightly when lifting shadows (like Lightroom)
// if (shadowsValue > 0.0 && lum < shadowThreshold) {
// saturationFactor = 1.0 + (shadowsValue / 300.0) * (1.0 - lum / shadowThreshold);
// }
// Reduce saturation slightly when recovering highlights (like Lightroom)
if (highlightsValue > 0.0 && lum > highlightThreshold) {
saturationFactor *= 1.0 - (highlightsValue / 400.0) * ((lum - highlightThreshold) / (1.0 - highlightThreshold));
}
// Apply saturation adjustment while preserving luminance
return mix(vec3(newLum), adjusted, saturationFactor);
}
void main() {
vec4 color = texture(InputTexture, TexCoord);
color.rgb = applyHighlightsShadows(color.rgb);
FragColor = vec4(clamp(color.rgb, 0.0, 1.0), color.a);
}