0.00
60.0 fps

Log in to post a comment.

#version 300 es
precision highp float;

uniform float iTime;
uniform vec2  iResolution;

uniform sampler2D iBackbuffer;

out vec4 fragColor;

// ------------------------
// Utilities
// ------------------------

mat3 rotX(float a) {
    float s = sin(a), c = cos(a);
    return mat3(
        1.0, 0.0, 0.0,
        0.0,    c,   -s,
        0.0,    s,    c
    );
}

mat3 rotY(float a) {
    float s = sin(a), c = cos(a);
    return mat3(
          c, 0.0,   s,
        0.0, 1.0, 0.0,
         -s, 0.0,   c
    );
}

vec3 demoColor(float t) {
    return vec3(
        0.6 + 0.4 * sin(6.2831 * (t + 0.00)),
        0.6 + 0.4 * sin(6.2831 * (t + 0.33)),
        0.6 + 0.4 * sin(6.2831 * (t + 0.66))
    );
}

vec3 sphereToCube(vec3 p) {
    vec3 a = abs(p);
    float m = max(max(a.x, a.y), a.z);
    return p / m;
}

// ------------------------
// Main
// ------------------------

void main() {
    vec2 frag = gl_FragCoord.xy;
    vec2 res  = iResolution;

    float s = min(res.x, res.y);
    vec2 uv = (frag * 2.0 - res) / s;

    // Read backbuffer for trails
    vec3 prevCol = texture(iBackbuffer, frag / res).rgb;

    // ----------------------------
    // CAMERA — farther away now
    // ----------------------------
    float fov   = 1.0;
    float focal = 1.0 / tan(fov * 0.5);

    vec3 camPos = vec3(0.0, 0.0, -0.0);   // MUCH farther back

    // ----------------------------
    // SMOOTHER, SLOWER MOTION
    // ----------------------------
    float t = iTime * 1.725;  // slow everything down

    // Smooth drifting motion instead of bounce
    float bx = sin(t * 0.37) * 2.5;
    float by = sin(t * 0.29 + 1.4) * 2.2;
    float bz = sin(t * 0.41 + 2.7) * 1.6;

    vec3 center = vec3(bx, by, bz + 8.0); // shift forward into view volume

    // ----------------------------
    // SLOWER ROTATION
    // ----------------------------
    mat3 R = rotY(t * 0.6) * rotX(t * 0.7);

    // ----------------------------
    // SHAPE MORPHING (slow cycle)
    // ----------------------------
    float morph = 0.5 + 0.5 * sin(iTime * 0.25);

    // ----------------------------
    // RENDER POINT CLOUD
    // ----------------------------

    vec3 col = vec3(0.0);
    float maxAlpha = 0.0;

    const int POINT_COUNT = 900;
    float N = float(POINT_COUNT);
    float ga = 3.14159265 * (3.0 - sqrt(5.0));

    for (int i = 0; i < POINT_COUNT; ++i) {
        float fi = float(i);

        float y   = 1.0 - (fi / (N - 1.0)) * 2.0;
        float r   = sqrt(max(0.0, 1.0 - y * y));
        float phi = ga * fi;

        vec3 sphereP = vec3(
            cos(phi) * r,
            y,
            sin(phi) * r
        );

        // Cube target
        vec3 cubeP = sphereToCube(sphereP);

        // Morph between shapes
        vec3 p = mix(sphereP, cubeP, morph);

        // Radius unchanged
        float radius = 1.0;
        p *= radius;

        // Transform into world
        p = R * p + center;

        // Project into camera space
        vec3 v = p - camPos;
        if (v.z <= 0.1) continue;

        vec2 proj = v.xy * (focal / v.z);

        // Slower, softer pulse
        float baseR = 0.016;
        float pulse = 0.7 + 0.3 * sin(fi * 0.05 + t * 2.0);
        float rPix  = baseR * pulse;

        float d = length(uv - proj);
        if (d < rPix * 2.0) {
            float falloff = exp(-(d * d) / (rPix * rPix));

            float band = fi / N;
            vec3 pCol = demoColor(band + t * 0.15);

            col += pCol * falloff;
            maxAlpha = max(maxAlpha, falloff);
        }
    }

    // ----------------------------
    // TRAILS
    // ----------------------------
    float trailRetention = 0.094; // slightly longer, smoother trails
    float newContribution = clamp(maxAlpha, 0.004, 1.0);

    vec3 finalCol = prevCol * trailRetention + col * newContribution;

    // Mild gamma
    finalCol = pow(finalCol, vec3(0.9));

    fragColor = vec4(finalCol, 1.0);
}