一、引言
Cesium 是一個強大的開源 JavaScript 庫,用于創建基于 Web 的 3D 地理信息系統 (GIS) 應用程序。它提供了豐富的 API,可以實現各種復雜的地理可視化效果,包括地形渲染、建筑物建模、矢量數據顯示等。本文將詳細介紹如何使用 Cesium 實現 3D 地圖中的水面效果,包括水面材質的配置、動畫效果的實現以及性能優化。
二、Cesium 基礎與水面效果原理
2.1 Cesium 基礎概念
- Viewer:Cesium 的核心組件,負責管理整個地圖視圖和交互
- Primitive:Cesium 中渲染的基本單位,用于組織和渲染幾何圖形
- Geometry:定義幾何形狀,如點、線、面等
- Appearance:定義幾何圖形的外觀,包括材質和著色方式
- Material:定義物體表面的視覺特性,如顏色、光澤等
2.2 水面效果原理
Cesium 中的水面效果主要通過以下技術實現:
- 使用
PolygonGeometry
創建水面區域 - 應用內置的 "Water" 材質模擬水面反射和折射
- 通過法線貼圖和動畫參數實現水面波浪效果
- 調整頻率、振幅和速度參數控制波浪形態和流動效果
三、實現 3D 地圖水面效果的代碼解析
下面是實現 Cesium 3D 地圖水面效果的核心代碼:
<template><div id="cesiumContainer" style="width: 100%; height: 100vh"></div>
</template><script>
import initMap from '@/config/initMap.js';
import { mapConfig } from '@/config/mapConfig';
export default {data() {return {viewer: null,waterEntity: null,};},mounted() {// 初始化地圖并設置初始視圖this.viewer = initMap(mapConfig.gaode.url3, true);this.drawWater();this.viewer.scene.globe.depthTestAgainstTerrain = false;this.viewer.camera.setView({destination: Cesium.Cartesian3.fromDegrees(118.006, 39.7128, 150000),});},methods: {// 創建水面效果drawWater() {this.viewer.scene.primitives.add(new Cesium.Primitive({geometryInstances: new Cesium.GeometryInstance({geometry: new Cesium.PolygonGeometry({polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray([// 定義水面多邊形的頂點坐標117.18714141845703, 39.377288818359375,117.172721862792957, 39.345016479492188,117.18164825439453, 39.303817749023438,117.25855255126953, 39.2962646484375,117.25855255126953, 39.366302490234375,117.18714141845703, 39.377288818359375,])),vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,}),}),appearance: new Cesium.EllipsoidSurfaceAppearance({aboveGround: true,material: new Cesium.Material({fabric: {type: 'Water',uniforms: {normalMap: Cesium.buildModuleUrl('Assets/Textures/waterNormals.jpg'),frequency: 1000.0,animationSpeed: 0.01,amplitude: 10,},},}),}),show: true,}));},// 設置初始視角setInitialView() {const center = Cesium.Cartesian3.fromDegrees(116.39, 39.9, 1000);const heading = Cesium.Math.toRadians(1110);const pitch = Cesium.Math.toRadians(-20);this.viewer.camera.setView({destination: center,orientation: {heading: heading,pitch: pitch,roll: 0,},});},},beforeDestroy() {// 清理資源,防止內存泄漏if (this.waterEntity) {this.viewer.entities.remove(this.waterEntity);}if (this.viewer) {this.viewer.destroy();}},
};
</script><style lang="scss" scoped>
#cesiumContainer {width: 100%;height: 100vh;touch-action: none;
}
</style>
3.1 代碼關鍵部分解析
3.1.1 初始化與地圖設置
mounted() {// 初始化地圖,使用高德地圖3D服務this.viewer = initMap(mapConfig.gaode.url3, true);this.drawWater(); // 繪制水面// 設置地形深度測試,影響水面與地形的交互this.viewer.scene.globe.depthTestAgainstTerrain = false;// 設置初始相機位置和高度this.viewer.camera.setView({destination: Cesium.Cartesian3.fromDegrees(118.006, 39.7128, 150000),});
},
3.1.2 水面效果實現
drawWater() {this.viewer.scene.primitives.add(new Cesium.Primitive({geometryInstances: new Cesium.GeometryInstance({geometry: new Cesium.PolygonGeometry({// 定義水面多邊形區域polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray([...])),vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,}),}),appearance: new Cesium.EllipsoidSurfaceAppearance({aboveGround: true,material: new Cesium.Material({fabric: {type: 'Water', // 使用內置水面材質uniforms: {// 水面材質參數配置normalMap: Cesium.buildModuleUrl('Assets/Textures/waterNormals.jpg'),frequency: 1000.0, // 波浪頻率animationSpeed: 0.01, // 波浪動畫速度amplitude: 10, // 波浪振幅},},}),}),show: true,}));
},
3.1.3 資源清理
beforeDestroy() {// 組件銷毀前清理Cesium資源if (this.waterEntity) {this.viewer.entities.remove(this.waterEntity);}if (this.viewer) {this.viewer.destroy(); // 釋放查看器資源}
},
四、水面效果參數調優
Cesium 的水面效果通過多個參數控制,合理調整這些參數可以獲得不同的水面效果:
4.1 主要參數說明
- normalMap:法線貼圖,控制水面的波浪形態
- frequency:頻率,控制波紋的緊密程度,值越大波紋越密集
- animationSpeed:動畫速度,控制水面流動的速度
- amplitude:振幅,控制波浪的高度,值越大波浪越明顯
4.2 參數調優建議
- 對于平靜的湖泊,可以使用較低的 frequency (500-1000) 和 amplitude (5-10)
- 對于海洋效果,可以使用較高的 frequency (1500-2000) 和 amplitude (15-30)
- animationSpeed 通常在 0.005-0.02 之間調整,過大的值會使水面看起來不自然
五、性能優化與注意事項
5.1 性能優化
- 復雜的水面效果會影響性能,特別是在移動設備上
- 可以通過降低 frequency 和 amplitude 值來提高性能
- 對于大面積水域,可以考慮將水域分割成多個較小的區域
5.2 注意事項
depthTestAgainstTerrain
屬性會影響水面與地形的交互,開啟后可能導致水面在某些視角下不可見- 確保在組件銷毀時正確清理 Cesium 資源,避免內存泄漏
- 水面效果在不同的 Cesium 版本中可能有差異,建議查看對應版本的文檔
六、總結
通過本文的介紹,我們了解了如何使用 Cesium 實現 3D 地圖中的水面效果。主要步驟包括初始化地圖、創建水面多邊形、應用水面材質以及設置動畫效果。通過調整材質參數,可以模擬不同類型的水體,從平靜的湖泊到波濤洶涌的海洋。同時,我們也提到了性能優化和資源管理的重要性,這些都是開發高質量 Cesium 應用的關鍵因素。
希望本文對您理解和使用 Cesium 實現水面效果有所幫助,歡迎在評論區分享您的經驗和問題。