FreeVJ FULL AUTO VJ LOOP

FreeVJ / Loop-Bibliothek / Sequenz

Ai Aurora Curtains

Soft white aurora curtains drift and ripple on black, slow and luminous.

Ai Aurora Curtains
Diesen Loop live spielen

Exporte entstehen in diesem Browser und werden direkt gespeichert.

GLSL-Quelltext

const float SEQ_N = 32.0;
const float SEQ_COLS = 5.0;
const float SEQ_ROWS = 7.0;
const float SEQ_LUMA_ALPHA = 1.0;
const float SEQ_COVER = 0.0;
// Sequence (seq@1) shared shader — plays the frames of a greyscale atlas (uTex) by mode.
// SEQ_N · SEQ_COLS · SEQ_ROWS · SEQ_LUMA_ALPHA · SEQ_COVER constants are prepended.
// uParams: x=mode (0 A→B · 1 B→A · 2 A→B→A · 3 random N s each · 4 sliced panes · 5 slot reel) y=speed (frames/beat) z=hold (s) w=panes (panes · reels)
// Neighbouring frames are crossfaded so even few frames flow — a morph melts A into B this way.

float seqCell(float f, vec2 p) {
    if (p.x < 0.0 || p.y < 0.0 || p.x > 1.0 || p.y > 1.0) return 0.0;
    f = mod(floor(f), SEQ_N);
    vec2 grid = vec2(SEQ_COLS, SEQ_ROWS);
    vec2 cell = vec2(mod(f, SEQ_COLS), floor(f / SEQ_COLS));
    vec2 inset = 0.75 / vec2(textureSize(uTex, 0)) * grid;      // keep samples off the neighbouring cells
    vec2 q = clamp(vec2(p.x, 1.0 - p.y), inset, 1.0 - inset);
    return texture(uTex, (cell + q) / grid).r;
}

float seqAt(float pos, vec2 p) {
    return mix(seqCell(pos, p), seqCell(pos + 1.0, p), smoothstep(0.0, 1.0, fract(pos)));
}

// window (aspect win) coords → frame coords. contain (masks · symbols: never cropped) · cover (video: fill)
vec2 seqFit(vec2 q, float win) {
    vec2 ts = vec2(textureSize(uTex, 0));
    float cell = (ts.x / SEQ_COLS) / max(1.0, ts.y / SEQ_ROWS);
    vec2 p = q - 0.5;
    bool wide = win > cell;
    if ((SEQ_COVER > 0.5) != wide) p.x *= win / cell;
    else p.y *= cell / win;
    return p + 0.5;
}

vec2 prim(vec2 uv) {
    float mode = floor(uParams.x + 0.5);
    float sp = max(0.05, uParams.y);
    float aspect = uResolution.x / max(1.0, uResolution.y);
    float n = SEQ_N;
    float l = 0.0;

    if (mode < 3.5) {
        float pos;
        if (mode < 0.5) pos = uBeat * sp;                                   // A → B
        else if (mode < 1.5) pos = -uBeat * sp;                             // B → A
        else if (mode < 2.5) {                                              // A → B → A
            float per = max(1.0, 2.0 * (n - 1.0));
            float x = mod(uBeat * sp, per);
            pos = x < n - 1.0 ? x : per - x;
        } else {                                                            // random N s each — every segment flows from a different start frame
            float hold = max(0.25, uParams.z);
            float k = floor(uTime / hold);
            float t = uTime - k * hold;
            pos = floor(h11(k * 7.13 + uSeed * 0.37) * n) + t * sp * 2.0;
            l = smoothstep(0.0, 0.06, t);                                   // dip very briefly at the cut (no flash)
        }
        float v = seqAt(pos, seqFit(uv, aspect));
        l = mode > 2.5 ? v * l : v;
    } else if (mode < 4.5) {                                                // panes — sliced into vertical panes with their own phase, flowing up and down alternately
        float k = clamp(floor(uParams.w + 0.5), 1.0, 8.0);
        float i = floor(uv.x * k);
        float lx = fract(uv.x * k);
        float dir = mod(i, 2.0) < 0.5 ? 1.0 : -1.0;
        vec2 q = vec2(uv.x, fract(uv.y + dir * uBeat * 0.125 * sp));
        l = seqAt(uBeat * sp + i * n / k, seqFit(q, aspect));
        l *= smoothstep(0.0, 0.02, lx) * smoothstep(1.0, 0.98, lx);        // gap between panes
    } else {                                                                // slot reel — reels spin, then stop one by one with a small bounce
        float k = clamp(floor(uParams.w + 0.5), 1.0, 8.0);
        float hold = max(0.5, uParams.z);
        float i = floor(uv.x * k);
        vec2 q = vec2(fract(uv.x * k), uv.y);
        float cyc = floor(uTime / hold);
        float t = fract(uTime / hold);
        float stopAt = min(0.92, 0.3 + i * 0.6 / k);
        float from = floor(h11((cyc - 1.0) * 3.1 + i * 17.7 + uSeed) * n);
        float to = floor(h11(cyc * 3.1 + i * 17.7 + uSeed) * n);
        float e = 1.0 - pow(1.0 - clamp(t / stopAt, 0.0, 1.0), 3.0);
        float bounce = sin(clamp((t - stopAt) / 0.1, 0.0, 1.0) * 3.14159) * 0.06;
        float s = from + e * (2.0 * n + mod(to - from + n, n)) - bounce;
        float y = q.y + s;
        float win = aspect / k;
        l = seqCell(floor(y), seqFit(vec2(q.x, fract(y)), win));
        float spin = 1.0 - smoothstep(0.55, 1.0, clamp(t / stopAt, 0.0, 1.0));
        l = mix(l, seqCell(floor(y - 0.18), seqFit(vec2(q.x, fract(y - 0.18)), win)), 0.45 * spin);   // blur while spinning
        l *= smoothstep(0.0, 0.025, q.x) * smoothstep(1.0, 0.975, q.x);
    }

    l = clamp(l, 0.0, 1.0);
    return vec2(l, SEQ_LUMA_ALPHA > 0.5 ? l : 1.0);
}

Eine Funktion vec2 prim(vec2 uv) mit dem gemeinsamen Uniform-Vertrag (uBeat · uBass · uKick …). Sie gibt nur Luma und Alpha aus.

Ähnliche Loops

☕ Buy me a coffee

FreeVJ ist kostenlos. Wenn es dir gefällt, unterstütze den Macher mit einem Kaffee in USDT.

USDT · TRON (TRC20) nur über das TRC20-Netzwerk

TVg11kWumyqNpRU9HXKo8a8u2fa8sdJtKh

☕ 3 USDT☕☕ 5 USDT☕☕☕ 10 USDT

So sendest du mit Binance
  1. Binance-App: Wallet › Auszahlen › USDT › Adresse einfügen (oder QR scannen) › Netzwerk TRC20 › Betrag › bestätigen. Die Adresse gehört zu Binance, daher kann es als kostenlose interne Überweisung laufen.
  2. Andere Wallets und Börsen (Trust Wallet, OKX, Bybit …): USDT über das TRC20-Netzwerk an dieselbe Adresse senden. Eine eigene Wallet braucht etwas TRX für die Gebühr.

Immer über das TRC20-Netzwerk senden. Über ein anderes Netzwerk gesendetes USDT ist kaum zurückzuholen.