原文链接及内容

代码中加载的模型效果如下图所示:vscode中安装“KTX-HDR Viewer”插件即可预览glb格式模型文件。

使用的ktx2纹理效果如下所示:vscode中安装“GLB Viewer”插件即可预览ktx2文件。

效果如下图所示:详细解释清查看代码注释。

示例代码如下:

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
const viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false,
homeButton: false,
sceneModePicker: false,
baseLayerPicker: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
animation: false,
timeline: false,
fullscreenButton: false,
selectionIndicator: false,
skyBox: false,
shouldAnimate: true,
});
viewer.cesiumWidget.creditContainer.style.display = "none";

if (!viewer.scene.specularEnvironmentMapsSupported) {
window.alert("此浏览器不支持镜面环境贴图。");
}

const modelURL = "../SampleData/models/Pawns/Pawns.glb";

/**
* 此环境贴图是使用 Khronos 的 glTF IBL Sampler 处理的。
* 1 - 下载并构建 Khronos glTF IBL Sampler(https://github.com/KhronosGroup/glTF-IBL-Sampler)。
* 2 - 运行 `cli -inputPath /path/to/image.hdr -outCubeMap /path/to/output.ktx2`。运行 `cli -h` 查看所有选项。
*/
const environmentMapURL =
"https://cesium.com/public/SandcastleSampleData/kiara_6_afternoon_2k_ibl.ktx2";

/**
* 要生成以下的球谐函数,请使用谷歌的Filament项目:
* 1.下载Filament的发布版本(https://github.com/google/filament/releases)。
* 2.运行 cmgen --no-mirror --type=ktx --deploy=/path/to/output /path/to/image.hdr。也支持其他格式。运行 cmgen --help 以查看所有选项。
* 3.获取生成的系数并在CesiumJS中加载,如下所示。
*
* 关于球谐函数(spherical harmonic coefficients),请参考维基百科了解:https://en.wikipedia.org/wiki/Spherical_harmonics
*/
const L00 = new Cesium.Cartesian3(
1.234897375106812,
1.221635103225708,
1.273374080657959
);
const L1_1 = new Cesium.Cartesian3(
1.136140108108521,
1.171419978141785,
1.287894368171692
);
const L10 = new Cesium.Cartesian3(
1.245410919189453,
1.245791077613831,
1.283067107200623
);
const L11 = new Cesium.Cartesian3(
1.107124328613281,
1.112697005271912,
1.153419137001038
);
const L2_2 = new Cesium.Cartesian3(
1.08641505241394,
1.079904079437256,
1.10212504863739
);
const L2_1 = new Cesium.Cartesian3(
1.190043210983276,
1.186099290847778,
1.214627981185913
);
const L20 = new Cesium.Cartesian3(
0.017783647403121,
0.020140396431088,
0.025317270308733
);
const L21 = new Cesium.Cartesian3(
1.087014317512512,
1.084779262542725,
1.111417651176453
);
const L22 = new Cesium.Cartesian3(
-0.052426788955927,
-0.048315055668354,
-0.041973855346441
);
const coefficients = [L00, L1_1, L10, L11, L2_2, L2_1, L20, L21, L22];

const height = 0.0;
const hpr = new Cesium.HeadingPitchRoll(0.0, 0.0, 0.0);
const origin = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, hpr);

try {
const model = viewer.scene.primitives.add(
await Cesium.Model.fromGltfAsync({
url: modelURL,
modelMatrix: modelMatrix,
minimumPixelSize: 128,
})
);

model.readyEvent.addEventListener(() => {
const camera = viewer.camera;

// 缩放至模型
const controller = viewer.scene.screenSpaceCameraController;
const r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
controller.minimumZoomDistance = r * 0.5;

const center = model.boundingSphere.center;
const heading = Cesium.Math.toRadians(230.0);
const pitch = Cesium.Math.toRadians(-20.0);
camera.lookAt(
center,
new Cesium.HeadingPitchRange(heading, pitch, r * 2.0)
);
camera.lookAtTransform(Cesium.Matrix4.IDENTITY);//解除相机锁定

//Model.imageBasedLighting:用于管理此模型上基于图像的照明的属性。
const ibl = model.imageBasedLighting;
/**
* ImageBasedLighting.sphericalHarmonicCoefficients:
* 用于基于图像照明的漫反射颜色的三阶球谐系数
*/
ibl.sphericalHarmonicCoefficients = coefficients;
/**
* ImageBasedLighting.specularEnvironmentMaps:
* 指向 KTX2 文件的 URL,其中包含镜面反射光照的立方体贴图和复杂的镜面反射多级贴图(mipmap)。
*/
ibl.specularEnvironmentMaps = environmentMapURL;

//更改模型环境贴图的地面颜色
model.environmentMapManager.groundColor =
Cesium.Color.fromCssColorString("#292817");

/**
* 在 CesiumJS 中,环境光照通常通过以下两种预计算资源实现:
* - 球谐系数(spherical harmonic coefficients):用于漫反射光照的低频分量,描述光照的分布。
* - 环境贴图(specular environment maps):用于镜面反射的高频分量。
*/
Sandcastle.addToggleButton(
"使用程序生成的环境光照",
false,
function (checked) {
if (!checked) {
//未被选中时,会使用预先计算的球谐系数和环境贴图来实现环境光照。
ibl.sphericalHarmonicCoefficients = coefficients;
ibl.specularEnvironmentMaps = environmentMapURL;
} else {
//被选中时,则会禁用预计算的环境光照资源,转而使用程序生成的环境光照。
ibl.sphericalHarmonicCoefficients = undefined;
ibl.specularEnvironmentMaps = undefined;
}
}
);
});
} catch (error) {
window.alert(`模型加载出错: ${error}`);
}