Boba Time

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

Trà sữa trân châu đầy tới chỗ đang phát, lớp kem xoáy bên trên, trân châu nảy theo tiếng bass, tới nhịp là ống hút hút một viên lên cái vèo.

6 lượt tải Tải file, 6.3 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 77b906976e3ab1b8ab2c31c2a9fcc5ca0e29a0a9a9ee815487677f173680c36a

//! name: Boba Time
//! author: MusicBar
//! kind: progress
//! description: Milk tea with a cream swirl fills the bar up to a wide straw at the playhead, the pearls bounce on the bass and the straw slurps one up 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);
}

// One glossy tapioca pearl: dark and glassy, amber where light passes through its lower rim.
void pearl(inout float3 acc, inout float cover, float2 q, float rp)
{
    float d = length(q);
    float body = smoothstep(rp + 0.6, rp - 0.6, d);
    float t = d / rp;
    float3 c = lerp(float3(0.09, 0.05, 0.035), float3(0.2, 0.11, 0.06), t * t);
    c += float3(0.55, 0.3, 0.12) * smoothstep(0.55, 1.0, t) * saturate(-q.y / rp + 0.2) * 0.8;
    float spot = smoothstep(0.26, 0.1, length(q / rp - float2(-0.32, 0.36)));
    float dot2 = smoothstep(0.12, 0.04, length(q / rp - float2(0.38, -0.3)));
    c += float3(1, 0.95, 0.9) * (spot * 0.9 + dot2 * 0.35);
    layer(acc, cover, c, body);
}

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float2 px = float2(uv.x * size.x, (1.0 - uv.y) * size.y);  // pixels: along the bar, and up the screen so gravity holds on a top taskbar too
    float u = size.y;
    float head = progress * size.x;
    float floorY = u * 0.07;
    float bass = spectrum(0.04);

    // The tea's surface: a gentle slosh that grows with the music.
    float surf = u * 0.74 + u * 0.022 * sin(px.x / u * 2.6 - time * 2.2) * (0.6 + level) + u * 0.012 * sin(px.x / u * 6.1 + time * 1.4);
    float teaD = max(max(px.y - surf, floorY - px.y), px.x - head - u * 0.08);
    float tea = smoothstep(0.6, -0.6, teaD);

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

    // The rest of the song: the cup's base and a dotted fill line, barely there.
    float ahead = smoothstep(head, head + u * 0.5, px.x);
    float dots = smoothstep(1.2, 0.2, length(float2(frac(px.x / (u * 0.3)) - 0.5, 0.0) * u * 0.3 + float2(0.0, px.y - u * 0.74)));
    float base = smoothstep(1.0, 0.0, abs(px.y - floorY + 0.5));
    layer(acc, cover, colorB.rgb, ahead * (dots * 0.28 + base * 0.2));

    // Milk tea: beige near the top to caramel below, pulled toward colorA for the flavor,
    // with streaks of dark syrup curling down from the top like brown sugar on the cup wall.
    float h = saturate((px.y - floorY) / (surf - floorY));
    float3 teaTop = lerp(float3(0.95, 0.84, 0.7), colorA.rgb, 0.35);
    float3 teaLow = lerp(float3(0.7, 0.45, 0.25), colorA.rgb * 0.75, 0.45);
    float3 c = lerp(teaLow, teaTop, smoothstep(0.0, 1.0, h));
    float syrup = sin(px.x / u * 1.7 - px.y / u * 2.4 + 1.2 * sin(px.y / u * 3.0 + px.x / u * 0.9) - time * 0.25);
    c = lerp(c, colorA.rgb * float3(0.5, 0.36, 0.3), smoothstep(0.45, 0.9, syrup) * smoothstep(0.85, 0.2, h) * 0.85);

    // The cream swirl: a light layer on top that curls down into the tea in tendrils.
    float swirl = sin(px.x / u * 2.4 + 3.2 * sin(px.y / u * 6.0 + px.x / u * 1.1 + time * 0.5) + time * 0.3);
    float creamLine = surf - u * 0.19 + u * 0.035 * sin(px.x / u * 2.1 + time * 0.6);
    float cream = smoothstep(-0.12, 0.12, swirl * 0.75 + (px.y - creamLine) / (u * 0.08));
    float3 creamC = lerp(colorB.rgb, float3(1, 0.97, 0.92), 0.4) * 0.97;
    c = lerp(c, creamC, cream * 0.92);

    // Soft light across the cup and a bright lip along the surface.
    c *= 0.86 + 0.14 * sin(px.x / u * 0.9 + 0.5);
    c += float3(1, 1, 1) * smoothstep(u * 0.04, 0.0, abs(px.y - surf + u * 0.03)) * 0.22;
    layer(acc, cover, c, tea * 0.94);

    // Pearls resting on the bottom, two loose rows; they bounce with the bass and jump on the beat.
    float rp = u * 0.115;
    float cw = u * 0.27;
    float cell = floor(px.x / cw);
    [unroll] for (int i = -1; i <= 1; i++)
    {
        float k = cell + i;
        float hk = hash1(k * 3.7 + 0.5);
        float hop = u * (0.07 * bass * (0.5 + 0.5 * sin(time * 8.0 + hk * 6.28)) + 0.12 * beat * hk);
        float2 at = float2((k + 0.5) * cw + (hk - 0.5) * u * 0.06, floorY + rp + 0.5 + hop);
        float2 q = px - at;
        if (at.x < head - rp * 0.5) pearl(acc, cover, q, rp);
        float hu = hash1(k * 9.1 + 4.0);
        float2 top = float2((k + 1.0) * cw, floorY + rp * 2.65 + hop * 1.3);
        if (hu < 0.45 && top.x < head - rp) pearl(acc, cover, px - top, rp * 0.95);
    }

    // The straw at the playhead: wide, tilted, clear colored plastic. It jolts a little on the beat.
    float2 sa = float2(head - u * 0.02, floorY + u * 0.05);
    float2 dir = normalize(float2(0.5 + 0.08 * beat, 1.0));
    float2 sq = px - sa;
    float along = dot(sq, dir);
    float across = dot(sq, float2(dir.y, -dir.x));
    float sr = u * 0.19;
    float strawD = max(abs(across) - sr, -along);
    float straw = smoothstep(0.6, -0.6, strawD);
    float wallT = abs(across) / sr;

    // A ring where the straw breaks the surface.
    float ringY = abs(px.y - surf + u * 0.01);
    layer(acc, cover, float3(1, 1, 1), smoothstep(u * 0.05, 0.0, ringY) * smoothstep(sr + u * 0.12, sr, abs(across)) * tea * 0.35);

    // On the beat a pearl shoots up the straw with a column of tea behind it.
    float slurp = step(0.03, beat);
    float pAlong = lerp(u * 0.15, u * 1.4, 1.0 - beat);
    float teaIn = step(along, max(pAlong * slurp, (surf - sa.y) / dir.y)) * smoothstep(sr - 0.5, sr - 2.0, abs(across)) * straw;
    layer(acc, cover, lerp(teaLow, teaTop, 0.55) * (0.8 + 0.2 * (1.0 - wallT)), teaIn * 0.9);
    if (slurp > 0.5) pearl(acc, cover, sq - dir * pAlong, sr * 0.8);

    // The plastic: a tint over whatever is inside, solid walls, a long highlight down one side.
    // Under the surface it is half hidden by the tea.
    float sunk = lerp(1.0, 0.5, tea);
    float3 sc = lerp(colorC.rgb, float3(1, 1, 1), 0.35 - 0.25 * teaIn);
    layer(acc, cover, sc, straw * lerp(0.72, 0.3, teaIn) * sunk);
    layer(acc, cover, colorC.rgb * 0.95, straw * smoothstep(0.6, 0.88, wallT) * 0.9 * sunk);
    layer(acc, cover, float3(1, 1, 1), straw * smoothstep(0.14, 0.0, abs(across / sr + 0.42)) * 0.75 * sunk);
    layer(acc, cover, float3(1, 1, 1), straw * smoothstep(0.06, 0.0, abs(across / sr - 0.55)) * 0.3 * sunk);
    layer(acc, cover, colorC.rgb * 0.4, smoothstep(1.3, 0.2, abs(strawD + 0.6)) * 0.85 * sunk);

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