Skip to content
Sample of Pixel City — top-down procedural city

shader_legends · PolygoncityPixelCity

Pixel City — top-down procedural city

A top-down 50x50 procedural city built from a deterministic hash of grid cells. Every cell is classified as either road or building lot; buildings draw height from a value-noise field, get a colour from the hash, and (when in night mode) get a sprinkling of warm yellow windows. The camera slowly pans across the city so it feels like an aerial flyover, paying homage to Shamus Young's Pixel City screensaver and the many Shadertoy reworks of it (Polygoncity, Eiffie's Tokyo, polygoncity packs).

Original: https://www.shadertoy.com/view/Xtf3zn

▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.

Family
shader_legends
Source
shader legends
Evolution
cellular
Render
voxel_grid
Complexity
medium
Agents
0
Year
2009
Author
Shamus Young (Pixel City, 2009) — Shadertoy community reworks (Polygoncity, polygoncity, Eiffie's Tokyo)

Math essence

Each grid cell (cx, cy) is hashed to (a, b, c, d). If cx%6==0 or cy%6==0 the cell is a road (gray). Otherwise with probability a > 0.18 a building is placed; its visual height is a noise-driven factor 0.45 + 0.55*(0.6*value_noise + 0.4*value_noise), its colour is one of four warm-cool palette seeds, and lit windows are placed at a stride derived from roof_seed when in night mode. The canvas is rendered at tile resolution and the city pans modulo its tile period for endless flight.

Parameters

Name Type Default Range Description
dim int 400 160–800 Square output size in pixels.
cells int 50 10–100 Number of city cells per side.
block int 8 1–32 Visual block stride (per-cell pixel scale).
road_width int 1 0–4 Half-width of the road grid lines.
window_density float 0.35 0.05–1.5 Probability of placing windows on a building.
pan_speed float 0.18 -2–2 Aerial pan speed; positive pans down-right.
night bool true null–null Night mode (lit yellow windows on dark sky) vs day mode.

Reference

First 60 lines of reference.py. Full source: library_external/shader_legends/PolygoncityPixelCity/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


def _hash_int(x: int, y: int, seed: int) -> int:
    """Deterministic pseudo-random int from grid coordinates."""
    h = (np.int64(x) * np.int64(73856093)) ^ (np.int64(y) * np.int64(19349663)) ^ (np.int64(seed) * np.int64(83492791))
    h = h & np.int64(0xFFFFFFFF)
    h ^= h >> np.int64(13)
    h = (h * np.int64(0x5BD1E995)) & np.int64(0xFFFFFFFF)
    return int(h & np.int64(0x7FFFFFFF))


def _h2(x: int, y: int, seed: int) -> tuple[float, float]:
    h = _hash_int(x, y, seed)
    a = ((h & 0xFFFF) / 65535.0)
    b = (((h >> 16) & 0xFFFF) / 65535.0)
    return a, b


def _value_noise(x: float, y: float, seed: int) -> float:
    xi = int(np.floor(x))
    yi = int(np.floor(y))
    xf = x - xi
    yf = y - yi
    u = xf * xf * (3.0 - 2.0 * xf)
    v = yf * yf * (3.0 - 2.0 * yf)
    n00, _ = _h2(xi, yi, seed)
    n10, _ = _h2(xi + 1, yi, seed)
    n01, _ = _h2(xi, yi + 1, seed)
    n11, _ = _h2(xi + 1, yi + 1, seed)
    nx0 = n00 * (1 - u) + n10 * u
    nx1 = n01 * (1 - u) + n11 * u
    return nx0 * (1 - v) + nx1 * v


class PolygoncityPixelCity:
    """Top-down procedural pixel city — Polygoncity / PixelCity.

    Inspired by Shamus Young's *Pixel City* screensaver (2009) and the
    Shadertoy community's many procedural-city tributes (Polygoncity,
    polygonal/low-poly city packs, Eiffie's Tokyo etc.). Every cell of a
    50×50 grid is classified as either *road* or *building lot* by a
    deterministic checker plus noise. Buildings are coloured boxes with
    a height drawn from a noise field; lit yellow windows are speckled
    on each building face; the camera slowly pans across the city.
    """

    family: ClassVar[str] = "shader_legends"
    sketch: ClassVar[str] = "polygoncitypixelcity"

    _GRID: ClassVar[int] = 50

    def __init__(
        self,
        dim: int = 400,
        cells: int = 50,

Try running it locally

The reference implementation is self-contained Python with numpy. Install the package and run:

python library_external/shader_legends/PolygoncityPixelCity/reference.py

Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.

More from shader legends

See all shader_legends artworks →