A reed-roofed boat drifts under cherry trees at dawn, its lantern lit, the low sun on the water

桜幻想  Sakura Fantasy

A boat journey through a Japanese river valley, in four seasons and at any hour,
rendered live in the browser.

Take the journey  ·  How it works  ·  The score  ·  中文  ·  日本語

Live demo three.js r186 WebGL 2 No engine, no framework MIT licence Featured in Ruan Yifeng's weekly, issue 415


You sit in a *tomabune*, a reed-roofed river boat, while a boatman sculls you down a river. You pass through: - morning mist on the shallows; - an avenue of cherry trees; - a vermilion drum bridge; - a village beneath a five-storey pagoda; - a bamboo gorge; - a tunnel of a thousand torii; - a lake where a torii stands in the water. Then the season turns and the journey begins again. Every tree, flower and blade of grass is drawn from photogrammetry scans of real Japanese plants. The light follows the sun through the day, and the weather changes. The music is composed as you travel, for koto, shakuhachi and shō, among field recordings from temples and gardens in Kyoto and beyond. It is about 10,000 lines of plain JavaScript on three.js, with no engine and no framework.

The same stretch of river in spring, summer, autumn and winter

The same trees across the year: blossom, then summer green, then autumn colour turning leaf by leaf, then snow on the boughs.

## The journey
Shallows of Morning Mist
朝霧の瀬  Shallows of Morning Mist
Reeds, stones and heavy dawn mist.
The Cherry Avenue
桜並木  The Cherry Avenue
Banks lined with sakura, and rafts of fallen petals.
The Vermilion Drum Bridge
朱の太鼓橋  The Vermilion Drum Bridge
The boat passes under the arch.
Village of the Five-Storey Pagoda
五重塔の里  Village of the Five-Storey Pagoda
A pagoda, a hall and a belfry. The bell tolls as you arrive.
The Bamboo Gorge
竹林峡  The Bamboo Gorge
Cliffs, walls of bamboo and a waterfall.
A Thousand Gates
千本鳥居  A Thousand Gates
A straight channel under forty-one vermilion gates.
Lake of the Sacred Tree
御神木の湖  Lake of the Sacred Tree
An island's giant sakura and a torii standing in the water.
Fireworks over the lake
花火  Summer fireworks
On summer nights. Each boom arrives at the speed of sound.
Each place opens with a classical haiku chosen for it and for the season. Thirteen of these scenes are free to download as **[4K wallpapers](https://github.com/billpwchan/sakura-fantasy/releases/tag/wallpapers-4k)** (3840×2160, straight from the renderer). ## What's inside **Real plants.** Leaves, blossom and grasses are rendered in Blender into photo atlases (colour, AO and normal), from CC0 scans of Japanese species: - sakura, momiji and konara; - black pine and sugi; - bamboo, azalea, susuki and reeds. Trees are grown in code and instanced. They have three detail tiers by distance from the river, and up close they swap to full detail. **Light, air and weather.** - A sun and sky for any hour, with height fog and god rays. - Five weathers: clear, mist, rain, storm and snow. - Snow that settles on boughs, roofs and banks. **Water.** Reflections stretch and break in the ripples, and blur with distance as real water does, so the river never reads as a mirror. Gusts roughen it in drifting patches. Lanterns, fireflies and fireworks all reflect, and each burst lays a broken column of its colour on the water. The boat leaves a Kelvin wake and a bow wave, foam gathers along the shore and petals rest on the surface. **The boat and its crew.** - The boat is built plank by plank in Blender. - The boatman and the passenger are MPFB bodies, dressed in clothes made for them: a hanten and sugegasa; a furisode, brocade obi and a red wagasa. - He sculls with two-bone IK, his hands on the *ro* through every stroke. **Night.** Lit windows, foxfire wisps and lanterns floating on the lake. Sky lanterns rise from the island. **Sound.** | Layer | What you hear | |---|---| | Score | A live score in the Japanese modes (hirajōshi, yō, kumoijōshi). The koto plays phrases, a *danmono* before the bridge and *Sakura Sakura* under the cherries in spring. The shakuhachi plays long breaths, and the shō holds chords at the shrine. | | Recordings | Temple bells from Ōhara and Zōjō-ji, a suikinkutsu and shishi-odoshi from Kyoto gardens, cicadas, bell crickets, the uguisu. | Every recording is placed by place, season and hour. [The score →](docs/SOUND.md) **Smooth.** The valley is generated in a pool of workers. A frame-time governor keeps the render scale where frames hold their budget. The quick tier draws the first frame, and full-detail assets stream in behind it. ## Controls | | | |---|---| | W S / ↑ ↓ | faster, slower | | A D / ← → | steer within the channel | | drag · wheel | look around · zoom | | C | camera: follow → seat → cinematic | | Space | stop and drift / row on | | M | sound on and off | | P | photo mode (orbit camera, PNG export) | | H | hide the interface | The kanji dock sets the season, hour, weather, camera and sound, and the scroll of the journey jumps to any place. ## Run it ```sh git clone https://github.com/billpwchan/sakura-fantasy.git cd sakura-fantasy npm install npm run dev # http://127.0.0.1:5190 ``` `npm run build` writes a static site to `dist/` that any web server can host. The assets are in the repository, so nothing else needs downloading. Any scene can be opened straight from the URL, skipping the opening: | Parameter | Meaning | Example | |---|---|---| | `z` | position along the river, from `40` (start) to about `-2300` (the lake) | `z=-1640` | | `s` | season: `0` spring, `1` summer, `2` autumn, `3` winter | `s=2` | | `h` | hour, `0`–`24` | `h=17.5` | | `w` | weather: `clear` `mist` `rain` `storm` `snow` | `w=mist` | | `mode` | camera: `follow` `seat` `cinema` | `mode=seat` | | `cam`, `look` | a fixed camera position and target, `x,y,z` | `cam=4,3,-690&look=0,6,-720` | | `tier` | `hi` streams the full-detail assets, `lo` keeps the quick tier | `tier=lo` | | `intro` | play the opening anyway | `intro` | For example, [autumn dusk at the bridge](https://sakura.billpwchan.art/?z=-660&s=2&h=17.2) or [a winter night in the village](https://sakura.billpwchan.art/?z=-860&s=3&h=21). ## How it's made

Scanned blossom and maple leaves baked into atlases, and the same leaves in the scene

| Document | What it covers | |---|---| | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | The renderer and passes, the frame, the governor, world generation, vegetation and level of detail, the boat and people, night, the journey and camera, loading tiers. | | [docs/SOUND.md](docs/SOUND.md) | The score: modes, koto gestures, ma and jo-ha-kyū, how each instrument was made from free recordings, and how the mix was measured. | | [pipeline/](pipeline) | The offline tools that made the assets: Blender scripts for the plant atlases, people, boat and props, and the audio build. | ### Performance On an Apple M4 Max at 1920×1080 @2×, the full tier runs at **60 fps** with a p95 frame time of 18.4 ms. The governor holds the render scale at 1.0 for most of the river and 0.85–0.95 in the cherry avenue, the heaviest stretch. Phones and tablets get the quick tier. ## Project layout ``` src/ ├── main.js boot, frame loop, input ├── core/ render passes, post chain, shared uniforms, loaders ├── env/ time of day, season and weather ├── world/ layout, terrain, water, trees, grass, buildings, props, boat, people, sky ├── fx/ petals, leaves, snow, rain, fireflies, wisps, lanterns, fireworks ├── journey/ the voyage, the camera director, the haiku ├── audio/ score, soundscape, sound bank └── ui/ loader, title, chapter cards, dock, About, photo mode public/assets/ textures and atlases, models, KTX2 transcoder, audio pipeline/ offline asset tools (Blender, Node, Python) scripts/ texture fetch, perf and capture harnesses deploy/ Docker + Caddy deployment ``` ## More scenes The same author's other real-time scenes, each open source and running in the browser.
Halcyon
Halcyon
A tropical atoll through one day: FFT ocean, reef, bioluminescent night · live
移ろい Utsuroi
移ろい Utsuroi
A Kyoto house and garden, walked from first light to last · live
霓虹天頂 Neon Zenith
霓虹天頂 Neon Zenith
A rain-soaked cyberpunk Hong Kong you can fly through (WebGPU) · live
## Credits The plants, textures, people and most recordings are CC0 or public domain. Two statues and six recordings are CC BY. Every source and its author is listed in [CREDITS.md](CREDITS.md). The project was inspired by Meng To's *Sakura River Valley*. None of its code or assets are used. ## Licence The code is under the [MIT licence](LICENSE). The assets keep their own licences, listed in [CREDITS.md](CREDITS.md).