| name | cesiumjs-terrain-environment |
| description | CesiumJS terrain, globe, and environment - TerrainProvider, Globe, sampleTerrain, atmosphere, sky, fog, lighting, shadows, panoramas. Use when configuring terrain providers, querying terrain heights, customizing atmosphere or sky rendering, adding panoramas, or adjusting scene lighting and shadows. |
CesiumJS Terrain, Globe & Environment
Version baseline: CesiumJS v1.142 | ES module imports (import { ... } from "cesium";)
Terrain Providers
Terrain is served through TerrainProvider implementations. Use async factory methods
(fromIonAssetId, fromUrl), not the constructor directly.
Cesium Ion World Terrain
import { Viewer, Terrain } from "cesium";
const viewer = new Viewer("cesiumContainer", {
terrain: Terrain.fromWorldTerrain({
requestVertexNormals: true,
requestWaterMask: true,
}),
});
CesiumTerrainProvider from Ion Asset / URL
import { CesiumTerrainProvider } from "cesium";
const tp = await CesiumTerrainProvider.fromIonAssetId(3956, {
requestVertexNormals: true,
});
viewer.scene.globe.terrainProvider = tp;
const tp2 = await CesiumTerrainProvider.fromUrl(
"https://my-server.example.com/terrain",
{ requestVertexNormals: true },
);
EllipsoidTerrainProvider (Flat Globe)
import { EllipsoidTerrainProvider } from "cesium";
viewer.scene.globe.terrainProvider = new EllipsoidTerrainProvider();
CustomHeightmapTerrainProvider (Procedural)
import { CustomHeightmapTerrainProvider } from "cesium";
viewer.scene.globe.terrainProvider = new CustomHeightmapTerrainProvider({
width: 32,
height: 32,
callback: function (x, y, level) {
const buf = new Float32Array(32 * 32);
for (let r = 0; r < 32; r++) {
for (let c = 0; c < 32; c++) {
buf[r * 32 + c] = Math.sin((x + c / 32) * 6.28) * 5000;
}
}
return buf;
},
});
Sampling Terrain Heights
Both functions mutate the input Cartographic[] in place (setting .height) and
return a promise resolving to the same array.
import { sampleTerrain, sampleTerrainMostDetailed, Cartographic } from "cesium";
const positions = [
Cartographic.fromDegrees(86.925145, 27.988257),
Cartographic.fromDegrees(87.0, 28.0),
];
await sampleTerrain(viewer.scene.globe.terrainProvider, 11, positions);
await sampleTerrainMostDetailed(viewer.scene.globe.terrainProvider, positions);
await sampleTerrainMostDetailed(provider, positions, true);
Globe Configuration
Access via viewer.scene.globe. Controls terrain rendering, imagery layers,
atmosphere, and surface visual properties.
const globe = viewer.scene.globe;
globe.show = true;
globe.maximumScreenSpaceError = 2;
globe.tileCacheSize = 100;
globe.enableLighting = true;
globe.dynamicAtmosphereLighting = true;
globe.dynamicAtmosphereLightingFromSun = false;
globe.lambertDiffuseMultiplier = 0.9;
globe.showGroundAtmosphere = true;
globe.atmosphereHueShift = 0.0;
globe.atmosphereSaturationShift = 0.0;
globe.atmosphereBrightnessShift = 0.0;
globe.depthTestAgainstTerrain = false;
globe.showWaterEffect = true;
globe.shadows = Cesium.ShadowMode.RECEIVE_ONLY;
globe.baseColor = Cesium.Color.BLUE;
globe.backFaceCulling = true;
globe.showSkirts = true;
Globe.pick and Globe.getHeight
const ray = viewer.camera.getPickRay(windowPosition);
const hit = viewer.scene.globe.pick(ray, viewer.scene);
const h = viewer.scene.globe.getHeight(Cesium.Cartographic.fromDegrees(-105, 40));
Terrain Exaggeration
viewer.scene.verticalExaggeration = 2.0;
viewer.scene.verticalExaggerationRelativeHeight = 0.0;
Globe Translucency
Makes the globe see-through for underground/subsurface visualization.
const globe = viewer.scene.globe;
globe.translucency.enabled = true;
globe.translucency.frontFaceAlpha = 0.5;
globe.translucency.backFaceAlpha = 1.0;
globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar(
1.5e2, 0.5,
8.0e6, 1.0,
);
globe.translucency.rectangle = Cesium.Rectangle.fromDegrees(-120, 30, -80, 50);
Elevation Band Material
Color the globe surface by elevation.
import { createElevationBandMaterial, Color } from "cesium";
viewer.scene.globe.material = createElevationBandMaterial({
scene: viewer.scene,
layers: [{
entries: [
{ height: 0, color: new Color(0.0, 0.0, 0.5, 1.0) },
{ height: 500, color: new Color(0.0, 0.8, 0.0, 1.0) },
{ height: 2000, color: new Color(0.6, 0.3, 0.1, 1.0) },
{ height: 5000, color: Color.WHITE },
],
}],
});
SkyAtmosphere
Atmospheric haze ring around the globe limb. 3D mode only.
const sky = viewer.scene.skyAtmosphere;
sky.show = true;
sky.perFragmentAtmosphere = false;
sky.atmosphereLightIntensity = 50.0;
sky.hueShift = 0.0;
sky.saturationShift = 0.0;
sky.brightnessShift = 0.0;
sky.atmosphereRayleighCoefficient = new Cesium.Cartesian3(5.5e-6, 13.0e-6, 28.4e-6);
sky.atmosphereMieCoefficient = new Cesium.Cartesian3(21e-6, 21e-6, 21e-6);
sky.atmosphereMieAnisotropy = 0.9;
SkyBox
Star field cube map behind the globe. 3D mode only.
import { SkyBox } from "cesium";
viewer.scene.skyBox = SkyBox.createEarthSkyBox();
viewer.scene.skyBox = new SkyBox({
sources: {
positiveX: "skybox_px.png", negativeX: "skybox_nx.png",
positiveY: "skybox_py.png", negativeY: "skybox_ny.png",
positiveZ: "skybox_pz.png", negativeZ: "skybox_nz.png",
},
});
Fog
Blends distant terrain toward atmosphere color and culls far tiles. 3D mode only.
const fog = viewer.scene.fog;
fog.enabled = true;
fog.renderable = true;
fog.density = 0.0006;
fog.visualDensityScalar = 0.15;
fog.maxHeight = 800000.0;
fog.heightFalloff = 0.59;
fog.screenSpaceErrorFactor = 2.0;
fog.minimumBrightness = 0.03;
Sun and Moon
viewer.scene.sun = new Cesium.Sun();
viewer.scene.sun.show = true;
viewer.scene.moon.show = true;
Lighting
scene.light controls the scene light source. Default is SunLight (follows clock).
import { SunLight, DirectionalLight, Cartesian3, Color } from "cesium";
viewer.scene.light = new SunLight({ color: Color.WHITE, intensity: 2.0 });
viewer.scene.light = new DirectionalLight({
direction: new Cartesian3(0.2, -0.5, -0.8),
color: Color.WHITE,
intensity: 1.5,
});
viewer.scene.globe.enableLighting = true;
DynamicAtmosphereLightingType enum (NONE, SCENE_LIGHT, SUNLIGHT) is configured
via globe.enableLighting, globe.dynamicAtmosphereLighting, and
globe.dynamicAtmosphereLightingFromSun flags.
Shadows
Cascaded shadow maps from the scene light source.
viewer.shadows = true;
const sm = viewer.shadowMap;
sm.maximumDistance = 5000.0;
sm.softShadows = true;
sm.darkness = 0.3;
sm.fadingEnabled = true;
viewer.scene.globe.shadows = Cesium.ShadowMode.RECEIVE_ONLY;
Panoramas (v1.139+)
360-degree imagery at a scene location. Two formats: equirectangular and cube map.
EquirectangularPanorama
import {
EquirectangularPanorama, Cartesian3,
HeadingPitchRoll, Transforms, Math as CesiumMath,
} from "cesium";
const position = Cartesian3.fromDegrees(-75.17, 39.95, 100.0);
const hpr = new HeadingPitchRoll(CesiumMath.toRadians(45), 0, 0);
const transform = Transforms.headingPitchRollToFixedFrame(position, hpr);
viewer.scene.primitives.add(new EquirectangularPanorama({
transform,
image: "path/to/equirectangular-360.jpg",
radius: 100000.0,
}));
CubeMapPanorama
import { CubeMapPanorama, Cartesian3, Transforms, Matrix3, Matrix4 } from "cesium";
const pos = Cartesian3.fromDegrees(-122.42, 37.77, 10.0);
const northDown = Transforms.localFrameToFixedFrameGenerator("north", "down");
const xform = Matrix4.getMatrix3(northDown(pos), new Matrix3());
viewer.scene.primitives.add(new CubeMapPanorama({
sources: {
positiveX: "px.jpg", negativeX: "nx.jpg",
positiveY: "py.jpg", negativeY: "ny.jpg",
positiveZ: "pz.jpg", negativeZ: "nz.jpg",
},
transform: xform,
}));
GoogleStreetViewCubeMapPanoramaProvider
import { GoogleStreetViewCubeMapPanoramaProvider, Cartographic } from "cesium";
const provider = new GoogleStreetViewCubeMapPanoramaProvider({
key: "YOUR_GOOGLE_STREETVIEW_API_KEY",
});
const pano = await provider.loadPanorama({
cartographic: Cartographic.fromDegrees(-122.42, 37.77, 0),
});
viewer.scene.primitives.add(pano);
Terrain Provider Events
viewer.scene.globe.terrainProviderChanged.addEventListener((newProvider) => {
console.log("Terrain changed:", newProvider.constructor.name);
});
Performance Tips
- Increase
maximumScreenSpaceError from 2 to 4+ on mobile -- single biggest
terrain perf knob.
- Keep fog enabled (default) -- culls distant tiles, reducing draw calls.
- Avoid per-frame
verticalExaggeration changes -- forces terrain tile reloads.
- Set
requestVertexNormals: true only when lighting is enabled -- doubles tile size.
- Skip
requestWaterMask (default false) when showWaterEffect is off.
- Prefer
sampleTerrain over sampleTerrainMostDetailed when approximate heights
suffice -- resolves faster with fewer tile requests.
- Batch terrain sampling -- pass all positions in one array to share tile loads.
- Tune
tileCacheSize -- increase for zoom-heavy workflows, decrease for memory.
- Disable
showGroundAtmosphere on non-Earth ellipsoids to avoid artifacts.
- Keep
depthTestAgainstTerrain = false (default) to avoid z-fighting with
labels and billboards near the surface.
Quick Reference
| Class / Function | Purpose |
|---|
CesiumTerrainProvider.fromIonAssetId(id, opts) | Ion terrain asset |
CesiumTerrainProvider.fromUrl(url, opts) | Self-hosted terrain |
EllipsoidTerrainProvider | Flat ellipsoid (no terrain) |
CustomHeightmapTerrainProvider | Procedural/callback terrain |
ArcGISTiledElevationTerrainProvider | ArcGIS elevation service |
sampleTerrain(provider, level, positions) | Heights at fixed LOD |
sampleTerrainMostDetailed(provider, positions) | Heights at max LOD |
Globe | Surface rendering, terrain, atmosphere |
GlobeTranslucency | See-through globe for underground views |
createElevationBandMaterial | Color surface by elevation |
SkyAtmosphere | Atmospheric limb glow |
SkyBox / SkyBox.createEarthSkyBox() | Star field cube map |
Fog | Distance fog and terrain culling |
Sun / Moon | Celestial body rendering |
SunLight | Light following the Sun |
DirectionalLight | Fixed-direction light |
ShadowMap | Cascaded shadow maps |
EquirectangularPanorama | 360-degree panorama |
CubeMapPanorama | Cube map panorama |
GoogleStreetViewCubeMapPanoramaProvider | Google Street View panoramas |
DynamicAtmosphereLightingType | Enum: NONE, SCENE_LIGHT, SUNLIGHT |
ShadowMode | Enum: DISABLED, ENABLED, CAST_ONLY, RECEIVE_ONLY |
See Also
- cesiumjs-viewer-setup -- Viewer initialization, Ion token, Scene configuration
- cesiumjs-imagery -- Imagery providers and layer management
- cesiumjs-spatial-math -- Cartesian3, Cartographic, Transforms, coordinate math