Skip to content

jeonghopark/Wormhole

Repository files navigation

Wormhole

An interactive Three.js scene of glowing wireframe wormholes — hyperboloid tunnels punched through a shared flat sheet, with GPU-driven particles that run across the sheet, drop through a mouth, and run out on the other side.

screencapture_01.jpg

How a particle moves

A particle is not assigned to a wormhole. It is a start point on the top sheet and a heading, and the shader intersects that line with every mouth and takes the nearest one. Its cycle is three legs:

straight across the sheet  ->  down the tunnel  ->  straight out on the far sheet

Three things fall out of that shape, each of which was a bug fixed by it rather than worked around:

  • It cannot cross another mouth. Up to the first mouth its line meets, that line is by definition inside no mouth at all. Both flat runs stop at the first mouth ahead of them — the outbound one too, or it sails over the openings on the far sheet.
  • It does not lurch at the rim. The flat runs are straight, so distance travelled is arc length there and only the tunnel needs a baked lookup. A particle advances at a fixed world speed along the whole cycle.
  • It does not turn a corner at the rim. The tunnel opens along the radius, so lines are aimed at a mouth's centre — any offset in the aim is exactly the angle the path would break by — and re-aimed until the mouth being aimed at is the one actually reached. The swirl's rate eases to zero at both rims, so no tangential motion is left where the tunnel meets a sheet.

A line that meets no mouth simply runs to the rim of the sheet and starts over. So does the run out: placement picks each particle's swirl so that its exit line reaches the rim rather than stopping at another mouth, because a cycle ending at a mouth ends with the particle winking out on that mouth's edge — it does not go in, it goes back to its start.

Features

  • Punctured sheet — one lattice per sheet at y = ±H, with a disc cut out at every mouth, clipped to the circle so the openings stay round. Not a radial patch per hole stacked on the same ground: ten patches never read as one surface with openings in it, and the single lattice is a third of the segments.
  • Wormhole funnels — a hyperboloid grid whose meridian is vertical at the waist and horizontal at the mouth, so each funnel meets the sheet with no crease. One geometry, instanced at every mouth. The height profile is the odd quintic rather than a sine: a matching tangent at the rim is not enough on its own, because a sine leaves the second derivative non-zero there and the bend arrives at full rate.
  • Split directions — half the mouths are fed from the top sheet and half from the bottom. Which way a tunnel is travelled follows from the sheet a particle is on, not from the mouth, so any mouth can still be entered from either side and no opening ever has to be passed over.
  • Mouths kept apart — placement enforces a gap of 2.2 mouth radii. Two mouths closer than two radii overlap, which is broken geometry in its own right: the openings merge and the funnels intersect.
  • GPU particle flow — all motion is in the vertex shader; the CPU only advances a single uFlowTime uniform. Per-particle attributes (start, heading, phase, speed, swirl) are static.
  • Trails — each head drags a fading tail sampled back along its own cycle in world-distance steps, clamped at the start so it piles up rather than streaking back across the scene at the wrap.
  • Passage colour — a particle is neutral until it goes through a throat, then keeps the colour of the way it went: blue for down, red for up. Driven by height, not rate of climb — rate peaks at the throat and returns to zero at both rims, so a particle would leave a wormhole the same colour it arrived. The change is taken across the middle of the tunnel, so it happens deep inside rather than snapping at a rim.
  • Grid shader — vertex base colour plus an animated energy pulse travelling along the tunnel axis, with in-shader fog.
  • Bloom + fogUnrealBloomPass gives the lines their glow; linear fog dissolves distant grid and tails into the dark background.
  • Debug UI (lil-gui) — wormhole shape, plane grid spacing, flow, grid pulse, fog and glow, plus a randomize positions button.

Tech

  • Three.js ^0.184.0, Vite ^8, lil-gui, jszip
  • Package manager: pnpm only (only-allow pnpm)

Commands

cd Wormhole  # navigate to the project directory
pnpm dev     # start the dev server
pnpm build   # production build

Source lives in src/ (each src/*.html is a Vite build entry); static assets in public/; build output in dist/. See PROJECT_AI.md for the working rules AI agents follow on this project.

Structure

src/main.js is the composition root — it wires the modules together and runs the loop. Everything else lives in src/wormhole/:

Module Responsibility
config.js All parameters, config and palette (mutated live by the GUI)
shaders.js All GLSL (shared flow chunk + head / tail / grid programs)
profile.js Meridian math — funnelProfile, funnelMeridian
path.js Arc-length LUT for the TUNNEL, baked into a DataTexture
holes.js Wormhole instances (holes, randomizeHoles)
grid.js createGrid() — funnel geometry + the punctured sheets
particles.js createParticles() — GPU particle heads + tails
gui.js createGUI() — lil-gui debug panel

Only the tunnel is baked into the path texture. The flat runs are straight lines, where distance travelled and arc length are already the same thing, so there is nothing to resample — which is also what keeps the speed even across the join.

The params, flow, fogSettings and holes objects are single shared instances imported wherever needed, so GUI edits are seen everywhere.

Branches

This branch reaches the punctured sheet analytically: every particle's whole cycle is a closed-form function of its start and heading, with no state carried between frames. main takes the other route from the same starting point — a GPU-integrated 3D vector field, where the flow is stepped each frame and the shapes emerge from the field rather than from a profile.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages