Install
$ agentstack add skill-cesiumgs-cesiumjs-skills-cesiumjs-terrain-environment ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
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, // smoother lighting
requestWaterMask: true, // ocean water effect
}),
});
CesiumTerrainProvider from Ion Asset / URL
import { CesiumTerrainProvider } from "cesium";
// By Ion asset ID (e.g. 3956 = Arctic DEM)
const tp = await CesiumTerrainProvider.fromIonAssetId(3956, {
requestVertexNormals: true,
});
viewer.scene.globe.terrainProvider = tp;
// By URL (self-hosted terrain server)
const tp2 = await CesiumTerrainProvider.fromUrl(
"https://my-server.example.com/terrain",
{ requestVertexNormals: true },
);
EllipsoidTerrainProvider (Flat Globe)
import { EllipsoidTerrainProvider } from "cesium";
// Flat ellipsoid -- no terrain data, useful for 2D/Columbus or testing
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 0)
fog.screenSpaceErrorFactor = 2.0;
fog.minimumBrightness = 0.03; // prevents completely black fog
Sun and Moon
viewer.scene.sun = new Cesium.Sun();
viewer.scene.sun.show = true;
viewer.scene.moon.show = true; // follows real lunar ephemeris
Lighting
scene.light controls the scene light source. Default is SunLight (follows clock).
import { SunLight, DirectionalLight, Cartesian3, Color } from "cesium";
// SunLight -- follows the Sun position based on scene clock
viewer.scene.light = new SunLight({ color: Color.WHITE, intensity: 2.0 });
// DirectionalLight -- fixed direction for studio-style lighting
viewer.scene.light = new DirectionalLight({
direction: new Cartesian3(0.2, -0.5, -0.8), // must be non-zero
color: Color.WHITE,
intensity: 1.5,
});
viewer.scene.globe.enableLighting = true; // required for light to affect terrain
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; // cascade range (meters)
sm.softShadows = true; // PCF for softer edges
sm.darkness = 0.3; // 0 = invisible, 1 = black
sm.fadingEnabled = true; // fade near horizon
viewer.scene.globe.shadows = Cesium.ShadowMode.RECEIVE_ONLY; // default
// ShadowMode: DISABLED, ENABLED, CAST_ONLY, 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
maximumScreenSpaceErrorfrom2to4+ on mobile -- single biggest
terrain perf knob.
- Keep fog enabled (default) -- culls distant tiles, reducing draw calls.
- Avoid per-frame
verticalExaggerationchanges -- forces terrain tile reloads. - Set
requestVertexNormals: trueonly when lighting is enabled -- doubles tile size. - Skip
requestWaterMask(default false) whenshowWaterEffectis off. - Prefer
sampleTerrainoversampleTerrainMostDetailedwhen 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
showGroundAtmosphereon 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, SCENELIGHT, SUNLIGHT | | ShadowMode | Enum: DISABLED, ENABLED, CASTONLY, 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
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: CesiumGS
- Source: CesiumGS/cesiumjs-skills
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.