Runs straight from GitHub Pages — desktop (keyboard) and mobile (touch). No install, no server.
A GEBARA Labs experiment.
Stage 1: Ecogarden — a 3D rally simulator that runs 100% in the browser, set on the red-earth backroads around Maringá, Paraná, Brazil: terra roxa dirt, coffee fields, pink and yellow ipê trees, farm houses and the Maringá Cathedral on the horizon. One ~6 km special stage with a co-driver calling pacenotes, and the 3D Red Foot logo monument spinning at the start line.
The stage follows real-world roads and elevations. The layout comes from
OpenStreetMap ways and the heights from SRTM (30 m) around
Ecogarden on Google Maps
(−23.469248, −51.900126), baked into src/data/ecogarden.json by
tools/build-map.mjs — the site stays fully static.
# rebake (or bake a brand-new location for a future stage):
node tools/build-map.mjs <lat> <lng> <name>The tool picks a long route through the real road graph, resamples it, fetches an elevation grid (OpenTopoData/SRTM), applies light exaggeration (1.15×) and then "grades" the road like a civil engineer would: the route profile is smoothed and capped at 12% grade, and the terrain is cut/filled in a corridor around it, so physics, road ribbon and scenery stay perfectly in sync.
| Layer | Technology |
|---|---|
| Build | Vite + TypeScript (fully static site) |
| Rendering | three.js WebGPU with TSL materials (automatic WebGL 2 fallback) |
| Physics | cannon-es — RaycastVehicle on a terrain heightfield |
| Post-processing | Bloom (headlights/sun) + vignette via TSL PostProcessing |
| Audio | WebAudio (engine, gravel, beeps) + co-driver voice via speechSynthesis |
Everything is generated procedurally at load time: track (Catmull-Rom), terrain, crop fields, ~560 trees, ~1600 coffee bushes, wind-blown grass, animated clouds, pacenotes extracted from the track curvature — and the Red Foot identity (the red footprint) drawn on canvas and extruded in 3D.
| Distance | Trees | Coffee | Grass |
|---|---|---|---|
| ≤ 130 m | branched trunk + multi-lobe canopy | full model | dense (≤ 175 m) |
| ≤ 460 m | single faceted canopy | full model | — |
| ≤ 1500 m | per-instance tinted billboard | culled (> 650 m) | — |
Re-bucketing runs every ~0.3 s and each level is split into 1000-instance sub-meshes (WebGPU's 64 KB uniform-buffer binding limit). Cloud shadows sweep the terrain and the road in sync with the sky (TSL noise).
- W / ↑ accelerate · S / ↓ brake & reverse
- A D / ← → steering · SPACE handbrake (drift)
- C camera (chase / hood / TV) · R reset to track · M sound
npm install
npm run dev # http://localhost:5173
npm run build # outputs docs/ (static)
npm run preview # serves the build at http://localhost:4300Tip: append ?webgl to the URL to force the WebGL 2 backend.
The build goes to docs/ with relative paths, so all it takes is:
- Push to the
mainbranch; - Settings → Pages → Deploy from a branch →
main/docs.
No workflow or server needed — static pages only.
Roadmap (see IDEAS.md)
- 🏃 Become a cross-country foot race: alternate the
1/0keys to run (left/right leg), runner avatar, still around Maringá. - 🗺️ Multiple maps at real tourist landmarks (Maringá–Londrina, Iguaçu Falls, Grand Canyon, Machu Picchu…), customizable avatars, new tracks added via GitHub issues.
PBR textures and the scanned boulder come from Poly Haven (CC0):
red_dirt_mud_01 (road), sparse_grass (fields), boulder_01 (roadside rocks).
Fetched by node tools/fetch-assets.mjs into public/assets/ (committed, so the
site stays static). Everything else is generated procedurally at runtime.
Built with Claude Code as an AI-model evaluation POC, for GEBARA Labs.