// 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); }