diff --git a/.config/hypr/shaders/01_red_tint.glsl b/.config/hypr/shaders/01_red_tint.glsl new file mode 100755 index 0000000..ea9f8c0 --- /dev/null +++ b/.config/hypr/shaders/01_red_tint.glsl @@ -0,0 +1,16 @@ +#version 300 es +// Pure Red Channel Shader - OPTIMIZED +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// Using Rec. 709 for consistency +const vec3 LUMA = vec3(0.2126, 0.7152, 0.0722); + +void main() { + vec4 pixColor = texture(tex, v_texcoord); + float gray = dot(pixColor.rgb, LUMA); + fragColor = vec4(gray, 0.0, 0.0, pixColor.a); +} diff --git a/.config/hypr/shaders/02_green_tint.glsl b/.config/hypr/shaders/02_green_tint.glsl new file mode 100755 index 0000000..c978154 --- /dev/null +++ b/.config/hypr/shaders/02_green_tint.glsl @@ -0,0 +1,16 @@ +#version 300 es +// Pure Green Channel Shader - FIXED +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +const vec3 LUMA = vec3(0.2126, 0.7152, 0.0722); + +void main() { + vec4 pixColor = texture(tex, v_texcoord); + float gray = dot(pixColor.rgb, LUMA); + // FIXED: Now correctly outputs to GREEN channel + fragColor = vec4(0.0, gray, 0.0, pixColor.a); +} diff --git a/.config/hypr/shaders/03_blue_tint.glsl b/.config/hypr/shaders/03_blue_tint.glsl new file mode 100755 index 0000000..78c1527 --- /dev/null +++ b/.config/hypr/shaders/03_blue_tint.glsl @@ -0,0 +1,15 @@ +#version 300 es +// Pure Blue Channel Shader - OPTIMIZED +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +const vec3 LUMA = vec3(0.2126, 0.7152, 0.0722); + +void main() { + vec4 pixColor = texture(tex, v_texcoord); + float gray = dot(pixColor.rgb, LUMA); + fragColor = vec4(0.0, 0.0, gray, pixColor.a); +} diff --git a/.config/hypr/shaders/04_optics_compensate.glsl b/.config/hypr/shaders/04_optics_compensate.glsl new file mode 100755 index 0000000..ea426c5 --- /dev/null +++ b/.config/hypr/shaders/04_optics_compensate.glsl @@ -0,0 +1,72 @@ +#version 300 es +// Retro CRT Shader - FULLY OPTIMIZED +// Fixes: Resolution-aware scanlines, proper vignette, edge clamping, +// correct aberration direction, anti-aliased scanlines + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +const float CURVATURE = 3.5; +const float SCANLINE_STRENGTH = 0.25; +// Approximate screen height in pixels (adjust to your resolution) +const float SCREEN_HEIGHT = 1080.0; +// Scanlines per screen height (lower = thicker lines) +const float SCANLINE_COUNT = 540.0; +const float ABERRATION = 0.002; +const float VIGNETTE_RADIUS = 1.00; +const float VIGNETTE_SOFTNESS = 0.45; +// Phosphor glow simulation +const float GLOW = 0.03; + +vec2 curveUV(vec2 uv) { + uv = uv * 2.0 - 1.0; + vec2 offset = abs(uv.yx) / vec2(CURVATURE); + uv = uv + uv * offset * offset; + uv = uv * 0.5 + 0.5; + return uv; +} + +void main() { + vec2 uv = curveUV(v_texcoord); + + // Black bezel for out-of-bounds + if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { + fragColor = vec4(0.0, 0.0, 0.0, 1.0); + return; + } + + // FIXED: Clamp aberration samples to prevent edge artifacts + vec2 centerDist = uv - 0.5; + vec2 aberrOffset = centerDist * ABERRATION; + + // FIXED: Correct direction - red focuses short, blue focuses long + float r = texture(tex, clamp(uv + aberrOffset, 0.0, 1.0)).r; + float g = texture(tex, uv).g; + float b = texture(tex, clamp(uv - aberrOffset, 0.0, 1.0)).b; + vec3 color = vec3(r, g, b); + + // FIXED: Anti-aliased scanlines that don't shimmer during scroll + // Using smooth triangle wave instead of harsh sine + float scanlinePhase = uv.y * SCANLINE_COUNT * 2.0; + float scanline = abs(fract(scanlinePhase) - 0.5) * 2.0; // Triangle wave 0-1 + scanline = smoothstep(0.0, 1.0, scanline); // Smooth it + float scanlineFactor = 1.0 - (SCANLINE_STRENGTH * (1.0 - scanline)); + color *= scanlineFactor; + + // Subtle phosphor glow (brightens slightly between scanlines) + color += GLOW * (1.0 - scanline); + + // FIXED: Proper circular vignette with correct smoothstep bounds + float dist = length(centerDist) * 2.0; // 0 at center, ~1.414 at corners + float vignette = 1.0 - smoothstep(VIGNETTE_RADIUS, VIGNETTE_RADIUS + VIGNETTE_SOFTNESS, dist); + color *= vignette; + + // Subtle brightness boost to compensate for darkening effects + color *= 1.1; + + fragColor = vec4(clamp(color, 0.0, 1.0), 1.0); +} diff --git a/.config/hypr/shaders/05_sketch.glsl b/.config/hypr/shaders/05_sketch.glsl new file mode 100755 index 0000000..29ffff9 --- /dev/null +++ b/.config/hypr/shaders/05_sketch.glsl @@ -0,0 +1,89 @@ +#version 300 es +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +const float edge_threshold = 0.15; // Sensitivity (0.05-0.5) - lower = more edges +const float edge_softness = 0.08; // Anti-aliasing amount +const float line_thickness = 1.0; // 1.0 = normal, 2.0 = thicker +const float line_darkness = 0.05; // 0.0 = pure black, higher = lighter +const float paper_brightness = 0.98; // Paper color +const float paper_grain = 0.03; // Paper texture intensity +const float noise_reduction = 0.5; // Reduces speckles in smooth areas +// --------------------- + +float luminance(vec3 color) { + return dot(color, vec3(0.2126, 0.7152, 0.0722)); +} + +float hash12(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * 0.1031); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +} + +// Sample luminance with bounds checking +float sampleLum(vec2 uv) { + vec2 safe_uv = clamp(uv, 0.0, 1.0); + return luminance(texture(tex, safe_uv).rgb); +} + +void main() { + vec2 screen_res = vec2(textureSize(tex, 0)); + vec2 pixel_size = line_thickness / screen_res; + vec2 pixel_coords = v_texcoord * screen_res; + + // Sobel kernel sampling with proper edge clamping + float tl = sampleLum(v_texcoord + vec2(-pixel_size.x, -pixel_size.y)); + float t = sampleLum(v_texcoord + vec2( 0.0, -pixel_size.y)); + float tr = sampleLum(v_texcoord + vec2( pixel_size.x, -pixel_size.y)); + float l = sampleLum(v_texcoord + vec2(-pixel_size.x, 0.0)); + float c = sampleLum(v_texcoord); // Center pixel + float r = sampleLum(v_texcoord + vec2( pixel_size.x, 0.0)); + float bl = sampleLum(v_texcoord + vec2(-pixel_size.x, pixel_size.y)); + float b = sampleLum(v_texcoord + vec2( 0.0, pixel_size.y)); + float br = sampleLum(v_texcoord + vec2( pixel_size.x, pixel_size.y)); + + // Sobel operators + float Gx = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); + float Gy = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); + float gradient = sqrt(Gx * Gx + Gy * Gy); + + // Calculate local variance for noise reduction + // (reduces speckles in smooth areas while preserving real edges) + float mean = (tl + t + tr + l + c + r + bl + b + br) / 9.0; + float variance = 0.0; + variance += (tl - mean) * (tl - mean); + variance += (t - mean) * (t - mean); + variance += (tr - mean) * (tr - mean); + variance += (l - mean) * (l - mean); + variance += (c - mean) * (c - mean); + variance += (r - mean) * (r - mean); + variance += (bl - mean) * (bl - mean); + variance += (b - mean) * (b - mean); + variance += (br - mean) * (br - mean); + variance = sqrt(variance / 9.0); + + // Adaptive threshold: require stronger edges in noisy areas + float adaptive_threshold = edge_threshold + variance * noise_reduction; + + // Smooth edge detection (anti-aliased) + float edge = smoothstep( + adaptive_threshold - edge_softness, + adaptive_threshold + edge_softness, + gradient + ); + + // Paper texture + float paper = paper_brightness; + paper -= hash12(pixel_coords * 0.4) * paper_grain; + paper -= hash12(pixel_coords * 2.1) * paper_grain * 0.4; + + // Final blend + float final_value = mix(paper, line_darkness, edge); + + fragColor = vec4(vec3(final_value), 1.0); +} diff --git a/.config/hypr/shaders/06_wobble.glsl b/.config/hypr/shaders/06_wobble.glsl new file mode 100755 index 0000000..b016aa0 --- /dev/null +++ b/.config/hypr/shaders/06_wobble.glsl @@ -0,0 +1,72 @@ +#version 300 es +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +uniform float TIME; +out vec4 fragColor; + +// --- CONFIGURATION --- +const float wobble_speed = 3.0; // Animation speed +const float wobble_frequency = 15.0; // Wave density +const float wobble_amplitude = 0.025; // Displacement amount +const float edge_fade = 0.1; // Fade near edges (0.0 to disable) +const bool organic_motion = true; // Multi-frequency for natural look +const bool prevent_edge_artifacts = true; +// --------------------- + +void main() { + // Use local time to prevent floating point precision issues with large TIME values + float t = mod(TIME, 628.318); // Wrap at 2*PI*100 + + vec2 new_uv = v_texcoord; + + // Calculate edge fade mask (reduces artifacts at screen borders) + float edge_mask = 1.0; + if (edge_fade > 0.0) { + vec2 dist_to_edge = min(v_texcoord, 1.0 - v_texcoord); + float min_dist = min(dist_to_edge.x, dist_to_edge.y); + edge_mask = smoothstep(0.0, edge_fade, min_dist); + } + + float amplitude = wobble_amplitude * edge_mask; + + float h_offset, v_offset; + + if (organic_motion) { + // Layer multiple frequencies for organic, natural motion + // Different speeds prevent repetitive patterns + + // Horizontal wobble (based on Y position) + h_offset = 0.0; + h_offset += sin(v_texcoord.y * wobble_frequency * 1.0 + t * wobble_speed * 1.00) * 0.50; + h_offset += sin(v_texcoord.y * wobble_frequency * 2.1 + t * wobble_speed * 1.37) * 0.30; + h_offset += sin(v_texcoord.y * wobble_frequency * 0.5 + t * wobble_speed * 0.71) * 0.20; + + // Vertical wobble (based on X position) + v_offset = 0.0; + v_offset += cos(v_texcoord.x * wobble_frequency * 0.9 + t * wobble_speed * 1.13) * 0.50; + v_offset += cos(v_texcoord.x * wobble_frequency * 1.7 + t * wobble_speed * 0.83) * 0.30; + v_offset += cos(v_texcoord.x * wobble_frequency * 0.4 + t * wobble_speed * 1.41) * 0.20; + + // Add subtle interaction between axes + h_offset += sin(v_texcoord.x * wobble_frequency * 0.3 + t * wobble_speed * 0.5) * 0.1; + v_offset += cos(v_texcoord.y * wobble_frequency * 0.3 + t * wobble_speed * 0.6) * 0.1; + + } else { + // Simple single-frequency wobble + h_offset = sin(v_texcoord.y * wobble_frequency + t * wobble_speed); + v_offset = cos(v_texcoord.x * wobble_frequency + t * wobble_speed); + } + + new_uv.x += h_offset * amplitude; + new_uv.y += v_offset * amplitude; + + // Prevent sampling outside texture bounds + if (prevent_edge_artifacts) { + // Clamp with small margin to prevent edge bleeding + new_uv = clamp(new_uv, 0.002, 0.998); + } + + fragColor = texture(tex, new_uv); +} diff --git a/.config/hypr/shaders/07_chromatic_aberration.glsl b/.config/hypr/shaders/07_chromatic_aberration.glsl new file mode 100755 index 0000000..0f5da19 --- /dev/null +++ b/.config/hypr/shaders/07_chromatic_aberration.glsl @@ -0,0 +1,43 @@ +#version 300 es +// Chromatic Aberration Shader for Hyprland - OPTIMIZED +// Fixes: Edge clamping, aspect ratio correction, quadratic falloff + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +const float STRENGTH = 0.010; +// Set to your monitor's aspect ratio (16/9, 21/9, etc.) or use 1.0 for uncorrected +const float ASPECT_RATIO = 16.0 / 9.0; +// Use quadratic falloff for more realistic lens distortion +const bool QUADRATIC_FALLOFF = true; + +void main() { + // Aspect-corrected center distance + vec2 distFromCenter = v_texcoord - 0.5; + distFromCenter.x *= ASPECT_RATIO; + + // Calculate offset magnitude + float dist = length(distFromCenter); + float falloff = QUADRATIC_FALLOFF ? dist * dist : dist; + + // Normalize direction and apply strength + vec2 dir = normalize(distFromCenter + 0.0001); // Prevent div by zero + vec2 offset = dir * falloff * STRENGTH; + offset.x /= ASPECT_RATIO; // Correct back for sampling + + // Sample with clamped coordinates to prevent edge artifacts + vec2 redCoord = clamp(v_texcoord - offset, 0.0, 1.0); + vec2 blueCoord = clamp(v_texcoord + offset, 0.0, 1.0); + + float r = texture(tex, redCoord).r; + vec4 centerPixel = texture(tex, v_texcoord); + float g = centerPixel.g; + float b = texture(tex, blueCoord).b; + + // Preserve alpha from center sample + fragColor = vec4(r, g, b, centerPixel.a); +} diff --git a/.config/hypr/shaders/08_newspaper.glsl b/.config/hypr/shaders/08_newspaper.glsl new file mode 100755 index 0000000..168c677 --- /dev/null +++ b/.config/hypr/shaders/08_newspaper.glsl @@ -0,0 +1,114 @@ +#version 300 es +precision highp float; // CRITICAL: Prevents many artifacts + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +const float dot_spacing = 4.0; // 3.0-6.0 recommended +const int color_levels = 4; // Posterization levels +const vec3 paper_color = vec3(0.95, 0.92, 0.85); +const float paper_texture_strength = 0.04; +const float dot_softness = 1.5; // Higher = softer dot edges (anti-aliasing) +const float ink_darkness = 0.95; // How dark the ink appears (0.0-1.0) +const bool use_dithering = true; // Reduces posterization banding +// --------------------- + +// Improved hash function - less pattern artifacts than sin-based +float hash12(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * 0.1031); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +} + +// Smoother 2D noise for paper texture +float valueNoise(vec2 p) { + vec2 i = floor(p); + vec2 f = fract(p); + + // Smooth interpolation + vec2 u = f * f * (3.0 - 2.0 * f); + + float a = hash12(i); + float b = hash12(i + vec2(1.0, 0.0)); + float c = hash12(i + vec2(0.0, 1.0)); + float d = hash12(i + vec2(1.0, 1.0)); + + return mix(mix(a, b, u.x), mix(c, d, u.x), u.y); +} + +float luminance(vec3 color) { + return dot(color, vec3(0.2126, 0.7152, 0.0722)); +} + +// Bayer 4x4 dithering matrix - reduces posterization banding +float bayerDither(vec2 pos) { + ivec2 p = ivec2(mod(pos, 4.0)); + int index = p.x + p.y * 4; + + // Bayer matrix values + float matrix[16] = float[16]( + 0.0, 8.0, 2.0, 10.0, + 12.0, 4.0, 14.0, 6.0, + 3.0, 11.0, 1.0, 9.0, + 15.0, 7.0, 13.0, 5.0 + ); + + return (matrix[index] / 16.0) - 0.5; +} + +void main() { + vec2 screen_res = vec2(textureSize(tex, 0)); + vec2 pixel_coords = v_texcoord * screen_res; + + // 1. Sample original with clamped coordinates (prevents edge artifacts) + vec2 safe_uv = clamp(v_texcoord, 0.0, 1.0); + vec3 original_color = texture(tex, safe_uv).rgb; + + // 2. Posterize with optional dithering to reduce banding + float levels = float(color_levels); + vec3 posterized_color; + + if (use_dithering) { + // Add dither before quantization + float dither = bayerDither(pixel_coords) / (levels * 2.0); + posterized_color = floor((original_color + dither) * levels) / (levels - 1.0); + } else { + posterized_color = floor(original_color * levels) / (levels - 1.0); + } + posterized_color = clamp(posterized_color, 0.0, 1.0); + + // 3. Create layered paper texture (more natural looking) + float paper_noise = 0.0; + paper_noise += valueNoise(pixel_coords * 0.5) * 0.6; // Large grain + paper_noise += valueNoise(pixel_coords * 1.5) * 0.3; // Medium grain + paper_noise += hash12(pixel_coords) * 0.1; // Fine grain + paper_noise *= paper_texture_strength; + + vec3 textured_paper = max(paper_color - paper_noise, 0.0); // Prevent negative + + // 4. Create halftone grid + vec2 cell_coords = pixel_coords / dot_spacing; + vec2 grid_uv = fract(cell_coords); + + // 5. Calculate halftone dot + // Use sqrt for area-proportional dots (perceptually correct) + float lum = luminance(posterized_color); + float darkness = 1.0 - lum; + float dot_radius = sqrt(darkness) * 0.5; // Area proportional to darkness + + // Distance from cell center + float dist = length(grid_uv - 0.5); + + // Anti-aliased dot edge using screen-space derivatives + // This adapts to any resolution automatically + float pixel_width = fwidth(dist) * dot_softness; + float dot_mask = smoothstep(dot_radius - pixel_width, dot_radius + pixel_width, dist); + + // 6. Combine: ink color where dots are, paper elsewhere + vec3 ink_color = posterized_color * ink_darkness; + vec3 final_color = mix(ink_color, textured_paper, dot_mask); + + fragColor = vec4(final_color, 1.0); +} diff --git a/.config/hypr/shaders/09_pixelated.glsl b/.config/hypr/shaders/09_pixelated.glsl new file mode 100755 index 0000000..7425135 --- /dev/null +++ b/.config/hypr/shaders/09_pixelated.glsl @@ -0,0 +1,28 @@ +#version 300 es +// Pixelation Shader - OPTIMIZED +// Fixes: Sample from pixel CENTER (not corner), aspect ratio support + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +// Pixels across the shorter dimension (height usually) +const float PIXEL_COUNT = 350.0; +// Set to your aspect ratio, or 1.0 for square pixels +const float ASPECT_RATIO = 16.0 / 9.0; + +void main() { + // Calculate pixel dimensions accounting for aspect ratio + vec2 pixelCount = vec2(PIXEL_COUNT * ASPECT_RATIO, PIXEL_COUNT); + vec2 pixelSize = 1.0 / pixelCount; + + // FIXED: Sample from pixel CENTER, not corner + // This prevents the "swimming" artifact when content moves + vec2 pixelCoord = floor(v_texcoord * pixelCount) + 0.5; + vec2 sampleCoord = pixelCoord / pixelCount; + + fragColor = texture(tex, sampleCoord); +} diff --git a/.config/hypr/shaders/10_grayscale.glsl b/.config/hypr/shaders/10_grayscale.glsl new file mode 100755 index 0000000..f80900e --- /dev/null +++ b/.config/hypr/shaders/10_grayscale.glsl @@ -0,0 +1,40 @@ +#version 300 es +// Grayscale Shader for Hyprland - OPTIMIZED +// Added: Optional gamma-correct conversion for accurate luminance + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// Rec. 709 Luma coefficients (sRGB/HDTV standard) +const vec3 LUMA_709 = vec3(0.2126, 0.7152, 0.0722); + +// Set to true for gamma-correct grayscale (more accurate but slightly slower) +const bool GAMMA_CORRECT = false; + +// sRGB gamma functions +float toLinear(float c) { + return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4); +} +float toSRGB(float c) { + return c <= 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0/2.4) - 0.055; +} + +void main() { + vec4 pixColor = texture(tex, v_texcoord); + + float gray; + if (GAMMA_CORRECT) { + // Convert to linear space, compute luminance, convert back + vec3 linear = vec3(toLinear(pixColor.r), toLinear(pixColor.g), toLinear(pixColor.b)); + float luminance = dot(linear, LUMA_709); + gray = toSRGB(luminance); + } else { + // Fast path: direct computation in gamma space + gray = dot(pixColor.rgb, LUMA_709); + } + + fragColor = vec4(vec3(gray), pixColor.a); +} diff --git a/.config/hypr/shaders/11_invert.glsl b/.config/hypr/shaders/11_invert.glsl new file mode 100755 index 0000000..307b45d --- /dev/null +++ b/.config/hypr/shaders/11_invert.glsl @@ -0,0 +1,30 @@ +#version 300 es +// Invert Colors Shader - OPTIMIZED +// Added: Optional luminance-preserving mode + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// Set true for "smart invert" that preserves relative brightness +const bool PRESERVE_LUMINANCE = false; +const vec3 LUMA = vec3(0.2126, 0.7152, 0.0722); + +void main() { + vec4 color = texture(tex, v_texcoord); + vec3 inverted = 1.0 - color.rgb; + + if (PRESERVE_LUMINANCE) { + // Adjust inverted colors to match original luminance + float origLuma = dot(color.rgb, LUMA); + float invLuma = dot(inverted, LUMA); + if (invLuma > 0.001) { + inverted *= origLuma / invLuma; + inverted = clamp(inverted, 0.0, 1.0); + } + } + + fragColor = vec4(inverted, color.a); +} diff --git a/.config/hypr/shaders/12_posterization.glsl b/.config/hypr/shaders/12_posterization.glsl new file mode 100755 index 0000000..e2391e2 --- /dev/null +++ b/.config/hypr/shaders/12_posterization.glsl @@ -0,0 +1,39 @@ +#version 300 es +// Posterization Shader - OPTIMIZED +// Fixes: Proper rounding, optional dithering to reduce banding + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +const float COLOR_LEVELS = 4.0; +// Enable dithering to reduce visible banding +const bool DITHER = true; + +// Simple dither pattern +float dither(vec2 pos) { + // 4x4 Bayer matrix approximation + vec2 p = fract(pos * 0.5); + float d = fract(dot(p, vec2(0.75, 0.5))); + return (d - 0.5) / COLOR_LEVELS; +} + +void main() { + vec4 color = texture(tex, v_texcoord); + + vec3 posterized; + if (DITHER) { + // Add dither noise before quantization + float ditherValue = dither(gl_FragCoord.xy); + posterized = floor((color.rgb + ditherValue) * COLOR_LEVELS + 0.5) / COLOR_LEVELS; + } else { + // FIXED: Use round() behavior instead of floor() for better color accuracy + posterized = floor(color.rgb * COLOR_LEVELS + 0.5) / COLOR_LEVELS; + } + + posterized = clamp(posterized, 0.0, 1.0); + fragColor = vec4(posterized, color.a); +} diff --git a/.config/hypr/shaders/13_sepia.glsl b/.config/hypr/shaders/13_sepia.glsl new file mode 100755 index 0000000..fcd451a --- /dev/null +++ b/.config/hypr/shaders/13_sepia.glsl @@ -0,0 +1,33 @@ +#version 300 es +// Sepia Tone Shader - OPTIMIZED +// Fixes: Clamping to prevent overflow on bright pixels + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// W3C standard Sepia Matrix (column-major for GLSL) +const mat3 SEPIA_MATRIX = mat3( + 0.393, 0.769, 0.189, // Red output weights + 0.349, 0.686, 0.168, // Green output weights + 0.272, 0.534, 0.131 // Blue output weights +); + +// Sepia intensity (0.0 = no effect, 1.0 = full sepia) +const float INTENSITY = 1.0; + +void main() { + vec4 color = texture(tex, v_texcoord); + + vec3 sepia = color.rgb * SEPIA_MATRIX; + + // FIXED: Clamp to prevent overflow artifacts on bright pixels + sepia = clamp(sepia, 0.0, 1.0); + + // Optional: blend with original for partial effect + vec3 final = mix(color.rgb, sepia, INTENSITY); + + fragColor = vec4(final, color.a); +} diff --git a/.config/hypr/shaders/14_vibrance.glsl b/.config/hypr/shaders/14_vibrance.glsl new file mode 100755 index 0000000..e0a8350 --- /dev/null +++ b/.config/hypr/shaders/14_vibrance.glsl @@ -0,0 +1,37 @@ +#version 300 es +// Vignette Shader - OPTIMIZED +// Fixes: Aspect ratio correction for circular vignette, safe smoothstep bounds + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +const float RADIUS = 0.65; +const float SOFTNESS = 0.45; +const float STRENGTH = 0.5; +// Set to your monitor's aspect ratio for circular vignette +const float ASPECT_RATIO = 16.0 / 9.0; + +void main() { + vec4 color = texture(tex, v_texcoord); + + // FIXED: Aspect-corrected distance for circular (not elliptical) vignette + vec2 centered = v_texcoord - 0.5; + centered.x *= ASPECT_RATIO; + float dist = length(centered); + // Normalize so corner distance is ~1.0 regardless of aspect ratio + dist /= length(vec2(ASPECT_RATIO * 0.5, 0.5)); + + // FIXED: Ensure smoothstep has valid bounds (edge1 > edge0) + float innerEdge = RADIUS; + float outerEdge = RADIUS + SOFTNESS; + float vignette = 1.0 - smoothstep(innerEdge, outerEdge, dist); + + // Apply with strength control + color.rgb = mix(color.rgb, color.rgb * vignette, STRENGTH); + + fragColor = color; +} diff --git a/.config/hypr/shaders/15_anaglyph_3d.glsl b/.config/hypr/shaders/15_anaglyph_3d.glsl new file mode 100755 index 0000000..8294e31 --- /dev/null +++ b/.config/hypr/shaders/15_anaglyph_3d.glsl @@ -0,0 +1,35 @@ +#version 300 es +// Anaglyph 3D Shader - OPTIMIZED +// Fixes: Edge clamping, alpha preservation, depth-aware separation + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +const float SEPARATION = 0.003; +// Make separation stronger at edges (simulates depth from screen curvature) +const bool DEPTH_AWARE = true; + +void main() { + vec2 offset = vec2(SEPARATION, 0.0); + + // Optional: Increase separation toward screen edges for more depth + if (DEPTH_AWARE) { + float edgeFactor = abs(v_texcoord.x - 0.5) * 2.0; // 0 at center, 1 at edges + offset.x *= 1.0 + edgeFactor * 0.5; + } + + // Clamp coordinates to prevent edge sampling artifacts + vec2 leftCoord = clamp(v_texcoord - offset, 0.0, 1.0); + vec2 rightCoord = clamp(v_texcoord + offset, 0.0, 1.0); + + vec4 leftEye = texture(tex, leftCoord); + vec4 rightEye = texture(tex, rightCoord); + vec4 center = texture(tex, v_texcoord); + + // Combine: Red from left, Cyan (GB) from right + fragColor = vec4(leftEye.r, rightEye.g, rightEye.b, center.a); +} diff --git a/.config/hypr/shaders/16_vignette.glsl b/.config/hypr/shaders/16_vignette.glsl new file mode 100755 index 0000000..efd838d --- /dev/null +++ b/.config/hypr/shaders/16_vignette.glsl @@ -0,0 +1,37 @@ +#version 300 es +// Vignette Shader for Hyprland +// Description: Darkens the edges of the screen to draw focus to the center. +// Uses smoothstep for a high-quality, organic falloff. + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +// The radius where the darkening begins (0.0 is center, 0.8 is near corners) +const float RADIUS = 0.85; +// How soft the transition is (higher = smoother gradient) +const float SOFTNESS = 0.85; +// The strength of the darkness (0.0 = no vignette, 1.0 = pitch black corners) +const float STRENGTH = 0.8; + +void main() { + // 1. Sample the original screen color + vec4 color = texture(tex, v_texcoord); + + // 2. Calculate distance from center (0.5, 0.5) + float dist = distance(v_texcoord, vec2(0.5)); + + // 3. Calculate vignette factor using smoothstep for high-quality falloff + // We invert the smoothstep range so 1.0 is center and 0.0 is edges + float vignette = smoothstep(RADIUS, RADIUS - SOFTNESS, dist); + + // 4. Apply the vignette strength + // Mix between the original color and the darkened version + // This allows us to control intensity without changing the geometry of the falloff + color.rgb = mix(color.rgb, color.rgb * vignette, STRENGTH); + + fragColor = color; +} diff --git a/.config/hypr/shaders/vibrance.glsl b/.config/hypr/shaders/vibrance.glsl new file mode 100644 index 0000000..7b38230 --- /dev/null +++ b/.config/hypr/shaders/vibrance.glsl @@ -0,0 +1,40 @@ +#version 300 es +// Saturation & Contrast Shader for Hyprland +// Description: Allows fine-tuning of screen vibrancy and dynamic range. +// Efficiently applies saturation followed by contrast. + +precision highp float; + +in vec2 v_texcoord; +uniform sampler2D tex; +out vec4 fragColor; + +// --- CONFIGURATION --- +// 0.0 = Grayscale, 1.0 = Normal, 1.5 = Vibrant, 2.0 = Deep Fried +const float SATURATION = 3.0; + +// 1.0 = Normal, 1.2 = High Contrast, 0.8 = Low Contrast (Faded) +const float CONTRAST = 1.0; +// --------------------- + +// Rec. 709 Luma coefficients for accurate saturation calculations +const vec3 luma = vec3(0.2126, 0.7152, 0.0722); + +void main() { + // 1. Sample texture + vec4 color = texture(tex, v_texcoord); + + // 2. Apply Saturation + // Calculate the grayscale value (luminance) + float gray = dot(color.rgb, luma); + // Interpolate between grayscale and original color + vec3 satColor = mix(vec3(gray), color.rgb, SATURATION); + + // 3. Apply Contrast + // We shift color values so 0.5 is the "pivot" point. + // Values > 0.5 get pushed up, values < 0.5 get pushed down. + vec3 finalColor = (satColor - 0.5) * CONTRAST + 0.5; + + // 4. Output + fragColor = vec4(finalColor, color.a); +} diff --git a/.config/hypr/source/keybinds.conf b/.config/hypr/source/keybinds.conf index 9168804..431c8d2 100644 --- a/.config/hypr/source/keybinds.conf +++ b/.config/hypr/source/keybinds.conf @@ -76,18 +76,24 @@ bind = $mainMod SHIFT, S, movetoworkspace, special:magic workspace = special:h, on-created-empty: $terminal bind = $mainMod SHIFT, Return, togglespecialworkspace, h -# Screen Rotate -bindld = CTRL ALT, R, Rotate Screen Clockwise, exec, hypr_screen_rotate.sh -90 -bindld = CTRL ALT SHIFT, R, Rotate Screen Anti-Clockwise, exec, hypr_screen_rotate.sh +90 # Accessibility: Zoom cursor:zoom_disable_aa = true # Zoom In -binded = SUPER SHIFT, equal, Zoom In, exec, sh -c "hyprctl keyword cursor:zoom_factor \"$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {print $2 * 1.25}')\"" +binded = SUPER, equal, Zoom In, exec, sh -c "hyprctl keyword cursor:zoom_factor \"$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {print $2 * 1.25}')\"" # Zoom Out -binded = SUPER SHIFT, minus, Zoom Out, exec, sh -c "hyprctl keyword cursor:zoom_factor \"$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {val = $2 / 1.25; if (val < 1.0) val = 1.0; print val}')\"" +binded = SUPER, minus, Zoom Out, exec, sh -c "hyprctl keyword cursor:zoom_factor \"$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {val = $2 / 1.25; if (val < 1.0) val = 1.0; print val}')\"" # Reset Zoom -bindld = SUPER SHIFT, BACKSPACE, Reset Zoom, exec, hyprctl keyword cursor:zoom_factor 1.0 +bindld = SUPER, BACKSPACE, Reset Zoom, exec, hyprctl keyword cursor:zoom_factor 1.0 + +# Screen Rotate +bindld = $mainMod CTRL, comma, Rotate Screen Anti-Clockwise, exec, hypr_screen_rotate.sh +90 +bindld = $mainMod CTRL, period, Rotate Screen Clockwise, exec, hypr_screen_rotate.sh -90 + +# --- Hyprshade (Visual Filters) --- +bindd = $mainMod CTRL, S, Shader Menu, exec, hypr_shader_menu.sh +bindld = $mainMod CTRL, X, Disable Shader, exec, hyprshade off +bindld = $mainMod CTRL, V, Vibrant Shader, exec, hyprshade on vibrance # Scroll through existing workspaces with mainMod + scroll bind = $mainMod, mouse_down, workspace, e+1 diff --git a/.config/waybar/config.jsonc b/.config/waybar/config.jsonc index 2c60193..b96c229 100644 --- a/.config/waybar/config.jsonc +++ b/.config/waybar/config.jsonc @@ -107,6 +107,7 @@ "format-alt": "{icon} ", "format-good": "{icon} {capacity:3}%", "format-full": "{icon} {capacity:3}%", + "tooltip-format": "{timeTo}\nHealth: {health}%\nPower Draw: {power:.2f} W\nCycles: {cycles}\n\nLMB: Toggle Format\nRMB: Timeout Settings", "format-icons": [ "", "", diff --git a/.local/bin/hypr/hypr_shader_menu.sh b/.local/bin/hypr/hypr_shader_menu.sh new file mode 100755 index 0000000..bfeb46a --- /dev/null +++ b/.local/bin/hypr/hypr_shader_menu.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Check deps +command -v fuzzel >/dev/null || { echo "fuzzel not found"; exit 1; } +command -v hyprshade >/dev/null || { echo "hyprshade not found"; exit 1; } + +# Get shader list +mapfile -t SHADERS < <(hyprshade ls) + +# Add "off" at top +SHADERS=("off" "${SHADERS[@]}") + +# Show in fuzzel +CHOICE=$(printf "%s\n" "${SHADERS[@]}" \ + | fuzzel --dmenu --prompt "Hyprshade > " \ + | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + +# User cancelled +[[ -z "$CHOICE" ]] && exit 0 + +# Apply +if [[ "$CHOICE" == "off" ]]; then + hyprshade off +else + hyprshade on "$CHOICE" +fi + +# Optional notification +command -v notify-send >/dev/null && notify-send "Hyprshade" "Applied: $CHOICE" +