ProjectsExperiments

Fireworks

Real-time fireworks built with React Three Fiber. Each shell rises with its trail and bursts into a sphere of 2,000 particles; a vertex shader drives the explosion, the fall and the twinkle.

Status
Finished
Period
2024.08 — 2024.11
Type
Shader / visual effect
Role
Solo project, 3D development
Technologies
  • Three.js
  • React
  • React Three Fiber
  • GLSL

Context and goal

An experiment in GPU particle animation. The whole motion lives in the vertex shader, and JavaScript only advances a 0-to-1 progress value with GSAP.

Demo

Click the orange pad or press ** F** to launch a shell. Each one gets one of four random colours and starts from a different spot on the launch area. The camera rotates on its own, and you can orbit with the mouse.

Technical description

  • Shell: a single vertex with a 10-point trail. Each point stops slightly before the one ahead of it, interpolated with mix(start, end, 1 − (1 − p)³) over one second.
  • Burst: 200 particles spread evenly over a sphere (acos(2r − 1)), each with a 10-point trail of shrinking size. Positions, sizes, time multipliers and trail offsets are computed once as BufferGeometry attributes.
  • Vertex shader: uses remap to split progress into stages:
    • a fast cubic ease-out explosion
    • a gravity curve
    • a slow fall
    • a size that opens and closes
    • a sin twinkle. Points smaller than one pixel are moved off screen.
float explodingProgress = remap(progress, 0.0, 0.3, 0.0, 1.0);
explodingProgress = clamp(explodingProgress, 0.0, 1.0);
explodingProgress = 1.0 - pow(1.0 - explodingProgress, 3.0);
newPosition *= explodingProgress;
  • Fragment shader: uses the particle texture as alpha, with additive blending.

Scene / details

When a shell bursts, it leaves a smoke cloud in its own colour (Drei’s Cloud) that lasts ten seconds. The ground is a reflective plane with an infinite grid. The launch area is a shader that draws only its outline.

Results and limitations

Each firework creates its own geometry and material and disposes of them when done, so many can be launched in a row. The twinkle changes size only, not brightness. Colours come from a fixed palette of four. Mobile has no keyboard, so you launch by tapping the pad.