~kris/dots

srice

srice/.config/picom/shaders/technicolor.glsl -rw-r--r-- 2.1 KiB
e98f3b03 — Kris Yotam chore: sync local state after restore (push updates, no pull) a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#version 330

/*
   Technicolor 3-Strip (1930s-1960s) — picom shader
   Golden Age Hollywood dye-transfer look.
   Hyper-saturated primaries, warm tones, lifted blacks, gentle highlight rolloff.
*/

in vec2 texcoord;
uniform sampler2D tex;

const vec3 LUMA = vec3(0.2126, 0.7152, 0.0722);

float hash(vec2 p) {
    vec3 p3 = fract(vec3(p.xyx) * .1031);
    p3 += dot(p3, p3.yzx + 33.33);
    return fract((p3.x + p3.y) * p3.z);
}

float vignette(vec2 uv) {
    vec2 d = uv - 0.5;
    float dist = length(d);
    return 1.0 - smoothstep(0.35, 1.1, dist) * 0.20;
}

vec4 window_shader() {
    vec2 texsize = textureSize(tex, 0);
    vec4 pixColor = texture2D(tex, texcoord / texsize, 0);
    vec3 color = pixColor.rgb;

    // Technicolor cross-channel color matrix
    // Boosts primary separation, adds warm cross-channel bleed
    mat3 tcMatrix = mat3(
        1.30, -0.10, -0.05,
       -0.05,  1.25, -0.05,
       -0.08, -0.08,  1.35
    );
    color = tcMatrix * color;

    // Warm hue rotation
    float angle = 0.02;
    float cosA = cos(angle);
    float sinA = sin(angle);
    float r3 = 0.57735;
    mat3 hueRot = mat3(
        cosA + (1.0 - cosA) / 3.0,       (1.0 - cosA) / 3.0 - r3 * sinA, (1.0 - cosA) / 3.0 + r3 * sinA,
        (1.0 - cosA) / 3.0 + r3 * sinA,  cosA + (1.0 - cosA) / 3.0,      (1.0 - cosA) / 3.0 - r3 * sinA,
        (1.0 - cosA) / 3.0 - r3 * sinA,  (1.0 - cosA) / 3.0 + r3 * sinA, cosA + (1.0 - cosA) / 3.0
    );
    color = hueRot * color;

    // Saturation boost ~1.5x
    float luma = dot(color, LUMA);
    color = mix(vec3(luma), color, 1.5);

    // Lift blacks (dye transfer Dmin)
    color = max(color, vec3(0.03));

    // Gentle highlight rolloff
    color = mix(color, smoothstep(0.0, 1.05, color), 0.3);

    // Midtone contrast enhancement
    color = mix(color, color * color * (3.0 - 2.0 * color), 0.15);

    // Film grain — fine, even, non-clumpy
    vec2 screenPos = gl_FragCoord.xy;
    float grain = (hash(screenPos * 0.7) - 0.5) * 0.03;
    color += grain;

    // Vignette (beam-splitter light loss)
    vec2 normalizedCoord = texcoord / texsize;
    color *= vignette(normalizedCoord);

    return vec4(clamp(color, 0.0, 1.0), 1.0);
}