From 27a4e2e426417184e86780857aff98603041890d Mon Sep 17 00:00:00 2001 From: April John Date: Fri, 16 Oct 2026 14:47:41 +0200 Subject: [PATCH] Add kik CRT terminal shader Co-Authored-By: Claude Sonnet 5.5 --- shaders/kik.glsl | 56 ++++++++++++++++++++++++++++++++++++++++++++++ shaders/pulse.glsl | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 shaders/kik.glsl diff --git a/shaders/kik.glsl b/shaders/kik.glsl new file mode 100644 index 0000000..1a35e1f --- /dev/null +++ b/shaders/kik.glsl @@ -0,0 +1,56 @@ +// Khaos im Kiez: CRT terminal on the stairs (palette from berlin.ccc.de/kik) +// +// Output lines scroll along the stairs, the prompt sits on the last active +// step with a blinking cursor, now and then a line is KiK red. + +const vec3 BG = vec3(0.008, 0.040, 0.016); // #020a04 +const vec3 FG = vec3(0.200, 1.000, 0.400); // #33ff66 +const vec3 DIM = vec3(0.122, 0.604, 0.247); // #1f9a3f +const vec3 HOT = vec3(1.000, 0.165, 0.165); // #ff2a2a + +const float PROMPT_STEP = 12.0; // last step trepped drives +const float SCROLL_SPEED = 1.6; // lines per second + +float hash(float n) { + return fract(sin(n * 12.9898) * 43758.5453); +} + +// What line number n of the output looks like +vec3 line(float n) { + float h = hash(n); + if (h < 0.15) return BG; // blank line + if (h > 0.92) return HOT * 0.9; // "error" + float len = 0.25 + 0.75 * hash(n + 7.0); // line length ~ brightness + return mix(DIM * 0.5, FG, len * len); +} + +void mainImage(out vec4 fragColor, in vec2 fragCoord) { + float i = floor(fragCoord.x); + float s = iTime * SCROLL_SPEED; + float scroll = floor(s) + smoothstep(0.75, 1.0, fract(s)); + + vec3 col; + if (i < PROMPT_STEP - 1.0) { + // output area, lines move towards step 0 + float n = i + scroll; + col = line(n); + // glow bleeding from neighbouring lines + col += 0.10 * (line(n - 1.0) + line(n + 1.0)); + } else if (i < PROMPT_STEP) { + col = DIM * 0.9; // "visitor@khaos-im-kiez:~$" + } else if (i < PROMPT_STEP + 1.0) { + // cursor, blinks with steps(1) 1.1s like the site + col = fract(iTime / 1.1) < 0.5 ? FG : BG; + } else { + col = vec3(0.0); // not driven by trepped + } + + // rolling scanline + float band = fract(i / 16.0 * 2.0 - iTime * 0.15); + col *= 1.0 - 0.35 * smoothstep(0.0, 0.1, band) * (1.0 - smoothstep(0.1, 0.25, band)); + + // slight CRT flicker + col *= 0.96 + 0.04 * hash(floor(iTime * 30.0)); + + fragColor = vec4(col, 1.0); +} diff --git a/shaders/pulse.glsl b/shaders/pulse.glsl index 16cdcb3..22014df 100644 --- a/shaders/pulse.glsl +++ b/shaders/pulse.glsl @@ -1,7 +1,7 @@ // Warm white pulse travelling along the stairs void mainImage(out vec4 fragColor, in vec2 fragCoord) { float x = fragCoord.x / iResolution.x; - float wave = 0.5 + 0.5 * sin(x * 6.2831 * 2.0 - iTime * 3.0); + float wave = 0.5 + 0.9 * sin(x * 12.2831 * 2.0 - iTime * 2); vec3 warm = vec3(1.0, 0.45, 0.1); fragColor = vec4(warm * wave, 1.0); }