cd ../portfolio
Phase 2 // GPU-Accelerated Graphics

FXBackgrounds

GPU-accelerated particle effect backgrounds. Four distinct environments -- Clouds with boids, ThunderStorm with procedural lightning, Galaxy, and Gradient Flow. Dual renderer architecture: Three.js for 3D, Pixi.js for 2D. TypeScript. GLSL shaders. Adaptive quality that scales to any hardware.

Created Jun 29, 2025 Size 512 KB Stars 1 Shaders GLSL

Project Overview

FXBackgrounds is a library of GPU-accelerated particle effects designed as website backgrounds. Each effect is a standalone module that renders at 60fps while consuming minimal CPU. The dual renderer approach uses Three.js for effects that need 3D geometry (Galaxy, ThunderStorm) and Pixi.js for 2D effects (Clouds, Gradient Flow). An adaptive quality system monitors FPS and scales particle counts, shader complexity, and resolution to match the device.

4
Distinct Effects
GLSL
Custom Shaders
60fps
Target Frame Rate
512 KB
Total Size
2
Renderers (Three + Pixi)
TS
TypeScript (77%)

Technology

First TypeScript project. First GLSL shaders. Vite for the build, with separate renderer modules loaded dynamically based on the selected effect.

TypeScript 77%
HTML 13%
GLSL 6%
CSS 4%
TypeScript Three.js Pixi.js GLSL Vite WebGL2 requestAnimationFrame Performance API Boids Algorithm Procedural Lightning

Dual Renderer Architecture

Two renderers, each optimized for different types of effects. The engine loads only what is needed.

Three.js

3D geometry, camera, lighting

Galaxy / ThunderStorm
+

Pixi.js

2D sprites, particles, filters

Clouds+Birds / Gradient Flow

Effect Library

Clouds + Birds
Layered parallax clouds with boid-flocking bird silhouettes. Reynolds' flocking rules: separation, alignment, cohesion.
Pixi.js Boids Parallax
ThunderStorm
Procedural lightning bolts with branching recursion. Rain particles, cloud illumination on flash, screen shake.
Three.js GLSL Procedural
Galaxy
Spiral arm galaxy with point cloud stars. Logarithmic spiral distribution, color temperature mapping, bloom post-processing.
Three.js Points Bloom
Gradient Flow
Smooth animated gradient mesh with noise-driven color interpolation. Pure shader effect -- no geometry.
Pixi.js GLSL Simplex Noise

Key Features

📈
Adaptive Quality
FPS monitoring downgrades resolution, particle counts, and shader passes when performance drops. Upgrades when headroom returns.
Procedural Lightning
Recursive branching algorithm generates unique bolts every flash. Branch probability, angle variance, and intensity are all tunable.
🐦
Boids Flocking
Reynolds' three rules: separation, alignment, cohesion. Birds flock naturally across the cloud layer.
🌈
GLSL Shaders
Custom fragment and vertex shaders for the gradient flow and lightning glow effects. Raw GPU programming.

Code Snapshot

The procedural lightning shader -- generates branching bolts in GLSL with randomized offsets and glow falloff.

lightning.frag.glsl
precision mediump float;

uniform float u_time;
uniform vec2 u_resolution;
uniform vec2 u_bolt_origin;
uniform float u_intensity;

varying vec2 v_uv;

float hash(float n) {
    return fract(sin(n) * 43758.5453);
}

float bolt(vec2 uv, vec2 origin, float seed) {
    float segments = 12.0;
    float glow = 0.0;

    vec2 pos = origin;
    vec2 dir = vec2(0.0, 1.0);

    for (float i = 0.0; i < segments; i++) {
        // Random offset per segment
        float offset = (hash(i + seed) - 0.5) * 0.15;
        pos += dir * (1.0 / segments);
        pos.x += offset;

        // Distance-based glow
        float d = length(uv - pos);
        glow += 0.002 / (d + 0.001);
    }

    return glow * u_intensity;
}

void main() {
    vec2 uv = v_uv;
    float light = bolt(uv, u_bolt_origin, u_time);
    vec3 color = vec3(0.6, 0.7, 1.0) * light;
    gl_FragColor = vec4(color, light * 0.8);
}

Development Timeline

Jun 29, 2025
Project Created -- First TypeScript + GLSL
Vite + TypeScript setup. First shader compiled. Galaxy effect prototype.
Week 1
Galaxy + Gradient Flow
Spiral arm distribution, point clouds, simplex noise gradient shader.
Week 2
ThunderStorm + Lightning Shader
Procedural bolt generation, rain particles, screen flash. The hardest effect.
Week 3
Clouds + Boids + Adaptive Quality
Pixi.js renderer for 2D effects. Reynolds flocking. FPS monitoring system.

What This Project Taught

01

GLSL Opens Direct Access to the GPU

Writing shaders is like programming a different computer. No garbage collection, no objects, no strings. Just math running on thousands of cores simultaneously. The lightning bolt effect -- a simple loop with distance fields -- produces something that looks physically plausible.

02

Two Renderers, One Philosophy

Three.js excels at 3D geometry. Pixi.js excels at 2D sprites. Using both, loaded dynamically, means each effect uses the best tool. The abstraction layer -- a shared EffectManager interface -- keeps the API consistent.

03

Performance Budgets Are Non-Negotiable

A background effect that drops below 30fps is worse than no effect. The adaptive quality system was not a nice-to-have -- it was the core feature. Monitoring FPS, scaling resolution, reducing particles. The user's device sets the quality, not the developer's ambition.

04

TypeScript Catches Shader Bugs at the Boundary

GLSL has no type safety. But TypeScript on the JavaScript side catches uniform type mismatches, missing parameters, and wrong data shapes before they hit the GPU. The typed boundary between JS and GLSL saves hours of debugging.