Cesium supports streaming and visualizing global high-resolution terrain and water effects for oceans, lakes, and rivers. Mountain peaks, valleys, and other terrain features really show the benefit of a 3D globe compared to a 2D map.

Terrain datasets are huge, commonly totaling gigabytes or terabytes. Efficiently visualizing terrain with a low-level graphics API or with a general 3D engine involves quite a bit of work. Fortunately, Cesium has already done the heavy lifting so we only need to write a couple lines of code.

Quick start

Let’s start with an example. Open the Hello World example in Sandcastle. By default, the globe is a WGS84 ellipsoid. To add terrain using the Cesium Terrain Server, add the following code to the bottom (after the line var viewer = ...):

var terrainProvider = new Cesium.CesiumTerrainProvider({
    url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles'
});
viewer.terrainProvider = terrainProvider;

After modifying the example, press F8 to run it. To get a feel for the terrain, zoom to a mountainous area, and hold down the middle mouse button and drag to tilt to a horizon view. Here’s what Mount Everest looks like:

As we zoom closer, Cesium requests higher resolution terrain based on what parts of the globe are visible and how far away they are.

Terrain and imagery are treated separately; above, the default imagery is draped over the terrain. Any imagery provider(s) can be used with any terrain provider. See the Imagery Layers Tutorial for managing imagery.

Enabling Terrain Lighting and Water Effects

The Cesium Terrain Server also includes data for terrain lighting as well as coastline data needed for water effects. By default, the terrain server does not send lighting or coastline data with the terrain tiles; we must request the terrain lighting or coastline data when constructing a CesiumTerrainProvider.

To enabled terrain lighting, request the VertexNormals extension from the Terrain Server and enable lighting on the globe.

var terrainProvider = new Cesium.CesiumTerrainProvider({
    url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
	requestVertexNormals: true
});
viewer.terrainProvider = terrainProvider;
viewer.scene.globe.enableLighting = true;

Here is the same view of Mount Everest shown above, but now the terrain is shaded based on the location of the sun.

Water effects are enabled in a similar manner. To enable, we request the WaterMask extension from the Terrain Server as follows:

var terrainProvider = new Cesium.CesiumTerrainProvider({
    url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
	requestWaterMask: true
});
viewer.terrainProvider = terrainProvider;

Zoom to an area with water. For example, here is the San Francisco Bay:

The waves animate over time and bright specular highlights show the reflection of the sun and moon.

See the terrain example in Sandcastle to explore a few choice areas with interesting terrain and water.

Ready-to-use terrain

We maintain a catalog of Internet-accessible terrain tilesets on cesiumjs.org. These tilesets can be used in your own Cesium-based applications, usually just by adding a couple of lines of code.

Terrain providers

Cesium supports several methods for requesting terrain using terrain providers. Most terrain providers use a REST interface over HTTP to request terrain tiles as height maps. Terrain providers differ based on how requests are formatted and how terrain data is organized. Cesium has the following terrain providers:

We can access other terrain services by implementing the TerrainProvider interface. If you do so, and think it is generally useful, please contribute it to Cesium for everyone’s benefit.

As we saw above, to use a terrain provider, we construct it, and assign it by setting Viewer.terrainProvider. Terrain providers are constructed similarly to imagery providers and usually include the url of the terrain server and an optional proxy if the server does not support Cross-Origin Resource Sharing (CORS).

Some terrain providers, like CesiumTerrainProvider, include coastline data needed for animated water. The water can be customized by changing the normal map used to create waves with CentralBody.oceanNormalMapUrl. Changing the imagery provider also affects the water’s appearance because the water color is blended with the underlying imagery.

Resources

Checkout the terrain example in Sandcastle and the reference documentation for all terrain providers.