Signal Death

GLSL shader by merrypranxter · created 2026-02-14 · 10s loop · 2 passes

TV test card actively dying. Gradient bars, corrupted checkerboards, VHS jitter, block displacement, data mosh bleed, and ornate tile overlays — all falling apart in real time.

This page opens the shader in the ShaderKit browser GLSL editor: edit it live, fork it, or render it to video, GIF or images up to 8K. Also available as a full-screen view and an embeddable player.

Shader source (GLSL)

Common

#define pi acos(-1.)
#define deg pi/180.  //1 degree
#define time iTime*2.*pi/10. //sin(time) loops 10 seconds
#define R iResolution.xy //shorthand
#define ar R.x/R.y //aspect ratio
#define M iMouse //shorthand
#define xm (M.xy/R) //normalized mouse
#define nm ((xm.xy-0.5)*vec2(ar,1.)+0.5) //aspect ratio correction
vec3 cs = vec3(1.,2.,3.);
mat2 r2d(float a) {
    return mat2(cos(a),sin(a),-sin(a),cos(a));
}

Buffer A (iChannel0)

// ============================================================
//  SIGNAL DEATH v1.2 — fully de-inlined, compiler proof
// ============================================================

const float PI  = 3.14159265359;
const float TAU = 6.28318530718;
const float speed      = 0.6;
const float glitchAmt  = 0.85;
const float noiseStr   = 1.4;
const float brightness = 1.5;
const float aberration = .022;

vec3 lfPalette(float t) {
    vec3 a = vec3(0.5, 0.3, 0.6);
    vec3 b = vec3(0.5, 0.5, 0.5);
    vec3 c = vec3(1.0, 1.3, 0.9);
    vec3 d = vec3(0.0, 0.25, 0.6);
    return a + b * cos(TAU * (c * t + d));
}
vec3 neonPalette(float t) {
    vec3 a = vec3(0.4, 0.2, 0.5);
    vec3 b = vec3(0.5, 0.5, 0.4);
    vec3 c = vec3(2.1, 1.5, 0.8);
    vec3 d = vec3(0.1, 0.4, 0.9);
    return a + b * cos(TAU * (c * t + d));
}

float hash11(float p) {
    float q = fract(p * 0.1031);
    q = q * q + 33.33;
    q = q * q + q;
    return fract(q);
}
float hash21(vec2 p) {
    vec2 q = fract(p * vec2(127.1, 311.7));
    float d = dot(q, q + 19.19);
    q += d;
    return fract(q.x * q.y);
}
float vnoise(vec2 p) {
    vec2 i = floor(p);
    vec2 f = fract(p);
    vec2 u = f * f * (3.0 - 2.0 * f);
    float a = hash21(i);
    float b = hash21(i + vec2(1,0));
    float c = hash21(i + vec2(0,1));
    float d = hash21(i + vec2(1,1));
    return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
}

float staticGrain(vec2 uv, float t) {
    vec2 p = uv * 500.0 + vec2(t * 137.0, t * 79.0);
    return hash21(p);
}

vec2 vhsJitter(vec2 uv, float t) {
    float scanBand = floor(uv.y * 30.0 + t * 11.0);
    float jArg     = scanBand + t * 47.0;
    float jitter   = (hash11(jArg) - 0.5) * glitchAmt * 0.06;
    float hardBand = floor(uv.y * 8.0 + t * 3.0);
    float hArg1    = hardBand + t * 13.0;
    float hArg2    = hardBand * 3.7;
    float hardJump = step(0.93, hash11(hArg1)) * (hash11(hArg2) - 0.5) * 0.15;
    return uv + vec2(jitter + hardJump, 0.0);
}

vec2 blockCorrupt(vec2 uv, float t) {
    float blockY  = floor(uv.y * 12.0);
    float tSnap   = floor(t * 5.0);
    float bArg    = blockY * 1.3 + tSnap;
    float enabled = step(0.85, hash11(bArg));
    float sArg    = blockY * 7.1 + t;
    float shift   = (hash11(sArg) - 0.5) * 0.18 * enabled;
    return uv + vec2(shift, 0.0);
}

vec3 barColor(float idx, float t) {
    float phase = idx / 7.0 + t * 0.04;
    return lfPalette(phase);
}

float ornateTile(vec2 uv, float t) {
    vec2  p     = uv * 12.0;
    vec2  ip    = floor(p);
    vec2  fp    = fract(p) - 0.5;
    float angle = hash21(ip) * TAU + t * 0.5;
    float ca    = cos(angle);
    float sa    = sin(angle);
    vec2  rp    = vec2(ca * fp.x - sa * fp.y,
                       sa * fp.x + ca * fp.y);
    float minrp = min(abs(rp.x), abs(rp.y));
    float cr    = smoothstep(0.04, 0.0, minrp);
    float dia   = abs(rp.x) + abs(rp.y);
    float diaE  = smoothstep(0.04, 0.0, abs(dia - 0.4));
    float ring  = smoothstep(0.03, 0.0, abs(length(fp) - 0.3));
    return clamp(cr + diaE + ring, 0.0, 1.0);
}

float dataMosh(vec2 uv, float t) {
    float band    = floor(uv.y * 20.0);
    float phase   = floor(t * 4.0);
    float enabled = step(0.8, hash21(vec2(band, phase)));
    return vnoise(uv * 3.0 + t * 0.5) * enabled;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2  uv = fragCoord / iResolution.xy - 0.5;
    uv.x    *= iResolution.x / iResolution.y;
    float t  = iTime * speed;

    vec2 juv = vhsJitter(uv, t);
    vec2 buv = blockCorrupt(juv, t);

    // Grid values
    float col7R  = floor((buv.x + aberration + 0.5) * 7.0);
    float col7G  = floor((buv.x + 0.5) * 7.0);
    float col7B  = floor((buv.x - aberration * 1.3 + 0.5) * 7.0);
    vec2  cell8  = floor((buv + 0.5) * 8.0);
    float check  = mod(cell8.x + cell8.y, 2.0);
    float bandV  = uv.y + 0.5;

    // Bars
    vec3 bars = vec3(barColor(col7R, t).r,
                     barColor(col7G, t).g,
                     barColor(col7B, t).b);

    // Checker
    float grain   = staticGrain(buv, t);
    float gArg    = floor(uv.y * 60.0) + t * 23.0;
    float grainB  = step(0.88, hash11(gArg));
    float cnoise  = vnoise(buv * 40.0 + t * 2.0);
    float checkPat = step(0.5, mod(check + step(0.7, cnoise), 2.0));
    float bandIdx  = floor((buv.y + 0.5) * 7.0);
    vec3  checkCol = mix(vec3(0.02, 0.01, 0.03),
                         neonPalette(bandIdx * 0.15 + t * 0.05),
                         checkPat);

    // Ornate
    float ornate    = ornateTile(buv, t);
    float ornPhase  = length(buv) * 2.0 + t * 0.08;
    vec3  ornateCol = neonPalette(ornPhase) * ornate;

    // Mosh
    float mosh    = dataMosh(buv, t);
    vec3  moshCol = lfPalette(mosh + t * 0.1) * mosh * 1.5;

    // Scanline
    float sl    = sin(buv.y * iResolution.y * PI) * 0.5 + 0.5;
    float scanline = mix(1.0, 0.6 + sl * 0.4, 0.3);

    // Zone weights
    float wTop  = smoothstep(0.68, 0.72, bandV);
    float wBars = smoothstep(0.44, 0.48, bandV)
                * (1.0 - smoothstep(0.66, 0.70, bandV));
    float wBot  = 1.0 - smoothstep(0.18, 0.22, bandV);
    float wMid  = clamp(1.0 - wTop - wBot - wBars, 0.0, 1.0);

    float noiseTop = vnoise(buv * 5.0 + t);
    float noiseTop2 = vnoise(buv * 8.0 - t * 0.5);
    vec3 topContent  = bars * 0.4 + moshCol * 0.8
                     + lfPalette(noiseTop + t * 0.1) * noiseTop2 * 0.6;
    vec3 barsContent = bars * 1.2 + ornateCol * 0.3;
    vec3 midContent  = mix(checkCol, moshCol, 0.3)
                     + vec3(grain) * grainB * noiseStr
                     + ornateCol * 0.4;
    vec3 botContent  = vec3(grain * 0.15) + ornateCol * 0.9
                     + lfPalette(bandV * 3.0 + t * 0.07) * 0.1;

    vec3 col = topContent  * wTop
             + barsContent * wBars
             + midContent  * wMid
             + botContent  * wBot;

    col *= scanline;

    float edgeX = abs(uv.x);
    col.r += edgeX * aberration * 30.0 * 0.3;
    col.b -= edgeX * aberration * 20.0 * 0.2;

    float flashArg = floor(t * 7.0);
    float flash    = step(0.97, hash11(flashArg)) * 0.15;
    col += lfPalette(t * 0.3) * flash;

    float vig = dot(uv * 1.2, uv * 1.2);
    col *= 1.0 - vig * 0.5;
    col  = pow(clamp(col * brightness, 0.0, 1.0), vec3(0.82));

    fragColor = vec4(col, 1.0);
}

Image

Not used

More shaders by merrypranxter

Browse all public shaders · All shaders by merrypranxter · ShaderKit home

Vibe Mode BETA
💰 ~0 credits
Uniforms
FPS: 0
Time: 0
Resolution: 0 x 0

Account

FPS: -- Time: -- --×-- 1x