Munch Munch

của MusicBar, thanh tiến trình

Bé quái tròn vo vừa chạy lạch bạch vừa đớp sạch hàng hạt sáng tới chỗ đang phát, cứ tới nhịp là há miệng thật to rồi đớp cái phập.

12 lượt tải Tải file, 9.5 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 98938ec4ae7f6e9ef02d0fa61b6b0cf653018ae1b97feef931856097397be6ba

//! name: Munch Munch
//! author: MusicBar
//! kind: progress
//! description: A round little critter chomps its way down a row of glowing pellets to the playhead, snapping its jaw wide on every beat.

// A steady random number for a whole number.
float hash1(float n) { return frac(sin(n * 127.1 + 311.7) * 43758.5453); }

// Turns a point around the origin by a (radians, counterclockwise).
float2 rot(float2 p, float a) { float c = cos(a), s = sin(a); return float2(c * p.x - s * p.y, s * p.x + c * p.y); }

// Signed distance to an ellipse with radii r (close enough near the edge).
float ellipse(float2 p, float2 r)
{
    float k0 = length(p / r);
    return k0 * (k0 - 1.0) / max(length(p / (r * r)), 0.0001);
}

float sdSeg(float2 p, float2 a, float2 b) { float2 pa = p - a, ba = b - a; return length(pa - ba * saturate(dot(pa, ba) / dot(ba, ba))); }

// Round-body shading: a sphere normal from the ellipse, a key light up front, a rim at the back.
float3 shade(float2 q, float2 c, float2 r, float3 base)
{
    float2 s = (q - c) / r;
    float z = sqrt(saturate(1.0 - dot(s, s)));
    float3 n = normalize(float3(s, z * 0.9 + 0.05));
    float dif = saturate(dot(n, normalize(float3(0.35, 0.7, 0.6))));
    float spec = pow(saturate(dot(n, normalize(float3(0.25, 0.55, 1.0)))), 28.0);
    float rim = pow(1.0 - z, 3.0) * saturate(0.4 - n.x);
    return base * (0.34 + 0.85 * dif) + colorB.rgb * rim * 1.1 + spec * 0.55;
}

// 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);
}

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float u = size.y;                                         // everything is sized from the bar height
    float2 px = float2(uv.x * size.x, rise(uv) * size.y);     // pixels: along the bar, up from the screen edge
    float head = progress * size.x;
    float mid = 0.5 * u;
    float3 acc = float3(0, 0, 0);
    float cover = 0;

    // Crumbs the critter leaves: sparkles that fall and fade behind it, then a faint dotted trail.
    float gap = 0.5 * u, cw = 0.23 * u;
    float k = floor(px.x / gap + 0.5), ci = floor(px.x / cw);
    float h1 = hash1(ci), h2 = hash1(ci + 17.3), life = frac(time * 0.8 + h1);
    float2 cd = abs(px - float2((ci + 0.2 + 0.6 * h2) * cw, mid + (h1 - 0.5) * 0.5 * u - life * life * 0.3 * u));
    float spark = exp(-length(cd) / (0.022 * u)) + exp(-cd.x / 0.8 - cd.y / (0.05 * u)) + exp(-cd.y / 0.8 - cd.x / (0.05 * u));
    float back = head - px.x;
    float fresh = exp(-max(back, 0.0) / (2.6 * u)) * smoothstep(0.2 * u, 0.6 * u, back) * (1.0 - life);
    layer(acc, cover, lerp(colorC.rgb, float3(1, 1, 1), 0.4), spark * fresh * step(0.45, h2) * (0.7 + 0.5 * level));
    float ghost = smoothstep(0.03 * u, 0.012 * u, length(px - float2(k * gap, mid)));
    layer(acc, cover, colorC.rgb, ghost * 0.22 * step(k * gap, head - 0.3 * u));

    // Pellets ahead, bobbing on the center line and swelling with the spectrum; every 8th is a music note.
    float spec = spectrum(frac(k / 12.0) * 0.85);
    float big = step(frac(k / 8.0 + 0.01), 0.05);
    float2 pc = float2(k * gap, mid + 0.025 * u * sin(time * 3.0 + k * 0.8));
    float ahead = smoothstep(head + 0.02 * u, head + 0.12 * u, pc.x);
    float pr = 0.045 * u * (0.8 + 0.6 * spec), pd = length(px - pc), small = (1.0 - big) * ahead;
    float cellFade = smoothstep(0.25 * u, 0.14 * u, abs(px.x - pc.x));   // glows stay inside their own cell
    layer(acc, cover, colorC.rgb, small * exp(-pd / (0.07 * u)) * (0.35 + 0.4 * spec) * cellFade);
    layer(acc, cover, colorC.rgb * 0.3, small * smoothstep(0.5, -0.5, pd - pr - 1.0));
    layer(acc, cover, lerp(colorC.rgb, float3(1, 1, 1), 0.45 * spec), small * smoothstep(0.5, -0.5, pd - pr));
    float2 nq = (px - pc) / (u * (1.0 + 0.35 * beat));
    float note = ellipse(rot(nq - float2(-0.035, -0.07), 0.45), float2(0.075, 0.052));
    note = min(note, min(sdSeg(nq, float2(0.032, -0.065), float2(0.032, 0.15)) - 0.014, sdSeg(nq, float2(0.032, 0.15), float2(0.1, 0.07)) - 0.017));
    float nglow = exp(-max(length(nq - float2(0.0, 0.02)) - 0.06, 0.0) / 0.09);
    layer(acc, cover, colorC.rgb, big * ahead * nglow * cellFade * (0.45 + 0.45 * beat));
    layer(acc, cover, lerp(colorC.rgb, float3(1, 1, 1), 0.3 + 0.4 * beat), big * ahead * smoothstep(0.5, -0.5, note * u));

    // The critter: q is in bar heights, origin at the mouth, facing right. It bobs with its steps and squashes on the beat.
    float stepT = time * 15.0 + 1.5 * level, bob = abs(sin(stepT));
    float2 q = (px - float2(head, 0.55 * u + 0.025 * u * bob)) / u / float2(1.0 + 0.05 * beat, 1.0 - 0.07 * beat);
    float2 B = float2(-0.12, -0.03), R = float2(0.38, 0.29), H = float2(-0.2, -0.03);   // body center, radii, jaw hinge

    // The jaw: opens and snaps shut four times a second, and gapes on a beat.
    float c = frac(time * 4.0);
    float ang = max(0.42 * smoothstep(0.0, 0.6, c) * (1.0 - smoothstep(0.72, 0.9, c)), 0.8 * beat);
    float2 qj = rot(q - H, ang) + H;                          // the pixel seen in the jaw's closed pose
    float dBody = ellipse(q - B, R), dQuad = max(H.x - q.x, q.y - H.y);
    float dUpper = max(dBody, -dQuad);
    float dJaw = max(ellipse(qj - B, R), max(H.x - qj.x, qj.y - H.y));
    float dMouth = max(max(dBody, dQuad), H.y - qj.y);

    // Two stubby feet pattering under it, and a sprout with a glowing bud that lags the bobbing and swings on the beat.
    float2 fA = float2(0.02 + 0.05 * sin(stepT), -0.35 + 0.05 * saturate(cos(stepT)));
    float2 fB = float2(-0.25 - 0.05 * sin(stepT), -0.35 + 0.05 * saturate(-cos(stepT)));
    float dFootA = ellipse(q - fA, float2(0.1, 0.06)), dFootB = ellipse(q - fB, float2(0.1, 0.06));
    float2 bud = float2(-0.07 + 0.035 * sin(stepT - 1.2) - 0.04 * beat, 0.35 - 0.02 * bob);
    float dStem = sdSeg(q, float2(-0.16, 0.22), bud) - 0.016;

    // A soft self-lit halo and a dark outline keep it readable on light or dark taskbars.
    float dAll = min(min(min(dUpper, dJaw), min(min(dFootA, dFootB), dMouth)), dStem);
    layer(acc, cover, colorA.rgb, exp(-max(dAll, 0.0) / 0.1) * (0.28 + 0.25 * level));
    layer(acc, cover, colorA.rgb * 0.18, smoothstep(0.5, -0.5, dAll * u - 1.3));
    layer(acc, cover, shade(q, fB, float2(0.1, 0.06), colorA.rgb * 0.6), smoothstep(0.5, -0.5, dFootB * u));
    layer(acc, cover, shade(q, fA, float2(0.1, 0.06), colorA.rgb * 0.85), smoothstep(0.5, -0.5, dFootA * u));

    // Inside the mouth: a dark throat, a tongue on the jaw, and a row of small teeth top and bottom.
    float throat = saturate(length(q - H) / 0.32);
    float3 mouthCol = lerp(float3(0.16, 0.02, 0.05), float3(0.55, 0.1, 0.16), throat);
    float tongue = ellipse(qj - float2(0.04, H.y - 0.025), float2(0.16, 0.05));
    mouthCol = lerp(mouthCol, float3(1.0, 0.42, 0.5) * (0.55 + 0.55 * throat), smoothstep(0.5, -0.5, tongue * u));
    float tx = abs(frac((q.x - H.x) / 0.07) - 0.5) * 2.0;
    float teethUp = step(q.y, H.y) * step(H.y - 0.06 * (1.0 - tx), q.y) * step(H.x + 0.12, q.x);
    float tjx = abs(frac((qj.x - H.x) / 0.07) - 0.5) * 2.0;
    float teethDn = step(H.y, qj.y) * step(qj.y, H.y + 0.05 * (1.0 - tjx)) * step(H.x + 0.15, qj.x);
    mouthCol = lerp(mouthCol, float3(0.97, 0.95, 0.9) * (0.8 + 0.2 * throat), saturate(teethUp + teethDn));
    layer(acc, cover, mouthCol, smoothstep(0.5, -0.5, dMouth * u));

    // The stem and its bud, behind the head.
    layer(acc, cover, colorA.rgb * 0.7, smoothstep(0.5, -0.5, dStem * u));
    float dBud = length(q - bud) - 0.045 - 0.015 * beat;
    layer(acc, cover, colorC.rgb, exp(-max(dBud, 0.0) / 0.05) * (0.5 + 0.4 * beat));
    layer(acc, cover, lerp(colorC.rgb, float3(1, 1, 1), 0.5), smoothstep(0.5, -0.5, dBud * u));

    // The lower jaw, then the body over it; the shut mouth shows as a crease.
    layer(acc, cover, shade(qj, B, R, colorA.rgb) * (1.0 - 0.25 * saturate(ang / 0.3)), smoothstep(0.5, -0.5, dJaw * u));
    float3 bodyCol = shade(q, B, R, colorA.rgb);
    bodyCol *= 1.0 - 0.45 * exp(-abs(q.y - H.y) / 0.015) * step(H.x + 0.05, q.x) * (1.0 - saturate(ang / 0.1));
    layer(acc, cover, bodyCol, smoothstep(0.5, -0.5, dUpper * u));

    // One big eye looking ahead: white, a pupil with a glint, and a blink now and then.
    float2 E = float2(0.0, 0.12);
    float dEye = length(q - E) - 0.115, blink = step(frac(time / 3.3), 0.04);
    float3 eyeCol = lerp(float3(1, 1, 1), float3(0.72, 0.78, 0.9), saturate((E.y - q.y) / 0.16 + 0.3));
    eyeCol = lerp(eyeCol, float3(0.06, 0.05, 0.12), smoothstep(0.5, -0.5, (length(q - E - float2(0.048, -0.005)) - 0.058 - 0.012 * beat) * u));
    eyeCol = lerp(eyeCol, float3(1, 1, 1), smoothstep(0.5, -0.5, (length(q - E - float2(0.07, 0.02)) - 0.02) * u));
    eyeCol = lerp(eyeCol, shade(q, B, R, colorA.rgb * 0.8), blink);
    eyeCol = lerp(eyeCol, colorA.rgb * 0.15, blink * smoothstep(0.018, 0.008, abs(q.y - E.y + 0.02 + 0.6 * (q.x - E.x) * (q.x - E.x))));
    layer(acc, cover, colorA.rgb * 0.2, smoothstep(0.5, -0.5, dEye * u - 1.1));
    layer(acc, cover, eyeCol, smoothstep(0.5, -0.5, dEye * u));

    // On a beat a few crumbs spray out of the mouth and fall.
    for (int i = 0; i < 5; i++)
    {
        float t = 1.0 - beat;
        float2 v = float2(0.25 + 0.5 * hash1(i + 3.0), 0.35 + 0.9 * hash1(i + 9.0));
        float cr = length(q - float2(0.22, -0.08) - v * t * 0.8 + float2(0.0, 2.2 * t * t)) - 0.022 * (1.0 - 0.5 * t);
        layer(acc, cover, lerp(colorC.rgb, float3(1, 1, 1), 0.3), step(0.05, beat) * beat * smoothstep(0.5, -0.5, cr * u));
    }

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