Short answer

CesiumJS is an open-source WebGL engine for streaming 3D geospatial content on a true ellipsoidal globe. For geology it earns its place when vertical relationships are the point: draping a geological map over high-resolution terrain, showing borehole traces and modelled surfaces in 3D, streaming LiDAR point clouds, or giving a project globe-scale context. It is heavier than MapLibre or deck.gl and unnecessary for flat thematic maps — reach for it only when the third dimension carries real information, and keep a clean 2D analytical view for tasks where comparison, not perspective, is what the user needs.

Where CesiumJS fits among web map engines

The three you will weigh:

  • MapLibre GL — 2D/2.5D vector and raster tiles with a JSON style spec; excellent for thematic cartography, fast, light. Limited true 3D (extrusions, some terrain).
  • deck.gl — GPU layers for very large datasets (millions of points, arcs, hexbins), composable over MapLibre or standalone. Visualization-first, not a globe.
  • CesiumJS — a full 3D globe with streamed terrain, 3D Tiles, an accurate WGS84 ellipsoid, sun/lighting, and camera control in geographic space.

For geology the decision is concrete. If the deliverable is "compare two alteration layers side by side," that is a 2D job — MapLibre. If it is "explore millions of geochemistry points fast," that is deck.gl. If it is "fly over a draped geological map, see boreholes pierce the terrain, and toggle a modelled fault surface," that is CesiumJS.

How CesiumJS handles terrain

Cesium streams terrain as quantized-mesh tiles — a compact, TIN-based (triangulated) format with level-of-detail keyed to the camera, so you only download the resolution you can see. You attach a terrain provider and overlay imagery:

const viewer = new Cesium.Viewer('cesiumContainer', {
  terrain: Cesium.Terrain.fromWorldTerrain(),   // streamed global terrain
});
// Drape a geological map (your own WMTS / tiled imagery)
viewer.imageryLayers.addImageryProvider(
  new Cesium.UrlTemplateImageryProvider({
    url: 'https://your.server/geology/{z}/{x}/{y}.png',
  })
);

You can host your own terrain from a high-resolution project DEM. The usual path is to convert a GeoTIFF DEM into quantized-mesh tiles with Cesium Terrain Builder (ctb-tile) or the cesium-terrain-builder Docker image, then serve the tile pyramid statically. Crucially, terrain expects heights relative to the WGS84 ellipsoid; project DEMs are almost always in an orthometric/geoid vertical datum (e.g. EGM2008, NAVD88). Skipping the geoid-to-ellipsoid conversion offsets your whole surface vertically by tens of metres in many regions.

Vertical exaggeration for subtle geological relief is a one-liner on modern Cesium:

viewer.scene.verticalExaggeration = 2.0;

Use it sparingly and always label it, because exaggeration changes apparent dip and slope and can mislead a reader into over-reading structure.

Coordinates, datums and accuracy

CesiumJS works on the WGS84 ellipsoid internally and uses Earth-Centred Earth-Fixed (ECEF) Cartesian coordinates under the hood; you usually feed it longitude/latitude/height. For survey-grade geological work, be deliberate about reference frames. WGS84 and ITRF realizations differ over time and continents move (plate motion is centimetres per year), so a high-precision local geodetic datum will not align pixel-perfectly with global WGS84. Reproject vector data to EPSG:4326 before loading (ogr2ogr -t_srs EPSG:4326 out.geojson in.gpkg), and document the source CRS and vertical datum in the app's metadata panel so users know the registration tolerance.

3D content: tiles, models and point clouds

  • 3D Tiles (an OGC community standard) is Cesium's format for massive tiled 3D content: photogrammetry meshes, BIM, point clouds and tiled models with spatial indexing and LOD. Convert LiDAR/LAS or large meshes to 3D Tiles and stream them.
  • glTF / GLB for individual models — a modelled fault surface, an orebody shell, a stratigraphic horizon exported from a geomodelling package.
  • CZML / GeoJSON for vector and time-dynamic data — borehole collars, sample points, animated monitoring data.

A geological model built in dedicated software (implicit modelling, block models) is best authored there and exported to glTF or 3D Tiles for the web; CesiumJS is the viewer/streamer, not the modeller.

Subsurface visualization

Cesium can render geometry below the ellipsoid and supports translucent terrain (viewer.scene.globe.translucency), letting users see underground models through a faded surface — useful for boreholes, tunnels and modelled horizons. The camera can be placed below ground. This works well for visual subsurface context, but Cesium is fundamentally a surface-and-globe engine: full voxel block models and implicit geology are heavy and better pre-processed into tiled glTF/3D Tiles surfaces and section meshes rather than computed in the browser.

A worked geology app outline

A defensible architecture for a 3D geological web map:

  1. Prepare data server-side. DEM → quantized-mesh (correct ellipsoidal heights). Geological map → tiled WMTS/imagery. Boreholes → GeoJSON/CZML polylines. Modelled surfaces → glTF/3D Tiles.
  2. Initialise the viewer with world or project terrain; add the geology imagery layer draped on top.
  3. Add 3D content: load fault/horizon glTF, point-cloud 3D Tiles, borehole entities with depth-coloured polylines.
  4. Build the UI: layer toggles, an opacity slider for the geology drape, a translucency control for subsurface, a vertical-exaggeration control (labelled), and a metadata/source panel.
  5. Test at real data volume, not a toy AOI — terrain tile counts and point-cloud sizes dominate performance.
  6. Expose uncertainty: confidence fields on modelled surfaces, clear source/date notes, and a visible note when exaggeration is on.

Common pitfalls and why they happen

  • Ellipsoidal vs geoid height mismatch. Loading an orthometric DEM as ellipsoidal heights shifts the surface vertically; convert via the geoid model first.
  • Adding 3D for spectacle. A globe fly-through looks impressive but obscures quantitative comparison; if the task is "which is higher/which changed," a 2D view is clearer.
  • Unlabelled vertical exaggeration. Readers infer dip and slope from the render; exaggeration silently distorts both.
  • Sending desktop files to the browser. Raw GeoTIFFs and large shapefiles will not stream; you need quantized-mesh, 3D Tiles, vector tiles or tiled imagery.
  • Ignoring CRS/datum registration. Mixing a local high-precision datum with global WGS84 produces a sub-metre to metre misalignment that matters for survey work.
  • Treating Cesium as a modeller. Block models and implicit geology belong in dedicated tools; export results for Cesium to display.

Quality and validation

  • Confirm the DEM's vertical datum and convert geoid→ellipsoid before tiling.
  • Verify vector data is in EPSG:4326 and registers against terrain features (ridgelines, coastlines).
  • State whether vertical exaggeration is applied and at what factor, in the UI.
  • Test terrain and 3D-tile load times with production-scale data and on mid-range hardware.
  • Surface source, date, CRS and model confidence in a metadata panel rather than hiding them behind a polished interface.

Bathyl perspective

We use CesiumJS where the third dimension genuinely carries geological meaning — draped maps over relief, boreholes, modelled surfaces and point clouds — and we keep complementary 2D views for quantitative comparison. The interface is built to make the data inspectable: correct datums, labelled exaggeration, and visible provenance, so a fly-through never quietly becomes fiction.

Related reading

Sources