#version 330 core float luminance(vec3 color) { return dot(color, vec3(0.2126, 0.7152, 0.0722)); } out vec4 FragColor; in vec2 TexCoord; uniform sampler2D InputTexture; uniform float clarityValue; // -100 (blur) to 100 (sharpen) // Simple Box Blur (approximates Gaussian for unsharp mask) vec3 boxBlur(sampler2D tex, vec2 uv, vec2 texelSize, int radius) { vec3 blurred = vec3(0.0); float weightSum = 0.0; float r = float(radius); for (int x = -radius; x <= radius; ++x) { for (int y = -radius; y <= radius; ++y) { // Optional: Use Gaussian weights instead of box for better quality blur // float weight = exp(-(float(x*x + y*y)) / (2.0 * r*r)); float weight = 1.0; // Box weight blurred += texture(tex, uv + vec2(x, y) * texelSize).rgb * weight; weightSum += weight; } } return blurred / weightSum; } // Apply Clarity using Unsharp Masking vec3 applyClarity(vec3 originalColor, vec2 uv, float clarity) { if (abs(clarity) < 0.01) return originalColor; // No change vec2 texelSize = 1.0 / textureSize(InputTexture, 0); // Clarity targets mid-frequencies, use a moderate blur radius int blurRadius = 2; // Adjust radius for desired frequency range (1-3 typical) // 1. Create a blurred version (low-pass filter) vec3 blurredColor = boxBlur(InputTexture, uv, texelSize, blurRadius); // 2. Calculate the high-pass detail (Original - Blurred) vec3 highPassDetail = originalColor - blurredColor; // 3. Add the scaled detail back to the original // Map clarity -100..100 to a strength factor, e.g., 0..2 float strength = clarity / 100.0; // Map to -1..1 vec3 clarifiedColor = originalColor + highPassDetail * strength; return clarifiedColor; } void main() { vec4 color = texture(InputTexture, TexCoord); color.rgb = applyClarity(color.rgb, TexCoord, clarityValue); FragColor = vec4(max(color.rgb, vec3(0.0)), color.a); }