Hi-Fi Spectrum

của MusicBar, visualizer

Dàn đèn LED phân tích phổ kiểu dàn âm thanh đời cũ, bass nằm giữa, cột nhảy từ xanh lên vàng rồi đỏ theo nhạc.

59 lượt tải Tải file, 3.4 KB
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 b12224214c3f43ddd19729c99e4741e74585158174cf3c017bdef384574207f3

//! name: Hi-Fi Spectrum
//! author: MusicBar
//! kind: visualizer
//! description: A classic stereo LED spectrum analyzer behind glossy glass, bass in the middle, crisp segments climbing from the main color through the second to the accent.

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 halfW = size.x * 0.5;

    // The grid snaps to whole pixels so every LED has hard edges: 8 rows, columns mirrored from the middle.
    float rows = 8.0;
    float segP = max(3.0, floor(H * 0.105));
    float gapY = max(1.0, floor(segP * 0.3));
    float base = max(1.0, floor((H - rows * segP) * 0.35));
    float colP = max(5.0, floor(H * 0.34));
    float gapX = max(1.0, floor(colP * 0.18));
    float d = floor(abs(px.x - halfW));
    float ci = floor(d / colP);
    float lx = d - ci * colP;
    float yI = floor(px.y) - base;
    float si = floor(yI / segP);
    float ly = yI - si * segP;
    float inCol = step(floor(gapX * 0.5), lx) * step(lx, colP - 1.0 - ceil(gapX * 0.5));
    float inRow = step(ly, segP - 1.0 - gapY) * step(0.0, si) * step(si, rows - 1.0);
    float led = inCol * inRow;

    // This column's band: bass at the middle, treble at the ends; the two channels drift apart a little.
    float f = (ci + 0.5) * colP / halfW;
    float side = step(px.x, halfW);
    float v = saturate((spectrum(f * 0.92) * 1.75 - 0.22) * (1.0 + 0.08 * sin(time * 3.1 + f * 9.0 + side * 2.0)) + 0.14 * beat);
    float fill = saturate(v * rows - si);
    float on = step(0.35, fill);
    float tip = on * step(v * rows - 1.0, si + 0.65);

    // The color climbs from main to second to accent; LEDs show a bright core and a lit top edge.
    float t = si / (rows - 1.0);
    float3 c = lerp(lerp(colorA.rgb, colorB.rgb, saturate(t * 1.8)), colorC.rgb, saturate(t * 2.4 - 1.4));
    float segH = segP - gapY;
    float core = 1.0 - 0.35 * abs((lx - colP * 0.5) / (colP * 0.5)) - 0.15 * (1.0 - ly / max(segH - 1.0, 1.0));
    float3 lit = c * core * (0.95 + 0.25 * fill) + 0.25 * step(segH - 1.5, ly) * step(1.5, segH);

    // Glass over the panel: a reflection with a crisp lower edge across the upper part, each LED's
    // upper half a little glossier, and a slow diagonal glint gliding past.
    float gloss = step(0.6 * H, px.y) * lerp(0.26, 0.08, saturate((px.y - 0.6 * H) / (0.4 * H)));
    gloss += step(segH * 0.5, ly) * 0.1;
    float glint = exp(-abs(frac((px.x + px.y * 2.0) / (16.0 * H) - time * 0.05) - 0.5) * 24.0) * 0.4;

    float3 acc = float3(0, 0, 0);
    float cover = 0;

    // Light bleeding from the lit run into the gaps, then unlit LEDs, then lit ones.
    float topY = base + floor(v * rows + 0.65) * segP - gapY;
    float dx = max(abs(lx - colP * 0.5) - colP * 0.4, 0.0);
    float dy = max(px.y - topY, 0.0) + max(base - px.y, 0.0);
    float bleed = exp(-length(float2(dx, dy)) / (0.05 * H + 0.6)) * step(px.y, base + rows * segP + 0.08 * H);
    layer(acc, cover, c, bleed * 0.3 * (0.8 + 0.4 * level));
    layer(acc, cover, c * 0.3 + 0.05, led * (1.0 - on) * 0.32);
    layer(acc, cover, lit * lerp(1.0, 1.3, tip), led * on);
    layer(acc, cover, float3(1, 1, 1), led * saturate(gloss + glint) * (0.12 + 0.88 * on));

    return paint(acc / max(cover, 0.001), cover);
}