| 1 | #version 300 es |
| 2 | // Chromatic Aberration Shader for Hyprland - OPTIMIZED |
| 3 | // Fixes: Edge clamping, aspect ratio correction, quadratic falloff |
| 4 | |
| 5 | precision highp float; |
| 6 | |
| 7 | in vec2 v_texcoord; |
| 8 | uniform sampler2D tex; |
| 9 | out vec4 fragColor; |
| 10 | |
| 11 | // --- CONFIGURATION --- |
| 12 | const float STRENGTH = 0.010; |
| 13 | // Set to your monitor's aspect ratio (16/9, 21/9, etc.) or use 1.0 for uncorrected |
| 14 | const float ASPECT_RATIO = 16.0 / 9.0; |
| 15 | // Use quadratic falloff for more realistic lens distortion |
| 16 | const bool QUADRATIC_FALLOFF = true; |
| 17 | |
| 18 | void main() { |
| 19 | // Aspect-corrected center distance |
| 20 | vec2 distFromCenter = v_texcoord - 0.5; |
| 21 | distFromCenter.x *= ASPECT_RATIO; |
| 22 | |
| 23 | // Calculate offset magnitude |
| 24 | float dist = length(distFromCenter); |
| 25 | float falloff = QUADRATIC_FALLOFF ? dist * dist : dist; |
| 26 | |
| 27 | // Normalize direction and apply strength |
| 28 | vec2 dir = normalize(distFromCenter + 0.0001); // Prevent div by zero |
| 29 | vec2 offset = dir * falloff * STRENGTH; |
| 30 | offset.x /= ASPECT_RATIO; // Correct back for sampling |
| 31 | |
| 32 | // Sample with clamped coordinates to prevent edge artifacts |
| 33 | vec2 redCoord = clamp(v_texcoord - offset, 0.0, 1.0); |
| 34 | vec2 blueCoord = clamp(v_texcoord + offset, 0.0, 1.0); |
| 35 | |
| 36 | float r = texture(tex, redCoord).r; |
| 37 | vec4 centerPixel = texture(tex, v_texcoord); |
| 38 | float g = centerPixel.g; |
| 39 | float b = texture(tex, blueCoord).b; |
| 40 | |
| 41 | // Preserve alpha from center sample |
| 42 | fragColor = vec4(r, g, b, centerPixel.a); |
| 43 | } |