// Neon Drift, a stand-in world from zaisma.com/developers/backgrounds. MIT licensed: free to start from. float h1(float n) { return fract(sin(n * 127.1) * 43758.5453); } float h2(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); } vec2 h22(vec2 p) { p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3))); return fract(sin(p) * 43758.5453); } float noise(vec2 p) { vec2 i = floor(p), f = fract(p); vec2 u = f * f * (3.0 - 2.0 * f); return mix(mix(h2(i), h2(i + vec2(1.0, 0.0)), u.x), mix(h2(i + vec2(0.0, 1.0)), h2(i + vec2(1.0, 1.0)), u.x), u.y); } float fbm(vec2 p) { float v = 0.0, a = 0.5; for (int i = 0; i < 5; i++) { v += a * noise(p); p = p * 2.03 + 1.7; a *= 0.5; } return v; } // Soft particles in a grid of cells: each cell holds at most one, at a random spot, drifting with the grid. float motes(vec2 p, float size, float chance, float seed) { vec2 id = floor(p), f = fract(p) - 0.5; vec2 r = h22(id + seed) - 0.5; float on = step(1.0 - chance, h2(id + seed * 1.3)); float d = length(f - r * 0.7); return on * smoothstep(size, 0.0, d); } const float CAM = 0.55; // camera height over the road (a lane is 0.5 wide) float hs1(float n) { n = fract(n * 0.1031); n *= n + 33.33; return fract(n * (n + n)); } // Neon fog along the skyline: magenta and violet with pockets of cyan, drifting. vec3 fogc(float x, float t) { float a = sin(x * 2.3 + 1.0 - t * 0.02); return mix(mix(vec3(1.0, 0.24, 0.6), vec3(0.6, 0.2, 1.0), 0.5 + 0.5 * sin(x * 5.0 + a * 2.0)), vec3(0.25, 0.8, 1.0), smoothstep(0.75, 1.0, a) * 0.5); } // The city at q, drawn front to back so hidden layers cost nothing; full = 0 for reflections. vec3 city(vec2 q, float px, float t, float full) { vec3 glow = vec3(1.0, 0.26, 0.58), fog = fogc(q.x, t), acc = vec3(0.0), add = vec3(0.0); float T = 1.0, xs = abs(q.x), low = exp(-q.y * 9.0); for (int j = 0; j < 4; j++) { if (T < 0.003) break; if (j == 2) { // The arcology at the road's end: tiers, a needle, a holo ring, a beacon if (xs > 0.17 || q.y > 0.72) continue; float d = min(min(max(xs - 0.07, q.y - 0.17), max(xs - 0.048, q.y - 0.36)), min(max(xs - 0.03, q.y - 0.5), max(xs - 0.004, q.y - 0.6))); float m = smoothstep(px, -px, d), w = q.y < 0.17 ? 0.07 : (q.y < 0.36 ? 0.048 : 0.03), fade = smoothstep(0.17, 0.11, xs); vec3 tc = vec3(0.07, 0.02, 0.14) + vec3(0.25, 0.9, 1.0) * smoothstep(0.005, 0.0, abs(xs - w + 0.005)) * 0.9; tc += vec3(1.0, 0.3, 0.75) * smoothstep(0.55, 0.8, abs(fract(q.y * 24.0) - 0.5) * 2.0) * 0.25 * (1.0 - xs / w * 0.6); tc += vec3(1.0, 0.75, 0.95) * smoothstep(0.01, 0.0, min(min(abs(q.y - 0.166), abs(q.y - 0.356)), abs(q.y - 0.496))) * 0.7; add += T * vec3(0.9, 0.3, 0.8) * exp(-abs(d) / 0.03) * 0.15 * fade; if (full > 0.5 && abs(q.y - 0.41) < 0.08) { // The ring, only ever seen directly: bright arcs circling (sin 3x angle from the unit vector, no atan) vec2 e = vec2(q.x / 0.12, (q.y - 0.41) / 0.024), n = e / max(length(e), 0.001); float rd = abs(length(e) - 1.0) * 0.024, arc = 0.35 + 0.65 * smoothstep(0.3, 1.0, n.y * (3.0 - 4.0 * n.y * n.y) * cos(t * 0.9) - n.x * (4.0 * n.x * n.x - 3.0) * sin(t * 0.9)); add += T * vec3(0.3, 1.0, 0.95) * (smoothstep(px * 2.0, 0.0, rd) * arc * (e.y < 0.0 ? 1.0 : 1.0 - m * 0.8) + exp(-rd / 0.012) * 0.12 * fade); } if (q.y > 0.58) add += T * vec3(1.0, 0.1, 0.2) * smoothstep(0.006, 0.0, length(q - vec2(0.0, 0.605))) * (0.6 + 0.4 * sin(t * 3.0)); // beacon acc += T * m * mix(tc, fog * 0.7, low * 0.6); T *= 1.0 - m; continue; } // Towers in three layers, near (fi = 3) to far (fi = 1): far ones melt into the fog, near ones are dark and crisp float fi = j < 2 ? 3.0 - float(j) : 1.0; float sc = 20.0 - fi * 4.7; if (q.y > 0.18 + fi * 0.047 + step(1.5, fi) * 0.075 + (xs + 0.5 / sc) * (0.05 + fi * 0.17) || (full < 0.5 && j == 3)) continue; float off = fi * 7.31, cx = q.x * sc + off, id = floor(cx), fx = fract(cx) - 0.5; float r = hs1(id + fi * 13.7), r2 = fract(r * 13.1 + 0.3), r3 = fract(r * 7.7 + 0.6), wid = 0.28 + 0.16 * r2; if (fi > 2.5 && r < 0.4 && xs < 0.75) continue; // gaps in the nearest row open views deep into the city float top = 0.06 + fi * 0.012 + (0.07 + fi * 0.035) * r + abs(id + 0.5 - off) / sc * (0.05 + fi * 0.17); // Body, a setback crown on some, a mast on others float sb = (0.012 + 0.03 * r) * step(0.5, r2), mx = (r3 - 0.5) * wid * 0.8, mh = (sb + 0.03 + 0.04 * r) * step(0.45, r3) * step(1.5, fi) * full; float d = min(min(max((abs(fx) - wid) / sc, q.y - top), max((abs(fx) - wid * 0.6) / sc, q.y - top - sb)), max(abs(fx - mx) / sc - 0.0012, q.y - top - mh)); if (d > 0.05) continue; // open sky well clear of this tower and its glows float m = smoothstep(px, -px, d); vec3 bc = mix(fog * (0.5 + 0.35 * low), vec3(0.022, 0.008, 0.05), (0.18 + fi * 0.26) * (1.0 - low * (0.85 - fi * 0.2))); vec3 nc = mix(vec3(1.0, 0.2, 0.7), vec3(0.2, 0.95, 1.0), step(0.7, r)); // Aircraft warning lamp on each mast, pulsing slowly float ld = length(vec2((fx - mx) / sc, q.y - top - mh)); if (mh > 0.0 && ld < 0.03 && full > 0.5) add += T * vec3(1.0, 0.12, 0.15) * (smoothstep(0.0045, 0.0, ld) + exp(-ld * 160.0) * 0.3) * (0.3 + 0.7 * smoothstep(0.25, 0.0, abs(fract(t * 0.4 + r * 5.0) - 0.15))); // Neon signs: strips or bands, tubes brightest at the rim float band = step(0.8, r2), on = step(0.45, r) * step(1.5, fi) * (1.0 - step(0.72, r2) * step(2.5, fi)); float sd = max((abs(fx - (r - 0.5) * wid * (1.0 - band)) - mix(0.05, 0.3, band)) / sc, abs(q.y - top * (0.35 + 0.3 * r2)) - top * mix(0.18, 0.05, band)); // Holo panels: big blocks and bars of colour, cycling slowly, glowing into the haze float hp = step(0.72, r2) * step(2.5, fi), pw = wid * 0.85, pcy = top * (0.5 + 0.2 * r), phh = top * 0.13 + 0.015, pd = 1.0, blk = 0.0; vec2 pu = vec2(fx / pw, (q.y - pcy) / phh); vec3 pc = vec3(0.0); if (hp > 0.5) { pd = max((abs(fx) - pw) / sc, abs(q.y - pcy) - phh); blk = floor((pu.x + 1.0) * 1.5); pc = mix(mix(vec3(1.0, 0.15, 0.6), vec3(0.15, 0.9, 1.0), 0.5 + 0.5 * sin(t * 0.25 + blk * 2.1 + r * 6.0)), vec3(1.0, 0.6, 0.2), step(0.8, fract(blk * 0.37 + r * 3.0))); add += T * pc * exp(-max(pd, 0.0) * 50.0) * 0.28; } if (fi > 1.5 && m > 0.0) { bc += mix(glow, nc, 0.5) * smoothstep(px * 2.0, 0.0, (fx * sign(-q.x) + wid) / sc) * 0.12 * fi + nc * smoothstep(px, -px, sd) * (0.45 + 0.55 * smoothstep(-0.006, -0.001, sd)) * on; if (full > 0.5 && fi > 1.5) { // Windows: floors of varied height lit as bands, scattered or dark; warm and cool, a few flickering float fy = q.y * (55.0 + 55.0 * r2) * (1.0 + (3.0 - fi) * 0.3), fl = floor(fy), fh = hs1(fl + id * 7.7); float wx = (fx + 0.5) * (8.0 + floor(r * 5.0) * 2.0), wh = hs1(floor(wx) * 3.3 + fl * 1.7 + id * 5.1); float lit = fh > 0.8 ? 1.0 : (fh > 0.5 ? step(0.6, wh) : step(0.96, wh)); if (lit > 0.0) { float shape = smoothstep(0.5, 0.3, abs(fract(fy) - 0.5)) * mix(smoothstep(0.5, 0.28, abs(fract(wx) - 0.5)), 1.0, step(0.8, fh) * step(0.45, r3)); vec3 wc = mix(mix(vec3(1.0, 0.62, 0.38), vec3(0.45, 0.8, 1.0), step(0.5, fract(wh * 7.0 + r))), vec3(1.0, 0.4, 0.85), step(0.86, fract(wh * 13.0))); bc += wc * shape * step(abs(fx), wid - 0.03) * (fi - 0.6) * 0.06 * (1.0 - 0.7 * step(0.975, wh) * abs(fract(t * (0.1 + wh * 0.3) + wh * 7.0) * 2.0 - 1.0)); } } float inP = smoothstep(px, -px, pd) * hp; if (inP > 0.0) bc = mix(bc, pc * (full > 0.5 ? (0.55 + 0.45 * step(0.35, fract(pu.y * 1.5 + blk * 0.43))) * smoothstep(1.0, 0.86, abs(fract((pu.x + 1.0) * 1.5) - 0.5) * 2.0) * (0.85 + 0.15 * sin(q.y * 900.0)) : 0.8), inP * 0.85); } if (on > 0.5) add += T * nc * exp(-max(sd, 0.0) * 160.0) * 0.25 * (1.0 - m * 0.5); acc += T * m * bc; T *= 1.0 - m; } if (T > 0.003) { // Sky: the fog's glow under violet night, smog lit from below vec3 col = mix(mix(fog, vec3(0.3, 0.06, 0.44), smoothstep(0.0, 0.28, q.y)), vec3(0.035, 0.012, 0.09), smoothstep(0.22, 0.85, q.y)); col += vec3(1.0, 0.55, 0.8) * exp(-length(vec2(q.x * 0.5, q.y)) * 8.0) * 0.4; float c = 0.5; if (full > 0.5) c = noise(vec2(q.x * 2.0 + t * 0.012, q.y * 6.0)) * 0.8 + 0.1 * sin(q.x * 9.0 - q.y * 20.0 + t * 0.1); acc += T * (col + mix(vec3(0.85, 0.18, 0.6), vec3(0.35, 0.1, 0.55), smoothstep(0.0, 0.5, q.y)) * smoothstep(0.35, 0.85, c) * (smoothstep(1.1, 0.05, q.y) * 0.75 + 0.12)); } // Street-level neon fog blooming along the foot of the city return acc + add + fog * exp(-q.y * 16.0) * 0.55; } // Street lamps along both barriers; reflections pass the mirrored point. float lamps(vec2 q, float px) { if (abs(q.y - 0.463 * abs(q.x)) > 0.12) return 0.0; // lamps sit on one line per side float dx = abs(q.x), zn = max(floor(0.36 / max(dx, 0.001) + 0.5), 1.0) * 3.0; float d = length(vec2(dx, q.y) - vec2(1.08, 1.05 - CAM) / zn), size = max(0.05 / zn, px); return (smoothstep(size, 0.0, d) + exp(-d / (size * 3.0)) * 0.35) * smoothstep(60.0, 20.0, zn); } void mainImage(out vec4 color, in vec2 pixel) { vec2 uv = pixel / iResolution.xy; float ar = iResolution.x / iResolution.y, t = iTime, wide = clamp((ar - 0.6) / 1.0, 0.0, 1.0); float hz = mix(0.5, 0.4, wide), s = mix(0.8, 1.0, wide), px = 1.5 / iResolution.y / s; vec2 q = (vec2(uv.x * ar, uv.y) - vec2(ar * mix(0.5, 0.6, wide), hz)) / s; // scene units from the vanishing point // Below the horizon the deck (depth z, lateral X) and the bay mirror the city, stretched and rippled; one city per pixel float down = step(q.y, 0.0), z = CAM / max(-q.y, 0.0001), X = q.x * z, bay = step(1.08, abs(X)); vec2 m = q; if (down > 0.5) { float rw = mix(X * 3.0, q.x * 40.0, bay); m = vec2(q.x + sin(rw * 2.1 + z * 1.3 - t * 0.6) * sin(rw * 1.3 - z * 2.2 + t * 0.45) * 0.5 * mix(0.012 / (1.0 + z * 0.1), 0.007, bay), -q.y * mix(0.4, 0.5, bay)); } vec3 col = city(m, px * (1.0 + down), t, 1.0 - down) + vec3(0.85, 0.8, 1.0) * lamps(m, px * (1.0 + down * 2.0)); if (down > 0.5) { vec3 refl = col, road = vec3(0.02, 0.01, 0.04) + refl * (0.3 + 0.45 * smoothstep(1.5, 12.0, z)); if (bay < 0.5) { // Lane dashes, fading with distance road += vec3(0.6, 0.5, 0.7) * smoothstep(px + 0.01 / z, 0.01 / z - px, abs(fract(X * 2.0 + 0.5) - 0.5) / 2.0 / z) * step(0.55, fract(z * 0.35)) * step(abs(X), 0.75) * 0.3 * smoothstep(25.0, 4.0, z); // Light trails: headlights coming on the left, tail lights going on the right, a pair of lamps per car for (int k = 0; k < 4; k++) { float fk = float(k), xc = -0.75 + fk * 0.5, away = step(1.5, fk), w = 0.022 / z, wd = max(w, px * 0.5), dl = abs(abs(X - xc) - 0.07) / z; float u = z * 0.11 + (1.0 - 2.0 * away) * t * (0.3 + 0.06 * fk) + fk * 0.37, ph = mix(fract(u), 1.0 - fract(u), away); float comet = smoothstep(0.0, 0.025, ph) * max(1.0 - ph / (0.25 + 0.5 * hs1(floor(u) + fk * 7.0)), 0.0); comet *= sqrt(comet); vec3 tc = mix(vec3(0.7, 0.97, 1.0), vec3(1.0, 0.12, 0.42), away); road += tc * (0.1 + 2.4 * comet) * min(1.0, w / wd) * (smoothstep(wd + px, wd - px, dl) + exp(-dl / (wd * 4.0 + 0.003)) * 0.3); road += mix(tc, vec3(1.0), 0.4) * smoothstep(0.0, 0.05, ph) * exp(-ph * 10.0) * exp(-abs(X - xc) / z / (w * 8.0 + 0.008)) * 0.25; } } else { // Barriers with an LED strip, the drop to the bay beyond float zb = 1.08 / max(abs(q.x), 0.001); road = q.y > -CAM / zb && q.y < (0.14 - CAM) / zb ? vec3(0.06, 0.025, 0.1) + refl * 0.06 : vec3(0.008, 0.004, 0.025) + refl * (0.6 + 0.4 * noise(vec2(q.x * 60.0, q.y * 3.0))); road += vec3(0.3, 0.95, 1.0) * smoothstep(px * 1.5 + 0.008 / zb, 0.0, abs(q.y + (CAM - 0.14) / zb)) * 0.9; } col = mix(road, vec3(0.85, 0.25, 0.55), mix((1.0 - exp(-z * 0.035)) * 0.8, exp(q.y * 60.0) * 0.3, bay)); } // Rain: two layers of long slanted streaks for (int j = 0; j < 2; j++) { float fj = float(j), sc = 22.0 + fj * 16.0; vec2 r = vec2((uv.x * ar + uv.y * 0.12) * sc, uv.y * sc * 0.05 + t * (1.6 + fj * 0.6)); float rr = hs1(floor(r.x) + fj * 9.0), drop = fract(r.y + rr * 7.0); col += vec3(0.6, 0.75, 1.0) * smoothstep(0.0, 0.04, drop) * smoothstep(0.45, 0.04, drop) * step(0.4, rr) * smoothstep(0.14, 0.04, abs(fract(r.x) - 0.5 - (rr - 0.5) * 0.6)) * (0.1 + fj * 0.06); } // Grade: violet blacks, vignette col = col / (1.0 + col * 0.35) + vec3(0.012, 0.0, 0.03); color = vec4(col * (1.0 - 0.3 * pow(length(uv - 0.5) * 1.2, 2.0)), 1.0); }