大家好,我是日拱一卒的攻城师不浪,致力于前沿科技探索,摸索小而美工作室。这是2025年输出的第7/100篇文章。
今天咱们来聊聊如何在Cesium
中实现一个动态多边形扩散效果,源码请文末自取。
这种效果在应急指挥
、污染扩散模拟
甚至游戏场景
中都非常实用。本文将从代码实战出发,带你手撕实现逻辑!
效果预览
🎯 应用场景:当技术遇上业务
-
应急指挥 :模拟火灾、洪水等灾害的
扩散范围
,所以不止有辐射圈哦。 -
环境监测:动态展示污染物扩散趋势。
实现原理
多边形扩散圈
效果的核心是通过动态几何形状 和材质透明度渐变实现,具体分为以下两个部分:
1.1 动态多边形生成
-
顶点计算 :根据中心点、边数(
edge
)和当前半径(currentRadius
),计算正多边形顶点坐标。每个顶点的位置通过极坐标公式(x = r*cosθ, y = r*sinθ)
确定,再转换为三维空间坐标。 -
实时更新 :使用Cesium的
CallbackProperty
属性,逐帧更新多边形半径和高度,实现扩散动画。当半径超过设定值或高度降为0时,参数重置,形成循环效果。
1.2 材质渐变效果
- 透明度控制 :在GLSL着色器中,通过
fract(st.t)
获取纹理坐标的垂直分量,实现从底部到顶部的透明度渐变。公式material.alpha = color.a * (1.0 - fract(st.t)) * 0.8
使得高度越高越透明。
核心代码分析
动态多边形类 WallRegularDiffuse
javascript
// 实时更新多边形顶点(WallPolygonDiffuse.js)
positions: new Cesium.CallbackProperty(() => {
this._currentRadius += (this._radius * this._speed) / 1000.0;
this._currentHeight -= (this._height * this._speed) / 1000.0;
// 参数重置逻辑
if (this._currentRadius > this._radius || this._currentHeight < 0) {
this._currentRadius = this._minRadius;
this._currentHeight = this._height;
}
return this._getPositions(...);
}, false)
-
功能:每帧更新半径和高度,超出范围后重置,形成循环动画。
-
关键点 :
CallbackProperty
是Cesium的动态属性机制,允许属性值随时间变化。
简单来说,这就是一个**"呼吸循环"**:每次渲染时增大半径、减小高度,超出阈值后重置,形成无限循环的扩散动画。
顶点生成方法 _getPositions
javascript
// 扩散正多变形的边数
this._edge = options.edge || 64;
let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(...);
for (let i = 0; i < edge; i++) {
let angle = (i / edge) * Cesium.Math.TWO_PI;
let point = new Cesium.Cartesian3(x * currentRadius, y * currentRadius, currentHeight);
positions.push(Cesium.Matrix4.multiplyByPoint(modelMatrix, point));
}
- 功能:将局部坐标转换为世界坐标,生成闭合多边形(首尾顶点需要重复)。
自定义材质类 WallDiffuseMaterialProperty
着色器代码(核心)
glsl
// 透明度渐变逻辑(WallDiffuseMaterialProperty.js)
material.alpha = color.a * (1.0 - fract(st.t)) * 0.8;
- 解释 :
st.t
表示纹理的垂直坐标(0到1),fract(st.t)
取其小数部分,实现从下到上透明度递减。
材质定义
javascript
Cesium.Material._materialCache.addMaterial(
Cesium.Material.WallDiffuseMaterialType, {
fabric: {
source: `uniform vec4 color; ...`, // 上述GLSL代码
uniforms: { color: new Cesium.Color(...) }
},
translucent: true // 启用透明度
}
);
- 功能:将自定义材质注册到Cesium材质系统,供实体调用。
关键参数说明
参数名 | 作用 |
---|---|
edge |
控制多边形的边数(>=3) |
speed |
扩散速度(值越大动画越快) |
radius /height |
最大扩散半径和初始高度 |
minRadius |
重置时的最小半径(循环起点) |
总结
通过结合Cesium的动态属性机制和自定义着色器,我们实现了多边形扩散圈
这一复杂视觉效果。此方案可扩展应用于雷达扫描、灾害范围模拟等场景。
核心思想是动态几何+材质控制,大家也可调整参数或修改着色器代码实现更多变种效果。
最后
【源码地址】:github.com/tingyuxuan2...
【预览地址】tingyuxuan2302.github.io/cesium-vue3...
如果开源对您有帮助,希望可以给一个star
,鼓励我们开源更多!
不会Cesium的基础,也很难做出更高级的效果,所以可以了解下不浪的教程
《Cesium从入门到实战》
,将Cesium的知识点进行串联,让不了解Cesium的小伙伴拥有一个完整的学习路线,并最终完成一个智慧城市
的完整项目,课程也在不断更新迭代中,想了解+作者:brown_7778(备注来意)。
有需要进可视化&Webgis交流群
可以加我:brown_7778(备注来意)。