Back

Willow Ferry

A Jiangnan water town rendered live in the browser — white walls and dark tiles, horse-head gables, a stone arch bridge, wupeng boats, willows and jade-green water — with a whole day going round in about seven minutes. Switch between six viewpoints, walk the banks, or take a wupeng boat down the canal and under the bridge; the whole town is generated procedurally by Blender scripts.

Author: Theodore
Try it live
Willow FerryTry it live

Description

Willow Ferry is a Jiangnan water town rendered live in the browser: white walls and dark tiles, horse-head gables, lattice shopfronts under lantern-hung eaves, a stone arch bridge over the canal, wupeng boats moored at the steps and willows trailing over jade-green water. The loading screen sets the tone: “Follow the water. Come home a little late.”

The town keeps its own day — golden hour, blue hour, moonlit night, dawn, morning, afternoon — going round in about seven minutes, with the sun and the moon always moving and the shadows creeping round after them. Hold T to let the hours run faster, or press 1–5 to jump straight to afternoon, golden hour, blue hour, moonlight or misty rain. Misty rain is weather rather than an hour: choosing it stops the clock until you pick another hour.

The ←/→ keys step through six viewpoints: Willow Bank, Moon Bridge, Ferry Steps, Tea Pavilion, Town in the Mist and The Slow Boat. Each comes with a short line, some changing with the hour — at golden hour Willow Bank reads “The sun rests in the arch.” — and the Moon Bridge line is a take on Bian Zhilin’s poem “Fragment” (断章): “You stand on the bridge to watch the view. / From a window, someone watches you.”

Drag to look around, scroll to glide forward, walk with WASD (Shift to go faster, Q/E to rise and sink) and click to focus. The aperture button steps from f/1.4 to f/16, and the last stop turns depth of field off so everything is sharp; the camera has a gentle hand-held sway (Drift) that can be switched off, and H hides the interface. Press “Ride the boat” and the camera glides down onto the bow as the boat drifts along the canal: ←/→ (A/D) steer, ↑ (W) rows harder, ↓ (S) eases off, and when you let go it finds its line again. How far it may stray was measured along the route, so it never runs into the embankments, the moored boats or the bridge’s arch.

The whole town is made by code: the houses, the stone arch bridge, wupeng boats, lanterns, willows, peach trees and the embankment’s blocks and steps are all generated by Blender Python scripts and exported as GLB. The house generator lays out the plots, picks house types, sets the horse-head gables by height and slips small walled gardens in between; only the hero house by the ferry steps is placed by hand. The skies and some of the plaster, stone, timber and pebble surfaces are CC0 photo skies and scanned textures from Poly Haven; every other texture, and all the sound, comes from the scripts too.

The interface is in English only, and the sound starts with your first click. It’s best in desktop Chrome, Edge or Safari, and falls back to WebGL2 where WebGPU is missing; the first visit downloads a little over 40 MB, so the loading screen stays up for a moment.

How it runs in the browser

The web side is built on three.js r186’s WebGPU renderer with Vite, with the models meshopt-compressed. As the models come in from Blender, their materials are rebuilt by name in TSL: water-line stains, moss, caustics, weathering, wind sway and the night glow of windows and lanterns are all worked out in shaders, and the same TSL materials run under WebGL2 as well.

Most of the effort went into the water: reflection, refraction, turbidity and absorption, sun and moon glitter and the moon’s path, rain ripples, wind patches, the boat’s wake and the water pushed aside at its bow. The sky is a Poly Haven photo sky that cross-fades between hours and also supplies the ambient light and the direction of the sun and moon; cloud shadows drift over the town, the hills and the water, low mist banks lie on the canal, and there are fireflies, floating motes and rain streaks.

Post-processing adds SSAO (on ambient light only), the mist banks, bloom, depth of field, grading and FXAA. Autofocus works like a DSLR’s, casting a ray from the centre of the frame (accelerated by three-mesh-bvh), or you can click to choose the focus point. To keep it fast the scene is split into layers: fine detail such as cover tiles, lattice and brass is drawn only in the main view and hidden altogether beyond 28 metres; the canal bed and pebbles stay out of the reflections; and the stonework and trees are kept out of the SSAO pre-pass. The key light’s shadows are redrawn when the light moves and every fifth frame otherwise; the boat’s parts are merged by material on load, and the grass and embankment stones are drawn instanced.

All the sound is synthesised live with Web Audio — there isn’t a single audio file: water lapping and dripping (louder near the water), wind in the willows, birds by day, crickets and frogs at night, a distant temple bell, oar strokes when you ride the boat, and a sparse pentatonic pluck for music.