| 1 | #version 300 es |
| 2 | // Saturation & Contrast Shader for Hyprland |
| 3 | // Description: Allows fine-tuning of screen vibrancy and dynamic range. |
| 4 | // Efficiently applies saturation followed by contrast. |
| 5 | |
| 6 | precision highp float; |
| 7 | |
| 8 | in vec2 v_texcoord; |
| 9 | uniform sampler2D tex; |
| 10 | out vec4 fragColor; |
| 11 | |
| 12 | // --- CONFIGURATION --- |
| 13 | // 0.0 = Grayscale, 1.0 = Normal, 1.5 = Vibrant, 2.0 = Deep Fried |
| 14 | const float SATURATION = 3.0; |
| 15 | |
| 16 | // 1.0 = Normal, 1.2 = High Contrast, 0.8 = Low Contrast (Faded) |
| 17 | const float CONTRAST = 1.0; |
| 18 | // --------------------- |
| 19 | |
| 20 | // Rec. 709 Luma coefficients for accurate saturation calculations |
| 21 | const vec3 luma = vec3(0.2126, 0.7152, 0.0722); |
| 22 | |
| 23 | void main() { |
| 24 | // 1. Sample texture |
| 25 | vec4 color = texture(tex, v_texcoord); |
| 26 | |
| 27 | // 2. Apply Saturation |
| 28 | // Calculate the grayscale value (luminance) |
| 29 | float gray = dot(color.rgb, luma); |
| 30 | // Interpolate between grayscale and original color |
| 31 | vec3 satColor = mix(vec3(gray), color.rgb, SATURATION); |
| 32 | |
| 33 | // 3. Apply Contrast |
| 34 | // We shift color values so 0.5 is the "pivot" point. |
| 35 | // Values > 0.5 get pushed up, values < 0.5 get pushed down. |
| 36 | vec3 finalColor = (satColor - 0.5) * CONTRAST + 0.5; |
| 37 | |
| 38 | // 4. Output |
| 39 | fragColor = vec4(finalColor, color.a); |
| 40 | } |