Waveform
của MusicBar, thanh tiến trình
Cả bài hiện thành dạng sóng y như mấy app nghe nhạc, phần đã phát lên màu, mấy cột gần con trỏ thì phập phồng theo nhạc.
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 17977bfff1141839d36c0045e7c01e7d1d2c6ccf87f089a80df7b1aea81735cc
//! name: Waveform
//! author: MusicBar
//! kind: progress
//! description: The whole song drawn as a streaming-player waveform, lit up to the playhead, with the bars by the cursor breathing to the live spectrum.
// A steady random number for a bar.
float hash1(float n) { return frac(sin(n * 78.233) * 43758.5453); }
// Smooth random wobble: values that drift slowly from bar to bar.
float wobble(float x)
{
float i = floor(x);
float f = frac(x);
f = f * f * (3.0 - 2.0 * f);
return lerp(hash1(i), hash1(i + 1.0), f);
}
// The loudness of the song at t (0 to 1): intro, verse, chorus, verse, chorus, bridge, last chorus, outro.
float shape(float t)
{
return 0.3 + 0.2 * smoothstep(0.0, 0.08, t) + 0.35 * smoothstep(0.28, 0.31, t) - 0.3 * smoothstep(0.44, 0.47, t)
+ 0.35 * smoothstep(0.58, 0.61, t) - 0.5 * smoothstep(0.77, 0.79, t) + 0.55 * smoothstep(0.84, 0.86, t)
- 0.7 * smoothstep(0.94, 1.0, t);
}
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);
}
float4 main(float2 uv : TEXCOORD) : COLOR
{
float2 px = float2(uv.x * size.x, rise(uv) * size.y); // pixels: along the bar, up from the screen edge
float H = size.y;
float head = progress * size.x;
float y0 = 0.34 * H; // the line the bars stand on
float tall = 0.62 * H;
// One thin bar per cell; its height is fixed per bar, so the picture never jitters.
float P = max(3.0, 0.14 * H);
float i = floor(px.x / P);
float cx = (i + 0.5) * P;
float r = max(0.75, 0.29 * P);
float detail = 0.45 * wobble(i * 0.23) + 0.25 * wobble(i * 0.9 + 17.0) + 0.3 * hash1(i);
float h = shape(cx / size.x) * (0.3 + 0.75 * detail);
// The bars by the cursor breathe with the live spectrum: bass at the cursor, treble further out.
float k = i - floor(head / P);
float near = exp(-abs(k) / 2.2);
float s = spectrum(saturate(0.06 + abs(k) * 0.08));
h *= lerp(1.0, 0.45 + 1.1 * s + 0.3 * beat, near);
h = clamp(h, 0.06, 1.0);
// The bar (a capsule above the line) and its short reflection below.
float top = y0 + max(h * tall, 2.0 * r);
float dy = px.y - clamp(px.y, y0 + r + 0.5, top - r);
float d = length(float2(px.x - cx, dy)) - r;
float bottom = y0 - max(h * tall * 0.42, 2.0 * r);
float dyR = px.y - clamp(px.y, bottom + r, y0 - r - 0.5);
float dR = length(float2(px.x - cx, dyR)) - r;
float bar = smoothstep(0.5, -0.5, d);
float mirror = smoothstep(0.5, -0.5, dR) * (0.25 + 0.75 * saturate((px.y - bottom) / (y0 - bottom)));
// Played: the palette gradient up the bar, a slow sheen running through, a halo near the cursor.
float played = smoothstep(0.5, -0.5, px.x - head);
float t = saturate((px.y - y0) / tall);
float3 hot = lerp(colorA.rgb, colorB.rgb, t);
float sweep = frac(time * 0.11) * (head + 6.0 * H) - 3.0 * H;
float sheen = exp(-abs(px.x - sweep) / (1.5 * H)) * 0.35;
hot = lerp(hot, float3(1, 1, 1), sheen) * (0.9 + 0.2 * level);
float3 cool = float3(0.6, 0.62, 0.68);
float3 acc = float3(0, 0, 0);
float cover = 0;
float halo = exp(-max(d, 0.0) / (0.05 * H + 0.8)) * exp(-abs(px.x - head) / (2.2 * H)) * played;
layer(acc, cover, colorA.rgb, halo * (0.25 + 0.3 * level));
layer(acc, cover, lerp(cool, hot, played), mirror * lerp(0.2, 0.42, played));
layer(acc, cover, lerp(cool, hot, played), bar * lerp(0.5, 1.0, played));
// The cursor: a thin glowing line with a knob on the base line that swells on the beat.
float dl = abs(px.x - head);
float lineMask = step(0.05 * H, px.y) * step(px.y, 0.97 * H);
layer(acc, cover, colorC.rgb, exp(-dl / (0.06 * H + 1.0)) * 0.35 * lineMask);
layer(acc, cover, lerp(colorC.rgb, float3(1, 1, 1), 0.5), smoothstep(0.9, 0.2, dl) * lineMask * 0.9);
float2 kp = px - float2(head, y0);
float rk = 0.12 * H * (1.0 + 0.3 * beat);
float dk = length(kp) - rk;
layer(acc, cover, colorA.rgb, exp(-max(dk, 0.0) / (0.08 * H + 2.0 * beat)) * (0.55 + 0.4 * beat));
layer(acc, cover, lerp(colorA.rgb, float3(1, 1, 1), 0.75 - 0.3 * smoothstep(-0.6 * rk, 0.0, dk)), smoothstep(0.5, -0.5, dk));
return paint(acc / max(cover, 0.001), cover);
}