66 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			GLSL
		
	
	
	
	
	
			
		
		
	
	
			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);
 | |
| } |