原文链接及内容

示例介绍:在 Cesium 场景中加载 3D Tiles 格式的体素数据,使用Cesium3DTilesVoxelProvider从预定义的 tileset.json 文件获取立方体、圆柱和椭球的体素内容。还借助了自定义着色器直接映射体素的 RGBA 属性,场景禁用部分 UI 控件(如动画、时间轴),并启用体素检查器(viewerVoxelInspectorMixin)和帧率显示。

注:关于voxels的介绍请参考Voxels中添加的注释。

效果如下图所示:

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>
@import url(../templates/bucket.css);

.cesium-performanceDisplay-defaultContainer {
top: 5px;
right: 50px;
}

.cesium-viewer-voxelInspectorContainer {
top: 60px;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>加载中...</h1></div>
<div id="toolbar"></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
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,
shadows: true,
projectionPicker: true,//启用投影选择器(正交投影和透视投影)
baseLayer: Cesium.ImageryLayer.fromProviderAsync(
Cesium.TileMapServiceImageryProvider.fromUrl(
Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII")
)
),
});
viewer.cesiumWidget.creditContainer.style.display = "none";

// viewerVoxelInspectorMixin:体素检查器,调试体素渲染。
viewer.extend(Cesium.viewerVoxelInspectorMixin);
viewer.scene.debugShowFramesPerSecond = true;//显示帧率,监控性能。

// 自定义着色器:直接映射体素的颜色数据,保持原始视觉效果
const customShaderColor = new Cesium.CustomShader({
fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
{
//使用体素元数据的 a 属性的 RGB 分量作为漫反射颜色
material.diffuse = fsInput.metadata.a.rgb;
//使用 a 属性的 alpha 分量作为透明度
material.alpha = fsInput.metadata.a.a;
}`,
});

/**
* 体素图元创建
*/
function createPrimitive(provider) {
viewer.scene.primitives.removeAll();

const voxelPrimitive = viewer.scene.primitives.add(
new Cesium.VoxelPrimitive({
provider: provider,
customShader: customShaderColor,
}),
);

// 启用最近邻采样,保持体素的清晰边缘(避免插值模糊)。
voxelPrimitive.nearestSampling = true;

// 将图元绑定到体素检查器,调试渲染。
viewer.voxelInspector.viewModel.voxelPrimitive = voxelPrimitive;
// 聚焦体素的边界球
viewer.camera.flyToBoundingSphere(voxelPrimitive.boundingSphere, {
duration: 0.0,
});

return voxelPrimitive;
}

Sandcastle.addToolbarMenu([
{
text: "加载立方体体素",
onselect: async function () {
const provider = await Cesium.Cesium3DTilesVoxelProvider.fromUrl(
"../SampleData/Cesium3DTiles/Voxel/VoxelBox3DTiles/tileset.json",
);
const primitive = createPrimitive(provider);
},
},
{
text: "加载圆柱体体素",
onselect: async function () {
const provider = await Cesium.Cesium3DTilesVoxelProvider.fromUrl(
"../SampleData/Cesium3DTiles/Voxel/VoxelCylinder3DTiles/tileset.json",
);
const primitive = createPrimitive(provider);
},
},
{
text: "加载椭球体体素",
onselect: async function () {
const provider = await Cesium.Cesium3DTilesVoxelProvider.fromUrl(
"../SampleData/Cesium3DTiles/Voxel/VoxelEllipsoid3DTiles/tileset.json",
);
const primitive = createPrimitive(provider);
},
},
]);