ImageToCity

Upload a photo. Get a tiny night city. Nothing leaves your browser.

Live demo

Role
Design & build
When
2026
Stack
  • React
  • TypeScript
  • React Three Fiber

ImageToCity samples a photo into an 84-column grid and rebuilds it as roughly 7,000 cubes plus a few bounded instanced details: park trees, bridge decks, waterfront lamps, and a small low-poly flock. Zoom in and tiny traffic marks and walking lights wake up along the generated street and park edges. Brightness becomes height, posterized into five zones, so the image reads as terraced architecture: a little city at night, lit by one warm lamp. The upload pipeline runs entirely in the browser.

The city plan

Water is flood-filled from the image’s dark edges, so it pools around the borders like rivers, with lighter cells where it meets land.
Parks are zoned, not detected: the flattest mid-tone stretches of land, where the dullest buildings would otherwise go, get reserved as parkland, jittered so it reads as canopy, with a few amber path lamps and low-poly trees. Genuinely green pixels still tip the vote, so a lawn in your photo becomes a park.
Buildings draw materials by height band: brownstone low, brick and limestone mid, glass towers on top, clustered into neighborhoods by value noise, then tinted by the photograph. Each cube borrows the hue of the pixel it stands on, damped to night levels, so every photo grades its own city.
About 300 windows flicker in the darkest buildings, shore lamps trace the waterline, bridges cross narrow canals, a small flock drifts over the skyline, zoom-revealed cars and walkers move through the grid, and one rooftop beacon blinks on the tallest tower.

Press "show original" and the city folds flat: every cube damps to a thin slab on a staggered wave, the street gaps close, and the posterized city colors bloom into the true colors of the photograph while the lamp crossfades to gallery light. Press it again and the city rebuilds. The easing runs on real delta time, so the choreography takes the same one-and-a-half seconds on every machine.