在三维可视化开发中,标准图元往往无法满足特定业务需求。当需要渲染非规则形状或动态生成的模型时,基于顶点、索引和颜色数组构建自定义多面几何体是更灵活的选择。
核心思路
Cesium 的 Primitive 接口允许我们加载自定义缓冲区数据。通过手动构造位置、法线、纹理坐标等属性,我们可以精确控制每个顶点的渲染效果。这种方式比加载外部模型文件更轻量,适合实时计算的场景。
关键步骤
- 准备数据:整理顶点坐标(x, y, z)、索引(三角形连接关系)以及对应的颜色值(r, g, b, a)。
- 创建 Geometry:使用
Cesium.Geometry将数组转换为 GPU 可识别的格式。 - 实例化 Primitive:绑定材质和几何体,添加到场景管理器。
代码实现
下面是一个完整的 HTML 示例,展示了如何初始化 Cesium 并绘制一个自定义的多面体。注意,实际项目中请确保引入正确的 Cesium JS 库。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cesium Custom Geometry</title>
<style>
body { margin: 0; overflow: hidden; }
#cesiumContainer { width: 100%; height: 100vh; }
</style>
<!-- 请替换为实际的 Cesium.js 路径 -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.109/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.109/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
<div id="cesiumContainer"></div>
<script>
const viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: undefined,
imageryProvider: undefined,
baseLayerPicker: false,
geocoder: false,
homeButton: false,
sceneModePicker: false,
navigationHelpButton: false,
animation: false,
timeline: false,
fullscreenButton: false,
infoBox: false,
selectionIndicator: false
});
// 定义一个简单的立方体数据
const positions = [
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0
];
const indices = [
0, 1, 2, 0, 2, 3,
4, 5, 6, 4, 6, 7,
0, 1, 5, 0, 5, 4,
2, 3, 7, 2, 7, 6,
0, 3, 7, 0, 7, 4,
1, 2, 6, 1, 6, 5
];
const colors = [];
for (let i = 0; i < positions.length / 3; i++) {
colors.push(1.0, 0.0, 0.0, 1.0); // 红色
}
const geometry = new Cesium.Geometry({
attributes: {
position: new Cesium.Cartesian3Array(positions),
color: new Cesium.ColorGeometryInstanceAttribute(colors)
},
indices: new Uint16Array(indices),
vertexCount: positions.length / 3
});
const primitive = new Cesium.Primitive({
geometry: geometry,
appearance: new Cesium.PerInstanceColorAppearance()
});
viewer.scene.primitives.add(primitive);
// 调整视角
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(0, 0, 5)
});
</script>
</body>
</html>
注意事项
- 性能优化:如果顶点数量巨大,建议合并多个几何体为一个
Primitive,减少 Draw Call。 - 坐标系:Cesium 默认使用 WGS84 地理坐标系,本地建模时需注意单位转换,通常建议使用笛卡尔坐标系配合
ModelMatrix进行定位。 - 光照影响:自定义几何体若未正确设置法线,可能无法响应场景光照,需补充法线数据或使用
PerInstanceColorAppearance。
通过这种方式,你可以完全掌控模型的几何结构,实现高度定制化的三维展示效果。


