前言
最近有一个需求,需要实现动态水面(并且能够动态拉伸)
,我相信很多小伙伴都需要这个需求,在网上也有很多的文章,写的都很不多,但是他们他们可能落下一些细节东西,而且有些都要钱,才能让各位看
。在这里总结一下,希望能帮到各位不管是热爱还是生活无赖的WebGIS同仁(保姆级教程)
。
效果
先来上一个我最终实现的效果,先镇定一下各位的心灵,各位为了这个目标,冲鸭!!!!
:
cesium动态水面
构建项目
构建项目,我这里就不多赘述其他方法了,网上一搜一大把,我的构建项目如下:
// 1.创建`vite+vue3`项目
npm init vite@latest my-vue-app -- --template vue
// 2.安装`cesium` 和 `vite-plugin-cesium`
npm i cesium vite-plugin-cesium -D
以上就是我的项目创建和cesium
和 vite-plugin-cesium 的安装,采用vite-plugin-cesium
插件集成cesium
可以减少很多的配置问题,网上好多不是vite项目创建的,配置起来一大堆,比较麻烦所以选择vite-plugin-cesium
。
***具体用法:
***在vite.config.js中导入:
import cesium from 'vite-plugin-cesium'
export default defineConfig({
plugins: [cesium()],
})
开始开发
到这里我欣喜若狂,我应该可以实现这个效果了吧。
矩形动态水面
我先来个矩形动态水面,这个简单,就不贴代码了,效果如下:
看到这个矩形效果,自我感觉还可以
,然后我就接着弄任意多边形,代码如下:
riverData.geometry.coordinates[0].forEach(item => {
river.push(item[0], item[1])
})
// 绘制面的几何实体
const riverPolygon = new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(river)),
height: 20,
extrudedHeight: 0,
ellipsoid: Cesium.Ellipsoid.WGS84
})
// 自定义材质
const riverMaterial = new Cesium.Material({
fabric: {
type: "Water",
uniforms: {
// baseWaterColor: new Cesium.Color(64 / 255.0, 157 / 255.0, 253 / 255.0, 0.5),
normalMap: './waterNormals.jpg',
frequency: 1000.0,
animationSpeed: 0.1,
amplitude: 10,
specularIntensity: 10
}
}
})
// 河道的riverPrimitive
const riverPrimitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
id: 'river',
geometry: riverPolygon
}),
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: riverMaterial,
fragmentShaderSource: fragmentShaderSource
}),
show: true,
allowPicking: false,
asynchronous: false
})
viewer.scene.primitives.add(riverPrimitive)
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(117.763172, 33.042816, 100000)
});
写完这些代码,我就迫不及待想看到效果了,满脑子预期效果出现在我眼前,好,一运行,走你,效果如下
细节,重点来了
看到这个效果,我崩溃了,然后找了好久,实在没办法了就去github上面找找找看,看到了两个人提的问题
第一位说是多边形图元设置材质不起效果,后面cesium工作人员给了建议,试了效果也不好
第二位呢直接做了版本回退,测试了1.108、1.109、1.110几个版本,发现1.108和1.109版本效果正常,得出1.108版本最稳定
这个时候,我才知道版本问题
,我用的是最新版本1.113,最新版本有这个bug,所以我也回退到1.108
回退之后问题
版本开始回退之后,我运行,又报错
在网上又找了办法,说是会请求cesium icon的资源,由于服务器在国外
,就会报错
,得加自己的地图,我又改了下:
const bing = await Cesium.BingMapsImageryProvider.fromUrl('https://dev.virtualearth.net', {
key: 'token',
mapStyle: Cesium.BingMapsStyle.AERIAL
})
viewer = new Cesium.Viewer('cesiumContainer', {
infoBox: false,
baseLayerPicker: false,
baseLayer: new Cesium.ImageryLayer(bing),
contextOptions: {
requestWebgl1: true
},
// terrain: Cesium.Terrain.fromWorldTerrain(),
timeline: false,
});
最后,再运行,奇迹出现了,成功了
。效果如下:
总结
导致这种原因就是cesium的版本问题,所以一定要看下版本。至于动态拉伸,我后面补充,先写到这。
最后如果各位同仁实现了这个效果,解决了你们的实际问题,欢迎大家多多点赞,评论,有什么问题可以留言咨询,总结不易,最终解决了问题的小伙伴
,手头宽裕的可以赞赏一波
,谢谢大家!