Skip to content

yourlcfr/rift

Repository files navigation

RIFT — Aetheron

Persistent-canvas WebGL website for the dark-fantasy novel RIFT. Next.js 16 + React Three Fiber, custom GLSL shaders, adaptive quality tiers, meshopt asset pipeline.

What this is

A promotional site for an unpublished novel, built as a single continuous 3D world instead of a page-per-route site. One WebGL canvas survives every route change; a scene registry maps 8 scene ids (intro, hub, read, map, song, art, codex, about) to App Router routes with deep-link support. If WebGL is unavailable, the site falls back to a fully static version. Solo project, built over 4 weeks.

Engineering notes

  • One canvas, many routes. The canvas mounts once and never unmounts. A RouteSync component keeps the active scene and the URL in agreement, so /codex deep-links land in the right scene without a canvas teardown.
  • Procedural atmosphere. The hub maelstrom vortex (components/scenes/hub/AetherVortex.tsx, 302 lines) and the sunset sky dome (components/canvas/SkyDome.tsx, 154 lines) are hand-written GLSL. No external effect assets.
  • Asset pipeline (scripts/reproc-models.mjs): gltf-transform weld → meshopt simplify (ratio 0.45, error 0.004) → WebP texture compression → meshopt encoding. Blender originals of 60–92 MB (1–2M tris each) come out as six web GLBs of 9–12.5 MB, ~66 MB total. Originals stay outside the repo.
  • Keep-color decision. An earlier pass stripped textures during decimation and flattened every realm to a single tone. Reverted (b1ab31d, b90568d); the pipeline now decimates geometry only and preserves the original 4K baseColor materials. The reasoning is documented in the script header.
  • Adaptive quality (lib/quality.ts): high/mid/low tiers at ≥55 / ≥35 FPS via drei PerformanceMonitor + AdaptiveDpr. Tiers scale DPR (up to 2x), particle count (1200/500/150), and toggle postprocessing.
  • Intro sequence. 6 narrative beats over ~7 seconds. ENTER click unlocks audio (browser autoplay policy), SKIP is always available, and reduced-motion or returning visitors auto-skip. The skip decision is a pure function with unit tests.
  • Transitions. One primitive (descend/rise), wired to the router through a Zustand SceneDirector store. Direction is derived from the from/to scene pair, not passed around by hand.
  • Terrain seating. Buildings sit on the terrain via a downward raycast against the actual mesh surface instead of hand-tuned Y offsets (14a78a0).
  • Lighting. The rig (warm key / cool shadow, ember underglow, ACES tone mapping) was dialed interactively with leva, then hardcoded and the panel removed once the look was locked (2d1ff7b).
  • Dev tooling never ships. leva renders hidden in production; r3f-perf is gated behind NODE_ENV !== 'production'.
  • Bundler split. Dev runs webpack (next dev --webpack) because r3f-perf 7.2.3 crashes Turbopack's dev server. Prod builds with Turbopack. Known regression-risk window; deliberate.
  • e2e against the real build. Playwright builds the production bundle, serves it on port 3100, and drives two journeys: ENTER → hub → READ → RISE → home, and a /codex deep-link landing.
  • Asset provenance. public/ASSETS.md lists every external asset as CC0 with source links (Poly Haven HDRI, ambientCG PBR textures). The 6 realm models and the theme audio are original work.

Tests: 8 Vitest suites (store, transitions, quality tiers, intro skip, nav a11y, sound pref, scene registry, smoke) + 1 Playwright spec.

Stack

  • Next.js 16.2.9 (App Router), React 19.2.4, TypeScript 5
  • three.js 0.184, @react-three/fiber 9.6.1, drei 10.7.7, postprocessing 3.0.4
  • Zustand 5, GSAP 3.15, Tailwind CSS 4
  • Vitest 4 + Testing Library (jsdom), Playwright 1.61
  • gltf-transform v4 + meshoptimizer (offline asset pipeline)
  • Vercel

Screenshots

None checked in yet. Run the dev server; the hub vortex and the map realms (Velsaria, Lexarion, Aegirheim) are the ones worth looking at.

Getting started

npm install
npm run dev        # webpack dev server (see bundler note above)
npm run build      # production build (Turbopack)
npm test           # Vitest unit suites
npm run e2e        # Playwright, builds and serves prod on :3100

Heads up: the repo carries ~66 MB of GLB/HDR/MP3 assets, so the clone is not small.

License

Code is MIT. The 6 realm models and public/audio/main-theme.mp3 are original creative work, all rights reserved — see public/ASSETS.md. Third-party assets are CC0, sourced in the same file.

About

Persistent-canvas WebGL site for the dark-fantasy novel RIFT — one canvas across all routes, custom GLSL, meshopt pipeline

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors