原文链接及内容

效果如下视频所示:

示例代码如下:

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
<style>
@import url(../templates/bucket.css);
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar">
<table>
<tbody>
<tr>
<td>启用景深效果</td>
<td><input type="checkbox" data-bind="checked: show"></td>
</tr>
<tr>
<td>focalDistance(焦距)</td>
<td>
<input type="range" min="0.0" max="500.0" step="1" data-bind="value: focalDistance, valueUpdate: 'input'">
</td>
</tr>
<tr>
<td>Delta(模糊过渡的平滑度)</td>
<td>
<input type="range" min="0.1" max="2" step="0.01" data-bind="value: delta, valueUpdate: 'input'">
</td>
</tr>
<tr>
<td>Sigma(模糊强度)</td>
<td>
<input type="range" min="0.5" max="5" step="0.01" data-bind="value: sigma, valueUpdate: 'input'">
</td>
</tr>
<tr>
<td>Step Size(渲染时的采样步长)</td>
<td>
<input type="range" min="0" max="7" step="0.01" data-bind="value: stepSize, valueUpdate: 'input'">
</td>
</tr>
</tbody>
</table>
</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
const viewer = new Cesium.Viewer("cesiumContainer",{
geocoder: false,
sceneModePicker: false,
homeButton: false,
navigationHelpButton: false,
baseLayerPicker: false,
navigationInstructionsInitiallyVisible: false,
fullscreenButton: false,
selectionIndicator: false,
skyBox: false,
timeline: false,
animation: false,
shouldAnimate: true,
});

viewer.cesiumWidget.creditContainer.style.display = "none";

//添加模型
function createModel(url, x, y, height) {
const position = Cesium.Cartesian3.fromDegrees(x, y, height);
viewer.entities.add({
name: url,
position: position,
model: {
uri: url,
},
});
}

const numberOfBalloons = 13;
const lonIncrement = 0.00025;//经度增量
const initialLon = -122.99875;//初始经度
const lat = 44.0503706;
const height = 100.0;

const url = "../SampleData/models/CesiumBalloon/CesiumBalloon.glb";

for (let i = 0; i < numberOfBalloons; ++i) {
const lon = initialLon + i * lonIncrement;
createModel(url, lon, lat, height);
}

const viewModel = {
show: true,
focalDistance: 87,
delta: 1,
sigma: 3.78,
stepSize: 2.46,
};

Cesium.knockout.track(viewModel);
const toolbar = document.getElementById("toolbar");
Cesium.knockout.applyBindings(viewModel, toolbar);
for (const name in viewModel) {
if (viewModel.hasOwnProperty(name)) {
Cesium.knockout.getObservable(viewModel, name).subscribe(updatePostProcess);
}
}

if (!Cesium.PostProcessStageLibrary.isDepthOfFieldSupported(viewer.scene)) {
window.alert("此浏览器不支持景深后期处理");
}

const depthOfField = viewer.scene.postProcessStages.add(
//createDepthOfFieldStage():创建一个后处理阶段,应用景深效果。
Cesium.PostProcessStageLibrary.createDepthOfFieldStage(),
);

/**
* focalDistance:设置景深效果的焦点距离
* delta:景深模糊过渡的范围或强度
* sigma:设置模糊的强度或扩散程度
* stepSize:设置景深算法的采样步长。
*/
function updatePostProcess() {
depthOfField.enabled = Boolean(viewModel.show);
depthOfField.uniforms.focalDistance = Number(viewModel.focalDistance);
depthOfField.uniforms.delta = Number(viewModel.delta);
depthOfField.uniforms.sigma = Number(viewModel.sigma);
depthOfField.uniforms.stepSize = Number(viewModel.stepSize);
}
updatePostProcess();

const target = Cesium.Cartesian3.fromDegrees(
initialLon + lonIncrement,
lat,
height + 7.5,
);
const offset = new Cesium.Cartesian3(
-37.048378684557974,
-24.852967044804245,
4.352023653686047,
);
viewer.scene.camera.lookAt(target, offset);