Slopcouver Labs

Labs · Experiment 3 of 7 · LiDAR, Open data, The game

False Creek from the air: a LiDAR mesh with the orthophoto draped on it

Started
Updated
Status
concluded
Verdict
Mixed

Can the City's open LiDAR and orthophotos alone make a photoreal aerial view of a neighbourhood that is small and fast enough for a web game?

Why

Seen from a helicopter, Slopcouver's procedural buildings are convincing in shape but not in surface. Commercial photoreal 3D cities come from oblique aerial photography and photogrammetry. Vancouver publishes something cheaper: a 2022 airborne LiDAR survey and 7.5 cm orthophotos, both under the City's open licence. We wanted to know how far those two alone get you, and at what size.

Hypothesis

A surface model built from the highest LiDAR return in each 0.5 m cell, meshed and textured with the orthophoto, will (1) read as real from 200 m up and above, (2) fit a 2 km² area into under 50 MB at full detail and under 5 MB at the coarsest level, and (3) build in minutes on one desktop.

Method

  • Area: about 1.75 × 1.25 km (2.2 km²), from the Burrard Bridge to the Cambie Bridge and from 2nd Avenue north to about Nelson Street. Cut into 35 tiles of 250 m.
  • Surface model: each 0.5 m cell takes the highest return that isn't noise or withheld: roofs, tree crowns, bridge decks, and ground where it's open. Water cells are flattened to the LiDAR's measured False Creek surface (−1.07 m, CGVD28). Gaps up to 4 m are filled from neighbours. Counts: 6.92 M cells measured, 1.50 M filled, 0.33 M water-filled, 0.19 M water flattened.
  • Mesh: heights at grid nodes, box-filtered to each level's step (0.5, 1 and 2 m); each quad split along its flatter diagonal (keeps eaves straighter); simplified with meshoptimizer 0.22.0 to an absolute error of 0.15, 0.4 and 1.0 m, with tile borders locked so neighbouring tiles share identical border vertices.
  • Texture: the orthophoto cut to a 0.1 m window (GDAL), sampled at 4096² per tile, downsized to 2048, 1024 and 512 px (12, 24 and 49 cm per pixel), WebP quality 80 (sharp 0.34.3).
  • Format: glTF binary with quantised positions, meshopt compression, WebP textures and unlit materials (the light is already in the photo). One draw call per tile. The glTF validator reports 0 errors.
  • Hardware and cost: one Debian desktop (Ryzen 7 3700X); renders in headless Chromium with software WebGL. No cost.

Results

Four aerial renders of the False Creek LiDAR mesh: towers, Granville Island, marinas and the bridges
Aerial renders of the full-detail mesh. Towers, the Granville Island market roofs, trees, marinas, the seawall and three bridges read correctly. Look at the tower walls and under the bridges for the failures listed below.
LevelGrid / errorTextureTile size (min / median / max)Triangles per tile (median)All 35 tiles
Full (0)0.5 m / 0.15 m2048² (12 cm)623 / 1,066 / 1,405 KB109 k37.2 MB; 3.54 M triangles (of 17.5 M on the full grid)
Medium (1)1 m / 0.4 m1024² (24 cm)192 / 322 / 392 KB21.8 k11.0 MB; 0.71 M triangles
Coarse (2)2 m / 1.0 m512² (49 cm)46 / 92 / 117 KB5.1 k3.1 MB; 0.17 M triangles
Compressed geometry is about 45% of the full level and 30% of the others; the rest is texture.

Under 4 minutes from the LiDAR and orthophoto archives to all 105 tiles (about 2.4 s a tile). In a local viewer all 35 full-detail tiles load and decode in about 0.6 s; the medium level in 0.37 s.

What a 2.5D surface and a plain orthophoto can't do

  • Walls are stretched roof colour. An orthophoto has no facades. Fix: draw procedural facades on walls and use the mesh only for roofs, trees and ground.
  • Bridge decks hang on curtains down to the water. The highest return hides the gap under a deck, and this survey has no bridge class. Fix: cut deck footprints out of the surface and model decks as their own thin meshes.
  • Boat masts make white spikes over the marinas, and tree crowns drip. Fix: a low percentile instead of the maximum over water; a small median over crowns.
  • Tall towers lean. The orthophoto isn't a true orthophoto, so tower roofs are offset and their sides smear onto the ground.
  • No skirts between levels yet, so cracks would show where a full-detail tile meets a coarse one.

Limitations and threats to validity

  • "Reads as real" is our judgement from renders, not a user study.
  • The orthophoto–LiDAR fit was checked by eye (roof colours sit on roofs), not measured; the two datums differ by under 1 m here.
  • The height datum offset to the game (5.61 m) is a city-wide median, not checked inside this box. It is one parameter in each tile, so it can change without a rebuild.
  • City-wide figures below are extrapolations (the LiDAR covers about 80 times this box), not measurements.

Verdict

Supported From 200 m up it reads as real; 37 MB full / 3.1 MB coarse for 2.2 km²; under 4 minutes to build.

Not supported as a street-level view: walls, the space under bridges and tall towers are wrong in ways only extra data or modelling can fix.

Practical application

  • For the game: a photoreal far field for flying and the helicopter, with the game's own buildings and facades up close.
  • For planning and the public: a free, browsable 3D context model of any neighbourhood from data the City already publishes, useful for shadow and view discussions at block scale.
  • For other cities: any city with open airborne LiDAR and orthophotos can do this; nothing is Vancouver-specific.
  • What it would take city-wide (estimates): about 3 GB at full detail, 0.9 GB medium, 0.25 GB coarse; about 5 hours of build on one process, under 1.5 h with four. Plus streaming by distance, skirts between levels, the deck cut-outs, and GPU-compressed textures (WebP decodes to 16 MB of GPU memory per full-detail tile).

Reproducibility

Scripts (Slopcouver repository, private for now): dsm.py (surface model), build.mjs (mesh, texture, glTF), render.cjs (renders), viewer.html (a standalone three.js viewer: serve the folder and open viewer.html?lod=lod1).

Data and credits: City of Vancouver LiDAR 2022 and orthophotos 2022, OGL–Vancouver. meshoptimizer (MIT), sharp (Apache-2.0), three.js (MIT), GDAL (MIT/X).