Streetwalk

An endless walk through Google Street View in the browser, with its own renderer and depth from an AI model to keep each step from warping.

3DAICreative tools
Walk it live

The demo shares one daily Google Street View allowance, so late in the day it can show a message that the limit is used up.

A Montreal street in Streetwalk mid-step: parked cars on the left, a glass office building on the right, the road running ahead into the distance
Mid-step on a Montreal street with AI depth on. Street View imagery from Google.
Status
Live demo, built in a day
Tools
WebGL 2, Google Map Tiles API, Depth Anything V2 on Transformers.js and WebGPU, Web Audio, Leaflet, OpenStreetMap, Claude Code

Streetwalk walks you down real streets without stopping. It loads Street View panoramas a few steps ahead and glides from one to the next with its own WebGL renderer, so there are no black frames and no jumps between seasons. Pick one of eight Montreal walks on the map, or let it wander.

Where it started

I wanted the slow, endless zoom of zoomquilt.org, made from real places. The first version, Earthquilt, zooms forever into satellite imagery. The next one walks Street View instead, one panorama after another, with no end.

The stock viewer broke the spell

Version one drove Google's own Street View viewer. A frame-by-frame recording of a walk showed what a viewer built for clicking does when you ask it to walk: black frames while the next place loads, blurry arrivals before the sharp tiles land, a jump from summer to November between two neighbours, and warped transitions.

Eight frames of a walk in Old Montreal one second apart: a sunny cobbled street, a blurred frame, a black frame, then an overcast street with orange traffic cones, ending in a warped frame
Version one, one frame a second. The black frame, the blur, the change of season and the warp set the brief for the rebuild.

A renderer of its own

The rebuild fetches panorama tiles from Google's Map Tiles API and draws them with WebGL. Four panoramas load ahead of the one you are walking into. Each step is a glide with a crossfade, and if the next place is not ready the view holds still instead of going black. When a junction offers several neighbours, the walk prefers one captured on the same date, so the light and the season stay put.

  1. 01

    Load ahead

    Low-resolution panorama first, then sharp tiles where the screen looks.

  2. 02

    Fit the street

    Try street shapes in tiny renders and keep the one with least ghosting.

  3. 03

    Add depth

    An AI depth map, in metres, becomes a mesh over the street model.

  4. 04

    Glide

    Move the camera and crossfade into the next panorama.

Fighting the warp

A panorama is a photo taken from one point, so moving the camera away from that point stretches it. I took the warp on in steps. The panorama is projected onto a rough street corridor rather than a sphere: pavement 2.5 m below the camera, building fronts to each side, a far sphere for the sky. Before each step, ten corridor shapes are rendered at 128 by 96 pixels and the one where the two panoramas line up best is kept. A Panini lens keeps vertical lines vertical on wide screens, more so as the view widens or swings round a corner.

Two frames of the same step at Place d'Armes, side by side: the bank's columns ghosted and doubled on the left, cleaner on the right, with people smeared in both
The same step before (left) and after (right) the distortion work. People and other things close to the camera still smear.

Depth from a model in the browser

The street corridor cannot know where a parked car is. So Depth Anything V2 (small) runs in a web worker over WebGPU on the part of each panorama you are walking into. Its output is relative, and the pavement turns it into metres: the camera is about 2.5 m up, so the true distance to the ground at each downward angle is known. The result is a 150 by 80 mesh. Each pixel also carries how much it can be trusted, and where one panorama only has the rough corridor behind a pixel, the other panorama fills it. Changing where the mesh tears, so a facade seen at a grazing angle no longer splits, took holes from 16 to 24% of the view down to 0%. In Chrome the walk went from 51 fps with depth at first to 59 fps after these fixes, with 79 to 209 ms of model time per panorama.

The same Montreal street side by side: on the left the parked cars are smeared flat, on the right with depth on they keep their shape
Depth off (left) and on (right). Parked cars keep their shape once the depth mesh is in.

Paying per tile

Street View tiles are free up to 100,000 a month, then $2 per 1,000, and a walk spends them quickly. Testing hit a daily ceiling of 15,000. Sharp tiles now load only for the columns the screen can see and the middle rows of the panorama, and the rest comes from one low-resolution image. That took a step from 12 tiles to about 8. When the daily limit is reached, the walk shows a notice and waits.

Sound and a map

The street sound is generated with Web Audio, with no recordings, and follows your speed and how close the buildings are. A dark vignette with a soft blur toward the edges keeps the eye in the middle. Click the view for a small map that follows you; click that for a big map of eight Montreal walks, 11.4 km in all, from Old Montreal to Mile End.

Decisions

Hold still, never go black

If the next panorama is late, the walk pauses on the current one, and a daily-limit error makes it wait rather than skip ahead.

Walks drawn from street lines

The Montreal walks follow OpenStreetMap street lines, with no router in between. A script averages the points in 15 m slices along each street, so both sides of a divided road collapse into one centre line to walk down.

Measure the warp, then pick

No single street shape suits both a narrow lane and an open square, so the renderer tries ten for every step and keeps the one with least ghosting. The readback is queued on the GPU, so the test never stalls the walk.