原文链接及内容

效果如下图所示:

注:lens flare翻译为镜头光晕,这是图形渲染领域的标准术语,指相机镜头因强光产生的散射效果,以下内容翻译自官方api文档,详情见:https://cesium.com/learn/cesiumjs/ref-doc/PostProcessStageLibrary.html?classFilter=PostProcessStageLibrary#.createLensFlareStage

关于Cesium.PostProcessStageLibrary.createLensFlareStage()方法:它会创建一个后处理阶段,用于应用模拟相机镜头光晕效果的处理。该阶段包含以下统一变量(uniforms):dirtTexturestarTextureintensitydistortionghostDispersalhaloWidthdirtAmountearthRadius

  • dirtTexture: 用于模拟镜头脏污的采样纹理。
  • starTexture: 用于光晕星形图案的采样纹理,星形图案指光晕的星芒效果。
  • intensity: 标量,用于乘以光晕效果的结果,默认值为 2.0。
  • distortion: 标量,影响色散效果的扭曲程度,默认值为 10.0。扭曲指的是色散效果中的变形。
  • ghostDispersal: 标量,表示光环效果与纹理中心的距离,默认值为 0.4。是光晕效果(halo effect)相对于纹理中心的分散距离。
  • haloWidth: 标量,表示从光晕分散点开始的晕环宽度,默认值为 0.4。光晕分散指光晕效果的扩散程度。
  • dirtAmount: 标量,表示镜头上的脏污程度,默认值为 0.4。
  • earthRadius: 地球的最大半径,默认值为 Ellipsoid.WGS84.maximumRadius。

示例代码如下:

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
<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>光晕强度</td>
<td>
<input type="range" min="0" max="10" step="0.01" data-bind="value: intensity, valueUpdate: 'input'">
</td>
</tr>
<tr>
<td>色散扭曲程度</td>
<td>
<input type="range" min="1" max="20" step="0.01" data-bind="value: distortion, valueUpdate: 'input'">
</td>
</tr>
<tr>
<td>(鬼影)分散(距离)</td>
<td>
<input type="range" min="0" max="1" step="0.01" data-bind="value: dispersion, valueUpdate: 'input'">
</td>
</tr>
<tr>
<td>晕环宽度</td>
<td>
<input type="range" min="0" max="1" step="0.01" data-bind="value: haloWidth, valueUpdate: 'input'">
</td>
</tr>
<tr>
<td>(镜头)脏污程度</td>
<td>
<input type="range" min="0" max="1" step="0.01" data-bind="value: dirtAmount, 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
const viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false,
homeButton: false,
sceneModePicker: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
animation: false,
timeline: false,
fullscreenButton: false,
skyBox: false,
shouldAnimate: true,
baseLayerPicker: false,
});
viewer.cesiumWidget.creditContainer.style.display = "none";

const viewModel = {
show: true,
intensity: 2.0,
distortion: 10.0,
dispersion: 0.4,
haloWidth: 0.4,
dirtAmount: 0.4,
};

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);
}
}

const lensFlare = viewer.scene.postProcessStages.add(
Cesium.PostProcessStageLibrary.createLensFlareStage()
);

function updatePostProcess() {
lensFlare.enabled = Boolean(viewModel.show);
lensFlare.uniforms.intensity = Number(viewModel.intensity);
lensFlare.uniforms.distortion = Number(viewModel.distortion);
lensFlare.uniforms.ghostDispersal = Number(viewModel.dispersion);
lensFlare.uniforms.haloWidth = Number(viewModel.haloWidth);
lensFlare.uniforms.dirtAmount = Number(viewModel.dirtAmount);
lensFlare.uniforms.earthRadius = Cesium.Ellipsoid.WGS84.maximumRadius;
}
updatePostProcess();

const camera = viewer.scene.camera;
camera.position = new Cesium.Cartesian3(
40010447.97500168,
56238683.46406788,
20776576.752223067
);
camera.direction = new Cesium.Cartesian3(
-0.5549701431494752,
-0.7801872010801355,
-0.2886452346452218
);
camera.up = new Cesium.Cartesian3(
-0.3016252360948521,
-0.13464820558887716,
0.9438707950150912
);
camera.right = Cesium.Cartesian3.cross(
camera.direction,
camera.up,
new Cesium.Cartesian3()
);

viewer.clock.currentTime = new Cesium.JulianDate(2458047, 27399.860215000022);