Night City
của MusicBar, visualizer
Dãy nhà cao tầng về đêm cao thấp theo nhạc, bass ở giữa, cửa sổ bật tắt, đèn đỏ trên cột ăng-ten nhấp nháy, bảng neon lóe lên mỗi nhịp.
Cách cài, mã SHA-256 và mã nguồn
Bấm Áp dụng: MusicBar tự tải về, kiểm tra mã SHA-256 rồi mặc lên taskbar; có rồi thì mặc luôn. Cần MusicBar 1.8 trở lên.
SHA-256 48c7594caca697d2f3f54a2b3daac6f685a104dd8c7ac79c3c92845dfc54bec9
//! name: Night City
//! author: MusicBar
//! kind: visualizer
//! description: A night skyline whose towers rise and fall with the music, bass in the middle, with windows flicking on and off, red lights blinking on the masts and neon signs that flare on the beat.
float hash2(float2 p)
{
float3 q = frac(float3(p.x, p.y, p.x) * 0.1031);
q += dot(q, q.yzx + 33.33);
return frac((q.x + q.y) * q.z);
}
// Lays a color over what is there (premultiplied light, and how much of the pixel it covers).
void layer(inout float3 acc, inout float cover, float3 rgb, float a)
{
a = saturate(a);
acc = rgb * a + acc * (1.0 - a);
cover = a + cover * (1.0 - a);
}
float boxD(float2 p, float2 b, float r)
{
float2 d = abs(p) - b + r;
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0) - r;
}
// The tower in cell k of a row: center, half width, roof height and crown height, in pixels.
// Its height follows the spectrum where it stands, mirrored so the bass sits in the middle.
float4 tower(float k, float cw, float seed, float lo, float vary, float amp, float H)
{
float hw = cw * (0.3 + 0.15 * hash2(float2(k, seed)));
float cx = (k + 0.5) * cw + (hash2(float2(k + 0.37, seed + 1.0)) - 0.5) * (cw - 2.0 * hw);
float s = saturate((spectrum(abs(cx / size.x - 0.5) * 2.0) - 0.22) * 2.4);
float top = H * (lo + vary * hash2(float2(k, seed + 2.0)) + amp * s + 0.07 * beat);
return float4(cx, hw, top, H * 0.1 * step(0.45, hash2(float2(k, seed + 3.0))));
}
// Distance to the tower's outline: a block with a narrower crown on top.
float towerD(float2 px, float4 t)
{
float dx = abs(px.x - t.x);
return min(max(dx - t.y, px.y - (t.z - t.w)), max(dx - t.y * 0.6, px.y - t.z));
}
// Its windows: x = 1 inside a lit pane (they flick on and off now and then), y = which kind of light.
float2 windows(float2 px, float4 t, float k, float H, float ratio)
{
float2 g = float2((px.x - t.x + t.y - 0.035 * H) / (0.085 * H), px.y / (0.1 * H));
float2 c = floor(g);
float2 f = frac(g);
float cols = floor((2.0 * t.y - 0.05 * H) / (0.085 * H));
float valid = step(0.0, c.x) * step(c.x, cols - 1.0) * step(1.0, c.y) * step(px.y, t.z - t.w - 0.05 * H);
float pane = step(0.22, f.x) * step(f.x, 0.74) * step(0.25, f.y) * step(f.y, 0.75);
float hw = hash2(c + k * 17.0);
float lit = step(hash2(float2(hw * 61.0, floor(time * 0.2 + hw * 9.0))), ratio);
return float2(pane * lit * valid, hw);
}
float4 main(float2 uv : TEXCOORD) : COLOR
{
// Pixels: along the bar, and up from the screen edge.
float H = size.y;
float2 px = float2(uv.x * size.x, rise(uv) * H);
float3 warm = lerp(colorC.rgb, float3(1.0, 0.86, 0.6), 0.35);
float3 acc = float3(0, 0, 0);
float cover = 0;
// The city glow on the haze, brighter when it is loud.
layer(acc, cover, lerp(colorA.rgb, colorB.rgb, saturate(px.y / H)), exp(-px.y / (0.45 * H)) * (0.14 + 0.14 * level + 0.08 * beat));
// The far row: hazy towers tinted by the glow, a few dim windows.
float cwB = 0.46 * H;
float kB = floor(px.x / cwB);
float4 tB = tower(kB, cwB, 7.0, 0.3, 0.25, 0.5, H);
float dB = towerD(px, tB);
float2 wB = windows(px, tB, kB + 500.0, H, 0.22);
float3 farC = colorB.rgb * 0.14 + 0.035 + colorB.rgb * 0.25 * smoothstep(1.5, 0.0, -dB);
layer(acc, cover, lerp(farC, warm * 0.6, wB.x * 0.7), smoothstep(0.5, -0.5, dB) * 0.85);
// The near row of towers.
float cw = 0.62 * H;
float k = floor(px.x / cw);
float4 t = tower(k, cw, 3.0, 0.1, 0.22, 0.68, H);
float d = towerD(px, t);
float hk = hash2(float2(k, 11.0));
// A mast on some crowns, its red light blinking in its own time.
float mastH = H * (0.1 + 0.12 * hk);
float mast = smoothstep(max(0.5, 0.012 * H) + 0.5, max(0.5, 0.012 * H) - 0.5, abs(px.x - t.x)) * step(t.z, px.y) * step(px.y, t.z + mastH);
float hasMast = step(0.4, hk);
layer(acc, cover, float3(0.12, 0.13, 0.17), mast * hasMast);
// The tower: dark glass and stone, a rim of city light around it, and its windows.
float3 body = float3(0.03, 0.035, 0.06) + 0.04 * saturate(px.y / H);
body += lerp(colorB.rgb, colorA.rgb, hk) * 0.35 * smoothstep(1.3, 0.0, -d);
float2 w = windows(px, t, k, H, 0.42 + 0.15 * level);
float3 pane = w.y < 0.72 ? warm : (w.y < 0.88 ? float3(0.65, 0.85, 1.0) : colorB.rgb);
layer(acc, cover, lerp(body, pane * (0.85 + 0.15 * beat), w.x), smoothstep(0.5, -0.5, d));
// A neon sign on some faces, flaring on the beat and now and then stuttering.
float hn = hash2(float2(k, 21.0));
float3 neon = hn < 0.72 ? colorA.rgb : colorB.rgb;
float2 sc = float2(t.x + (hash2(float2(k, 23.0)) - 0.5) * t.y * 0.8, t.z - t.w - 0.2 * H);
float sgn = boxD(px - sc, float2(0.055, 0.14) * H, 0.03 * H);
// Its glyphs: each row a bar, a stroke or a cross, made up and unreadable on purpose.
float gy = (px.y - sc.y) / (0.09 * H);
float gk = hash2(float2(k, floor(gy)));
float2 gq = float2(abs(px.x - sc.x) / (0.09 * H), abs(frac(gy) - 0.5));
float bar = step(gq.x, 0.3) * step(gq.y, 0.12);
float stroke = step(gq.x, 0.1) * step(gq.y, 0.32);
float glyph = max(bar * step(0.33, gk), stroke * step(gk, 0.66)) * step(sgn, -0.02 * H);
float tube = abs(sgn) - max(0.5, 0.013 * H);
float flick = 1.0 - 0.8 * step(hash2(float2(k, floor(time * 9.0))), 0.04);
float nb = step(0.4, hn) * step(0.3 * H, sc.y) * flick * (0.75 + 0.5 * beat + 0.2 * level);
layer(acc, cover, neon, exp(-max(sgn, 0.0) / (0.06 * H)) * 0.45 * nb);
layer(acc, cover, neon * 0.25, step(sgn, 0.0) * nb);
layer(acc, cover, lerp(neon, float3(1, 1, 1), 0.45), max(smoothstep(0.5, -0.5, tube), glyph) * nb);
// Neon outlining the crown of the towers that carry no sign.
float rimN = smoothstep(max(0.5, 0.012 * H) + 0.6, max(0.5, 0.012 * H) - 0.4, abs(d + 0.5)) * step(t.z - t.w - 0.04 * H, px.y);
float nr = step(hn, 0.4) * step(0.55, hash2(float2(k, 29.0))) * (0.7 + 0.5 * beat);
layer(acc, cover, colorB.rgb, exp(-abs(d) / (0.05 * H)) * 0.35 * nr * step(t.z - t.w - 0.04 * H, px.y));
layer(acc, cover, lerp(colorB.rgb, float3(1, 1, 1), 0.35), rimN * nr);
// The mast's red light: a hard blink with a soft glow.
float blink = smoothstep(0.3, 0.0, frac(time * 0.55 + hk * 5.0));
float rl = length(px - float2(t.x, t.z + mastH));
float3 red = float3(1.0, 0.15, 0.1);
layer(acc, cover, red, exp(-rl / (0.05 * H)) * (0.15 + 0.7 * blink) * hasMast);
layer(acc, cover, lerp(red, float3(1, 1, 1), 0.4), smoothstep(max(1.0, 0.03 * H) + 0.5, max(1.0, 0.03 * H) - 0.5, rl) * (0.35 + 0.65 * blink) * hasMast);
return paint(acc / max(cover, 0.001), cover);
}