Skip to content
GPU PARTICLE ENGINE · 90,000 POINTS

Pure math,
in motion.

A single buffer of ninety thousand particles, morphing through four shapes as you scroll — rendered live in a custom WebGL shader. Move your cursor to push the field around.

Begin the morph Drag your cursor across the field
90kparticles
4morph targets
1draw call
0textures
01 / FORM

A sphere of ninety thousand points.

Every particle starts life on a fibonacci shell — perfectly even, quietly breathing. Nothing is a texture. Nothing is a model file. It is pure math, drawn on the GPU.

02 / DISPERSE

The shell unwinds into a galaxy.

Scroll and the same points spiral outward into four logarithmic arms. No particle is created or destroyed — each one simply interpolates toward its next home in the vertex shader.

03 / KNOT

Order folds into a torus knot.

A (3, 4) knot, rendered as a fuzzy tube of light. Curl-flow noise keeps it alive; your cursor pushes the field aside with an inverse-square force.

04 / FIELD

And finally, a rippling plane.

The points settle into a grid and a wave rolls across it. One continuous morph, driven entirely by how far you have scrolled.

UNDER THE HOOD

No models. No textures. Just the GPU.

Vertex-shader morph

Each point carries its position in all four shapes as attributes; a cyclic weight blends the two nearest by scroll phase.

Pseudo-curl flow

Layered sine fields perturb every particle so the form never sits still — organic motion with zero noise-texture lookups.

Pointer force

Your cursor is projected onto the view plane and repels nearby points with an inverse-square falloff, right in the shader.

Additive iridescence

Color is computed per-point from an HSL palette and depth glow, composited with additive blending for a bloom-like core.

Built to behave

Honors prefers-reduced-motion, caps device pixel ratio, and renders the whole field in a single draw call.

Raw Three.js + R3F

No drei, no post-processing dependency — just @react-three/fiber, three, and a hand-written GLSL program.

THE CEILING, ON ONE ROUTE

This is what
max looks like.