Storm Arc
của MusicBar, thanh tiến trình
Tia sét lởm chởm nhảy từ đầu thanh tới quả cầu điện ở chỗ đang phát, nhạc càng to sét đánh càng dồn, tới nhịp là lóe sáng cả dải.
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 5b14fa2edbe245380844f4e87fd26dc13a33496cafad8d687e4e42f4766735bd
//! name: Storm Arc
//! author: MusicBar
//! kind: progress
//! description: Jagged lightning crackles from a small terminal at the start of the bar to a glowing electrode orb at the playhead, striking faster when the music is loud and flashing on every beat.
float hash1(float n)
{
n = frac(n * 0.1031);
n *= n + 33.33;
n *= n + n;
return frac(n);
}
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);
}
// Jagged noise: straight runs between random points (value and slope).
float2 jag(float x, float seed)
{
float i = floor(x);
float a = hash1(i + seed);
float b = hash1(i + 1.0 + seed);
return float2(lerp(a, b, frac(x)) * 2.0 - 1.0, (b - a) * 2.0);
}
// A bolt's offset from its centre line at x, in bar heights, with its slope: four jagged octaves.
float2 bolt(float x, float seed)
{
float2 v = jag(x * 0.9, seed) * float2(0.24, 0.24 * 0.9);
v += jag(x * 2.1, seed + 13.1) * float2(0.12, 0.12 * 2.1);
v += jag(x * 4.7, seed + 27.7) * float2(0.06, 0.06 * 4.7);
v += jag(x * 10.3, seed + 41.3) * float2(0.03, 0.03 * 10.3);
return v;
}
float4 main(float2 uv : TEXCOORD) : COLOR
{
float H = size.y;
float2 px = float2(uv.x * size.x, rise(uv) * size.y); // pixels: along the bar, up from the screen edge
float yc = H * 0.5;
float head = max(progress * size.x, 1.6 * H);
float ro = 0.23 * H * (1.0 + 0.12 * beat);
float x0 = 0.42 * H;
float x = px.x / H;
// A new strike many times a second, faster when loud; each one a little brighter or dimmer.
float tick = floor(time * 16.0);
float strike = 0.75 + 0.25 * hash1(tick * 3.7);
float span = smoothstep(0.0, 0.7, (px.x - x0) / H) * smoothstep(0.0, 0.5, (head - ro - px.x) / H) * step(px.x, head);
float wide = 0.1 * H * (1.0 + 0.6 * beat + 0.3 * level);
float cw = max(0.55, 0.022 * H);
float3 acc = float3(0, 0, 0);
float cover = 0;
// A faint wire for the rest of the song.
float wire = step(head + ro + 0.2 * H, px.x) * step(frac(px.x / (0.2 * H)), 0.5) * smoothstep(1.0, 0.0, abs(px.y - yc));
layer(acc, cover, colorB.rgb, wire * 0.18);
// The bloom over the whole arc, flashing on the beat.
// (Distance to a bolt: across the slope close to it, straight up and down further out so steep runs do not smear.)
float2 m = bolt(x, tick * 7.13);
float my = abs(px.y - yc - m.x * H * span);
float dm = my * lerp(rsqrt(1.0 + m.y * m.y * span * span), 1.0, saturate(my / (0.05 * H)));
layer(acc, cover, colorA.rgb, exp(-dm / (0.45 * H)) * (0.12 + 0.35 * beat) * step(px.x, head) * smoothstep(x0 - 0.1 * H, x0 + 0.3 * H, px.x));
// A second, dimmer filament, struck on its own rhythm.
float2 g = bolt(x, floor(time * 9.0) * 3.31 + 500.0);
float gy = abs(px.y - yc - g.x * H * span * 0.8);
float dg = gy * lerp(rsqrt(1.0 + g.y * g.y * span * span * 0.64), 1.0, saturate(gy / (0.05 * H)));
layer(acc, cover, colorB.rgb, exp(-dg / (wide * 0.7)) * 0.4 * span);
layer(acc, cover, lerp(colorB.rgb, float3(1, 1, 1), 0.5), smoothstep(cw * 0.8 + 0.5, cw * 0.8 - 0.5, dg) * 0.6 * span);
// Side branches forking forward off the main bolt.
float L = 1.3 * H;
float bi = floor(px.x / L);
float bh = hash1(bi * 1.37 + tick * 5.1);
float bx0 = (bi + 0.08 + 0.3 * bh) * L;
float blen = (0.3 + 0.28 * hash1(bi + tick * 2.9)) * L;
float bspan = smoothstep(0.0, 0.7, (bx0 - x0) / H) * smoothstep(0.0, 0.5, (head - ro - bx0) / H);
float by0 = yc + bolt(bx0 / H, tick * 7.13).x * H * bspan;
float bt = (px.x - bx0) / blen;
float bdir = (hash1(bi * 3.3 + tick) < 0.5 ? -1.0 : 1.0) * (0.35 + 0.4 * bh);
float2 bj = jag(bt * 5.0, bi + tick * 9.7);
float byy = by0 + bdir * (px.x - bx0) + bj.x * 0.07 * H * bt;
float slope = bdir + bj.y * 0.07 * H * 5.0 / blen;
float dbr = abs(px.y - byy) / sqrt(1.0 + slope * slope);
float bmask = step(0.0, bt) * step(bt, 1.0) * (1.0 - bt) * step(bh, 0.65) * step(bx0 + blen, head - ro) * step(x0 + 0.4 * H, bx0);
layer(acc, cover, colorB.rgb, exp(-dbr * dbr / (wide * wide * 0.3)) * 0.6 * bmask * smoothstep(0.0, 0.3, bt));
layer(acc, cover, lerp(colorB.rgb, float3(1, 1, 1), 0.6), smoothstep(cw * 0.7 + 0.5, cw * 0.7 - 0.5, dbr) * bmask);
// The main bolt: a colored glow and a white core.
float onArc = smoothstep(x0 - 0.1 * H, x0 + 0.1 * H, px.x) * step(px.x, head);
layer(acc, cover, colorA.rgb, exp(-dm / wide) * 0.85 * strike * onArc);
layer(acc, cover, lerp(float3(1, 1, 1), colorA.rgb, 0.12), smoothstep(cw + 0.5, cw - 0.5, dm) * strike * onArc);
// Short arcs licking forward off the orb.
float2 rel = px - float2(head, yc);
float a = atan2(rel.y, rel.x);
float ab = floor((a + 3.14159) / 6.28318 * 10.0);
float ah = hash1(ab * 1.9 + tick * 3.3);
float ang = (ab + 0.15 + 0.7 * ah) / 10.0 * 6.28318 - 3.14159;
float2 dir = float2(cos(ang), sin(ang));
float alen = H * (0.18 + 0.3 * hash1(ab + tick * 1.7)) * (0.7 + 0.6 * level + 0.6 * beat);
float al = dot(rel, dir) - ro;
float2 aj = jag(al / H * 9.0, ab * 11.0 + tick * 4.3);
float ac = dot(rel, float2(-dir.y, dir.x)) - aj.x * 0.05 * H * saturate(al / (0.1 * H));
float lick = smoothstep(cw + 0.5, cw - 0.5, abs(ac) / sqrt(1.0 + aj.y * aj.y * 0.2)) * step(0.0, al) * step(al, alen) * (1.0 - al / alen);
float fwd = step(0.0, cos(ang) + 0.35) * step(ah, 0.75);
layer(acc, cover, colorA.rgb, exp(-abs(ac) / (wide * 0.5)) * step(0.0, al) * step(al, alen) * (1.0 - al / alen) * fwd * 0.5);
layer(acc, cover, lerp(colorA.rgb, float3(1, 1, 1), 0.7), lick * fwd);
// The electrode orb: a glass ball full of plasma, rim lit, with a highlight; and a small terminal at the start.
float od = length(rel);
layer(acc, cover, colorA.rgb, exp(-max(od - ro, 0.0) / (0.2 * H)) * (0.45 + 0.4 * beat));
float3 orb = lerp(colorA.rgb * 0.55, lerp(colorA.rgb, float3(1, 1, 1), 0.85), exp(-od / (0.45 * ro)) * (0.8 + 0.2 * strike));
orb += lerp(colorB.rgb, float3(1, 1, 1), 0.3) * smoothstep(ro * 0.7, ro, od) * 0.6;
orb += smoothstep(0.32 * ro, 0.12 * ro, length(rel - float2(-0.35, 0.4) * ro)) * 0.8;
layer(acc, cover, orb, smoothstep(ro + 0.6, ro - 0.6, od));
float2 tr = px - float2(x0 - 0.12 * H, yc);
float td = length(tr);
float rt = 0.13 * H;
float n = sqrt(saturate(1.0 - td * td / (rt * rt)));
float3 term = float3(0.25, 0.27, 0.31) + float3(0.6, 0.62, 0.66) * n * smoothstep(-0.5, 0.6, tr.y / rt) + colorA.rgb * 0.35 * (1.0 - n);
layer(acc, cover, colorA.rgb, exp(-max(td - rt, 0.0) / (0.12 * H)) * 0.4 * strike);
layer(acc, cover, term, smoothstep(rt + 0.6, rt - 0.6, td));
return paint(acc / max(cover, 0.001), cover);
}