【实战篇】Cesium Shader实现军事级雷达探测波!数字孪生开发者必学(附开源代码)

大家好,我是日拱一卒的攻城师不浪,致力于前沿科技探索,摸索小而美工作室。这是2025年输出的第12/100篇文章。

前言

在数字孪生和可视化领域,动画往往能够给用户带来更直观的体验。

今天我们来聊聊如何在Cesium中实现一个炫酷的雷达发射波效果,这种效果不仅好看,而且实用性也很强。源码请文末自取!

数字孪生中的应用场景

  1. 信号覆盖分析 - 在智慧城市中,可视化基站雷达站的信号覆盖范围

  2. 安防监控可视化 - 展示摄像头、传感器的监控范围方向

  3. 军事模拟训练 - 模拟雷达扫描区域,辅助指挥决策

  4. 航空航天领域 - 可视化空管雷达的覆盖扇区

  5. 导航与避障系统 - 在无人机自动驾驶领域展示探测范围

这些场景都需要直观地表达出从一个点发射出去,覆盖一定范围的概念,而雷达发射波效果恰好满足这一需求。

渲染原理

雷达发射波的核心原理其实蛮简单的,主要包含两个关键部分:

  1. 几何形状 - 使用圆锥体(Cylinder)作为基础几何体,通过设置顶部半径为0,底部半径为一个较大的值,从而形成锥形

  2. 材质动画 - 自定义一种特殊的材质,使用着色器创建从中心向外扩散的波纹效果

实现这种效果的关键在于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(备注来意)。

相关推荐
不浪brown1 天前
地下管网的产品经理问我:能不能用Cesium在地表挖一个洞,让我直观的看到地下的管道(附开源代码)
cesium
熟悉不过7 天前
cesium项目之cesiumlab地形数据加载
前端·javascript·vue.js·cesium·webgis·cesiumlab
前端小菜鸟一枚s8 天前
`ConstantPositionProperty` 的使用与应用
前端·javascript·cesium
前端小菜鸟一枚s8 天前
`ConstantProperty` 的使用与应用
前端·javascript·cesium
阿铎前端9 天前
Cesium系列:从入门到实践,打造属于你的3D地球应用
vue·cesium
放逐者-保持本心,方可放逐13 天前
Cesium 核心思想及基础概念应用
scene·cesium·camera·entity·primitive·viewer
该怎么办呢19 天前
Cesium双击放大地图
javascript·cesium·webgis
DragonBallSuper20 天前
在Cesium中使用ThreeJs材质(不是场景融合哦)
webgl·材质·threejs·cesium·可视化渲染
前端付杰20 天前
轻松搞定 TIFF:基于 Three.js 和 Cesium 的渲染技巧分享
前端·three.js·cesium