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

| Level | Grid / error | Texture | Tile size (min / median / max) | Triangles per tile (median) | All 35 tiles |
|---|---|---|---|---|---|
| Full (0) | 0.5 m / 0.15 m | 2048² (12 cm) | 623 / 1,066 / 1,405 KB | 109 k | 37.2 MB; 3.54 M triangles (of 17.5 M on the full grid) |
| Medium (1) | 1 m / 0.4 m | 1024² (24 cm) | 192 / 322 / 392 KB | 21.8 k | 11.0 MB; 0.71 M triangles |
| Coarse (2) | 2 m / 1.0 m | 512² (49 cm) | 46 / 92 / 117 KB | 5.1 k | 3.1 MB; 0.17 M triangles |
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).