原文链接及内容

效果如下视频所示:

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<style>
@import url(../templates/bucket.css);

#toolbar {
background: rgba(42, 42, 42, 0.8);
padding: 4px;
border-radius: 4px;
}

#toolbar input {
vertical-align: middle;
padding-top: 2px;
padding-bottom: 2px;
}

.cesium-performanceDisplay-defaultContainer {
top: 10px;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>加载中...</h1></div>
<div id="toolbar">
<div id="hdr-toggle"></div>
<span>Tonemap(色调映射算法)</span>
<span id="tonemap-select"></span>
<br>
<span>曝光度</span>
<input type="range" min="0.1" max="10.0" step="0.1" data-bind="value: exposure, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: exposure">
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
const viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false,
sceneModePicker: false,
navigationHelpButton: false,
baseLayerPicker: false,
navigationInstructionsInitiallyVisible: false,
fullscreenButton: false,
selectionIndicator: false,
skyBox: false,
timeline: false,
animation: false,
shouldAnimate: true,
infoBox: false,
shadows: true,
terrain: Cesium.Terrain.fromWorldTerrain(),
});
viewer.cesiumWidget.creditContainer.style.display = "none";

if (!viewer.scene.highDynamicRangeSupported) {
window.alert("该浏览器不支持高动态范围(HDR,即high dynamic range)。");
}

viewer.scene.highDynamicRange = true;

// 启用或关闭HDR功能
Sandcastle.addToggleButton(
"HDR",
true,
function (checked) {
viewer.scene.highDynamicRange = checked;
},
"hdr-toggle"
);

/**
* postProcessStages:最终渲染应用的后期处理效果
* postProcessStages.tonemapper:用来指定使用高动态范围渲染时使用的色调映射算法。
*
* Tonemapper:
* - REINHARD:使用 Reinhard 色调映射。
* - MODIFIED_REINHARD:使用修改后的 Reinhard 色调映射。
* - FILMIC:使用 Filmic 色调映射。
* - ACES:使用 ACES 色调映射。
* - PBR_NEUTRAL:使用 Khronos 的 PBR 中性色调映射。 具体参考:https://github.com/KhronosGroup/ToneMapping/tree/main/PBR_Neutral
*/
const toneMapOptions = [
{
text: "PBR Neutral算法",
onselect: function () {
viewer.scene.postProcessStages.tonemapper = Cesium.Tonemapper.PBR_NEUTRAL;
},
},
{
text: "Aces算法",
onselect: function () {
viewer.scene.postProcessStages.tonemapper = Cesium.Tonemapper.ACES;
},
},
{
text: "Reinhard算法",
onselect: function () {
viewer.scene.postProcessStages.tonemapper = Cesium.Tonemapper.REINHARD;
},
},
{
text: "Modified_Reinhard算法",
onselect: function () {
viewer.scene.postProcessStages.tonemapper =
Cesium.Tonemapper.MODIFIED_REINHARD;
},
},
{
text: "Filmic算法",
onselect: function () {
viewer.scene.postProcessStages.tonemapper = Cesium.Tonemapper.FILMIC;
},
},
];
Sandcastle.addDefaultToolbarMenu(toneMapOptions, "tonemap-select");

const viewModel = {
exposure: 1,
};
// 将 viewModel 成员转换为 knockout 可观察对象。
Cesium.knockout.track(viewModel);
// 将 viewModel 绑定到需要它的 UI 的 DOM 元素上。
const toolbar = document.getElementById("toolbar");
Cesium.knockout.applyBindings(viewModel, toolbar);

/**
* postProcessStages.exposure: 默认值为1.
* 在 HDR 开启时控制曝光。小于 1.0 会使色调映射变暗,而大于 1.0 则使其变亮。
*/
Cesium.knockout
.getObservable(viewModel, "exposure")
.subscribe(function (newValue) {
viewer.scene.postProcessStages.exposure = Number.parseFloat(newValue);
});

const url = "../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf";
const position = Cesium.Cartesian3.fromRadians(
-1.9516424279517286,
0.6322397098422969,
1239.0006814631095
);
const heading = Cesium.Math.toRadians(-15.0);
const pitch = 0;
const roll = 0;
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
const scale = 10.0;

const entity = viewer.entities.add({
name: url,
position: position,
orientation: orientation,
model: {
uri: url,
scale: scale,//指定此模型的统一线性缩放比例。大于 1.0 的值会增加模型的大小,而小于 1.0 的值会减小它。
},
});

// 将相机视角设置到一个峡谷
viewer.scene.camera.setView({
destination: new Cesium.Cartesian3(
-1915097.7863741855,
-4783356.851539908,
3748887.43462683
),
orientation: new Cesium.HeadingPitchRoll(
6.166004548388564,
-0.043242401760068994,
0.002179961955988574
),
endTransform: Cesium.Matrix4.IDENTITY,
});

/**
* Cesium 场景的当前时间被设置为 2025年6月25日 06:00:37 UTC,上面的位置大概位于美国的亚利桑那州,
* 比我们的时间慢15个小时,则当前设置的时间正好是当地下午3点。
*
* Cesium.JulianDate(julianDayNumber, secondsOfDay, timeStandard):设定时间,让太阳位于头顶
* - julianDayNumber:代表完整天数的儒略日数,
* 儒略日 2460550 对应于公历日期 2025年6月25日(通过儒略日计算工具或算法得出)。
* - secondsOfDay:当前儒略日数中的秒数,21637 秒 ≈ 6小时(21600 秒) + 37 秒
* - timeStandard:默认值TimeStandard.UTC,前两个参数定义的时间标准
*/
viewer.clock.currentTime = new Cesium.JulianDate(2460550, 21637);

viewer.scene.debugShowFramesPerSecond = true;
// 覆盖默认主位置以返回到起点
viewer.homeButton.viewModel.command.beforeExecute.addEventListener((e) => {
e.cancel = true;
viewer.scene.camera.setView({
destination: new Cesium.Cartesian3(
-1915097.7863741855,
-4783356.851539908,
3748887.43462683
),
orientation: new Cesium.HeadingPitchRoll(
6.166004548388564,
-0.043242401760068994,
0.002179961955988574
),
endTransform: Cesium.Matrix4.IDENTITY,//解除相机视角锁定,即允许鼠标拖动场景
});
});