Skip to content

Commit 7d3efcb

Browse files
authored
Merge pull request #12963 from CesiumGS/3d-tiles-terrain
3d tiles terrain
2 parents a3ae794 + b321b6f commit 7d3efcb

40 files changed

+6217
-109
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta
7+
name="viewport"
8+
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
9+
/>
10+
<meta name="description" content="Apply materials to the globe." />
11+
<meta name="cesium-sandcastle-labels" content="Showcases" />
12+
<title>Cesium Demo</title>
13+
<script type="text/javascript" src="../Sandcastle-header.js"></script>
14+
<script
15+
type="text/javascript"
16+
src="../../../Build/CesiumUnminified/Cesium.js"
17+
nomodule
18+
></script>
19+
<script type="module" src="../load-cesium-es6.js"></script>
20+
</head>
21+
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
22+
<style>
23+
@import url(../templates/bucket.css);
24+
</style>
25+
<div id="cesiumContainer" class="fullSize"></div>
26+
<div id="loadingOverlay"><h1>Loading...</h1></div>
27+
<div id="toolbar">
28+
<div id="zoomButtons"></div>
29+
</div>
30+
<script id="cesium_sandcastle_script">
31+
window.startup = async function (Cesium) {
32+
"use strict";
33+
//Sandcastle_Begin
34+
const terrainProvider = await Cesium.Cesium3DTilesTerrainProvider.fromIonAssetId(
35+
3923568,
36+
{
37+
requestVertexNormals: true, // Needed for hillshade lighting
38+
requestWaterMask: true, // Needed to distinguish land from water
39+
},
40+
);
41+
42+
const viewer = new Cesium.Viewer("cesiumContainer", {
43+
terrainProvider: terrainProvider,
44+
scene3DOnly: true,
45+
sceneModePicker: false,
46+
navigationHelpButton: false,
47+
});
48+
49+
// Create a globe material for shading elevation only on land
50+
const customElevationMaterial = new Cesium.Material({
51+
fabric: {
52+
type: "ElevationLand",
53+
materials: {
54+
waterMaskMaterial: {
55+
type: "WaterMask",
56+
},
57+
elevationRampMaterial: {
58+
type: "ElevationRamp",
59+
},
60+
},
61+
components: {
62+
diffuse: "elevationRampMaterial.diffuse",
63+
alpha: "1.0 - waterMaskMaterial.alpha", // We'll need the inverse of the watermask to shade land
64+
},
65+
},
66+
translucent: false,
67+
});
68+
69+
const minHeight = -414.0; // approximate dead sea elevation
70+
const maxHeight = 8777.0; // approximate everest elevation
71+
const elevationRamp = [0.0, 0.045, 0.45, 0.5, 0.55, 1.0];
72+
function getColorRamp() {
73+
const ramp = document.createElement("canvas");
74+
ramp.width = 100;
75+
ramp.height = 1;
76+
const ctx = ramp.getContext("2d");
77+
78+
const values = elevationRamp;
79+
80+
const grd = ctx.createLinearGradient(0, 0, 100, 0);
81+
82+
// See https://gis.stackexchange.com/questions/25099/choosing-colour-ramp-to-use-for-elevation
83+
grd.addColorStop(values[0], "#344f31");
84+
grd.addColorStop(values[1], "#5b8742");
85+
grd.addColorStop(values[2], "#e6daa5");
86+
grd.addColorStop(values[3], "#fdc771");
87+
grd.addColorStop(values[4], "#b99d89");
88+
grd.addColorStop(values[5], "#f0f0f0");
89+
90+
ctx.fillStyle = grd;
91+
ctx.fillRect(0, 0, 100, 1);
92+
93+
return ramp;
94+
}
95+
96+
const globe = viewer.scene.globe;
97+
const material = customElevationMaterial;
98+
const shadingUniforms = material.materials.elevationRampMaterial.uniforms;
99+
100+
globe.showWaterEffect = false;
101+
globe.enableLighting = true;
102+
103+
shadingUniforms.minimumHeight = minHeight;
104+
shadingUniforms.maximumHeight = maxHeight;
105+
shadingUniforms.image = getColorRamp();
106+
globe.material = material;
107+
108+
// Light the scene with a hillshade effect similar to https://pro.arcgis.com/en/pro-app/latest/tool-reference/3d-analyst/how-hillshade-works.htm
109+
const scene = viewer.scene;
110+
scene.light = new Cesium.DirectionalLight({
111+
direction: new Cesium.Cartesian3(1, 0, 0), // Updated every frame
112+
});
113+
114+
// Update the light position base on the camera
115+
const scratchNormal = new Cesium.Cartesian3();
116+
scene.preRender.addEventListener(function (scene, time) {
117+
const surfaceNormal = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(
118+
scene.camera.positionWC,
119+
scratchNormal,
120+
);
121+
const negativeNormal = Cesium.Cartesian3.negate(surfaceNormal, surfaceNormal);
122+
scene.light.direction = Cesium.Cartesian3.normalize(
123+
Cesium.Cartesian3.add(negativeNormal, scene.camera.rightWC, surfaceNormal),
124+
scene.light.direction,
125+
);
126+
});
127+
//Sandcastle_End
128+
};
129+
if (typeof Cesium !== "undefined") {
130+
window.startupCalled = true;
131+
window.startup(Cesium).catch((error) => {
132+
"use strict";
133+
console.error(error);
134+
});
135+
Sandcastle.finishedLoading();
136+
}
137+
</script>
138+
</body>
139+
</html>
21.6 KB
Loading

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#### Additions :tada:
1313

14+
- Added experimental support for loading 3D Tiles as terrain, via `Cesium3DTilesTerrainProvider`. See [the PR](https://github.com/CesiumGS/cesium/pull/12963) for limitations on the types of 3D Tiles that can be used. [#12296](https://github.com/CesiumGS/cesium/issues/12296)
1415
- Added support for [EXT_mesh_primitive_edge_visibility](https://github.com/KhronosGroup/glTF/pull/2479) glTF extension. [#12765](https://github.com/CesiumGS/cesium/issues/12765)
1516

1617
#### Fixes :wrench:
5.23 KB
Binary file not shown.
1.69 KB
Binary file not shown.
11.1 KB
Binary file not shown.
11 KB
Binary file not shown.
11.3 KB
Binary file not shown.
11 KB
Binary file not shown.
5.15 KB
Binary file not shown.

0 commit comments

Comments
 (0)