| 1 | #version 300 es |
| 2 | // Grayscale Shader for Hyprland - OPTIMIZED |
| 3 | // Added: Optional gamma-correct conversion for accurate luminance |
| 4 | |
| 5 | precision highp float; |
| 6 | |
| 7 | in vec2 v_texcoord; |
| 8 | uniform sampler2D tex; |
| 9 | out vec4 fragColor; |
| 10 | |
| 11 | // Rec. 709 Luma coefficients (sRGB/HDTV standard) |
| 12 | const vec3 LUMA_709 = vec3(0.2126, 0.7152, 0.0722); |
| 13 | |
| 14 | // Set to true for gamma-correct grayscale (more accurate but slightly slower) |
| 15 | const bool GAMMA_CORRECT = false; |
| 16 | |
| 17 | // sRGB gamma functions |
| 18 | float toLinear(float c) { |
| 19 | return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4); |
| 20 | } |
| 21 | float toSRGB(float c) { |
| 22 | return c <= 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0/2.4) - 0.055; |
| 23 | } |
| 24 | |
| 25 | void main() { |
| 26 | vec4 pixColor = texture(tex, v_texcoord); |
| 27 | |
| 28 | float gray; |
| 29 | if (GAMMA_CORRECT) { |
| 30 | // Convert to linear space, compute luminance, convert back |
| 31 | vec3 linear = vec3(toLinear(pixColor.r), toLinear(pixColor.g), toLinear(pixColor.b)); |
| 32 | float luminance = dot(linear, LUMA_709); |
| 33 | gray = toSRGB(luminance); |
| 34 | } else { |
| 35 | // Fast path: direct computation in gamma space |
| 36 | gray = dot(pixColor.rgb, LUMA_709); |
| 37 | } |
| 38 | |
| 39 | fragColor = vec4(vec3(gray), pixColor.a); |
| 40 | } |