Settings
Flag
Wind
Cloth
Changes restart the simulation
Camera
Lighting
How It Works
Physics Simulation
The flag is simulated as a grid of particles connected by springs. Each particle has position, velocity, and is affected by gravity, wind, and air resistance. The left column of particles is pinned to the pole, while all others are free to move.
Integration: Semi-implicit Euler integration updates velocities from forces first, then positions from velocities. This runs in a dedicated Web Worker to keep the main thread free for rendering.
Constraints: Distance constraints between neighboring particles (horizontal, vertical, and diagonal) maintain the cloth's structure. Each step runs 6 constraint iterations, correcting particle positions to prevent stretching beyond 5% of rest length.
Wind model: Wind force is procedural and position-dependent, combining a base directional force with sinusoidal gusts and Perlin-like turbulence. Every particle receives a different wind vector based on its position and the current time.
Rendering
The scene is rendered with Three.js via React Three Fiber. The flag mesh is a subdivided plane whose vertex positions are updated each frame from the physics worker's output. Normals are recomputed per frame for accurate lighting.
Flag textures: Drawn procedurally onto an HTML Canvas at runtime. The US flag renders 13 stripes and 50 stars via canvas path operations. The Argentine flag composites the Sol de Mayo sun image. The Vercel flag draws a white triangle on black.
Terrain: The lunar surface is a high-resolution plane with procedural displacement (craters and noise), a real lunar photograph texture, and a generated normal map. Vertex alpha fades at the edges for a smooth circular silhouette.
Stars: 2,000 point sprites with randomized sizes and slight twinkle animation, rendered as a Three.js Points object.
Architecture
Physics runs in a Web Worker using a structure-of-arrays layout (separate Float32Arrays for X, Y, Z) for cache-friendly iteration. The main thread sends wind parameters and receives position buffers via postMessage. Rendering and simulation are fully decoupled.
Inspiration
This project was inspired by these open-source cloth simulations:
Textures
Built with Next.js, React Three Fiber, and Three.js. Simulation runs at 60fps in a dedicated Web Worker thread.