大家好,我是日拱一卒的攻城师不浪,致力于前沿科技探索,摸索小而美工作室。这是2025年输出的第12/100篇文章。
前言
在数字孪生和可视化领域,动画往往能够给用户带来更直观的体验。
今天我们来聊聊如何在Cesium中实现一个炫酷的雷达发射波
效果,这种效果不仅好看,而且实用性也很强。源码请文末自取!
数字孪生中的应用场景
-
信号覆盖分析 - 在
智慧城市
中,可视化基站
、雷达站
的信号覆盖范围 -
安防监控可视化 - 展示摄像头、传感器的
监控范围
与方向
-
军事模拟训练 - 模拟
雷达扫描
区域,辅助指挥决策 -
航空航天领域 - 可视化
空管雷达
的覆盖扇区 -
导航与避障系统 - 在
无人机
、自动驾驶
领域展示探测范围

这些场景都需要直观地表达出从一个点发射出去,覆盖一定范围的概念,而雷达发射波效果恰好满足这一需求。
渲染原理
雷达发射波的核心原理其实蛮简单的,主要包含两个关键部分:
-
几何形状 - 使用
圆锥体(Cylinder)
作为基础几何体,通过设置顶部半径为0
,底部半径为一个较大的值,从而形成锥形 -
材质动画 - 自定义一种特殊的材质,使用着色器创建从中心向外扩散的波纹效果
实现这种效果的关键在于GLSL
着色器的应用。着色器通过计算片元到中心点的距离,再结合时间参数
,创建出动态波纹的视觉效果。
代码解析
1. 自定义材质属性类
javascript
class RadarPrimitiveMaterialProperty {
constructor(options = {}) {
this.opts = {
color: Cesium.Color.RED,
duration: 2000,
time: new Date().getTime(),
repeat: 30,
offset: 0,
thickness: 0.3,
...options,
};
// ...
}
// ...
getValue(time, result) {
if (!Cesium.defined(result)) {
result = {};
}
result.color = Cesium.Property.getValueOrClonedDefault(
this._color,
time,
Cesium.Color.WHITE,
result.color
);
result.time =
((new Date().getTime() - this._time) % this.duration) /
this.duration /
10;
result.repeat = this.opts.repeat;
result.offset = this.opts.offset;
result.thickness = this.opts.thickness;
return result;
}
}
先定义了雷达材质
的属性,包括颜色
、动画持续时间
、重复次数
、偏移量
和厚度
等。
特别注意getValue
方法,它实时计算当前动画时间点的参数,创造出脉冲效果。
2. 着色器定义
javascript
_registerRadarMaterial() {
if (!Cesium.Material.radarPrimitiveType) {
Cesium.Material.radarPrimitiveType = "radarPrimitive";
Cesium.Material.radarPrimitiveSource = `
uniform vec4 color;
uniform float repeat;
uniform float offset;
uniform float thickness;
czm_material czm_getMaterial(czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
float sp = 1.0/repeat;
vec2 st = materialInput.st;
float dis = distance(st, vec2(0.5));
float m = mod(dis + offset-time, sp);
float a = step(sp*(1.0-thickness), m);
material.diffuse = color.rgb;
material.alpha = a * color.a;
return material;
}`;
// ...
}
}
这段代码是整个效果的灵魂所在。它注册了一个自定义的着色器材质,实现了从中心向外扩散的波纹。来拆解一下其中的关键部分:
-
distance(st, vec2(0.5))
: 计算当前片元到纹理中心的距离 -
mod(dis + offset-time, sp)
: 通过模运算创建周期性的波纹 -
step(sp*(1.0-thickness), m)
: 生成波纹的边缘,控制其厚度 -
最后设置透明度实现脉冲效果
3. 创建雷达锥体
javascript
createRadarCone() {
const position = Cesium.Cartesian3.fromDegrees(...this.options.position);
const heading = Cesium.Math.toRadians(this.options.heading);
const pitch = Cesium.Math.toRadians(0);
const roll = Cesium.Math.toRadians(0);
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
hpr
);
this.entity = this.viewer.entities.add({
name: "Radar Cone",
position: position,
orientation: orientation,
cylinder: {
length: this.options.length,
topRadius: 0,
bottomRadius: this.options.bottomRadius,
material: new RadarPrimitiveMaterialProperty({
color: this.options.color,
thickness: this.options.thickness,
}),
},
});
return this.entity;
}
-
通过
HeadingPitchRoll
设置锥体的朝向 -
圆柱体的
topRadius
设为0,形成锥形 -
关键部分是应用了我们自定义的
RadarPrimitiveMaterialProperty
材质
如何使用
在我们将完整效果封装完大类之后,使用起来就非常简单啦~
javascript
import RadarEmission from './RadarEmission';
// 创建雷达发射波
const radar = new RadarEmission(viewer, {
position: [116.39, 39.9, 1000], // 北京的位置
heading: 45, // 朝向东北方向
color: Cesium.Color.fromCssColorString('#00ffff').withAlpha(0.7),
length: 300000, // 300公里长度
bottomRadius: 100000, // 底部半径100公里
thickness: 0.2 // 波纹的厚度
});
// 定位到雷达
radar.zoomTo();
// 销毁雷达
radar.destroy();

最后
最后总结一下,主要是结合了Cesium
的实体Entity
系统和自定义着色器的能力。
如果你还有什么想看的场景效果,欢迎在评论区留言,博主将尽力满足~
【源码地址 】:github.com/jiawanlong/...
不浪的【Cesium案例集合源码 】:github.com/tingyuxuan2...
如果开源对您有帮助,也欢迎帮我们点一个免费的star
,以鼓励和支持我们开源更多案例!
想系统学习Cesium的小伙伴儿,可以了解下不浪的教程
《Cesium从入门到实战》
,将Cesium的知识点进行串联,让不了解Cesium的小伙伴拥有一个完整的学习路线,并最终完成一个智慧城市
的完整项目,课程最近也更新了不少新内容,想了解+作者:brown_7778(备注来意)。
有需要进可视化&Webgis交流群
可以加我:brown_7778(备注来意)。