首页 > 建站教程 > WebGL教程 Threejs教程 >  cesium雷达扫描图实现正文

cesium雷达扫描图实现

cesium实现雷达扫描图,效果图如下:

cesium雷达扫描图实现


1、安装gsap,这个是为了动画效果

npm install gsap


2、新建RadarMaterialProperty.js文件,这个主要是雷达图的材质,代码如下:

import * as Cesium from "cesium";
import gsap from "gsap";
export default class RadarMaterialProperty {
  constructor(name) {
    this.name = name;
    this.definitionChanged = new Cesium.Event();
    Cesium.Material._materialCache.addMaterial("RadarMaterial", {
      fabric: {
        type: "RadarMaterial",
        uniforms: {
          uTime: 0,
        },
        source: `
          czm_material czm_getMaterial(czm_materialInput materialInput)
          {
            // 生成默认的基础材质
            czm_material material = czm_getDefaultMaterial(materialInput);
            // 旋转uv
            vec2 newSt = mat2(
              cos(uTime),-sin(uTime),
              sin(uTime),cos(uTime)
            )*(materialInput.st-0.5);
            newSt = newSt+0.5;
            // 获取st
            vec2 st = newSt;
            
            // 设置圆,外部透明,内部不透明
            float alpha = 1.0 - step(0.5,distance(st,vec2(0.5))) ;
           
            // 按照角度来设置强弱
            float angle = atan(st.x-0.5,st.y-0.5);
            // angle是从-pi到pi的,所以如果要设置从0-1的转变,需要加上pi
            float strength = (angle+3.1416)/6.2832;
            // 将强弱与透明度结合
            alpha = alpha*strength;
            material.alpha = alpha;
            material.diffuse = vec3(st.x,st.y,1.0);
            return material;
          }
          `,
      },
    });
    this.params = {
      uTime: 0,
    };
    gsap.to(this.params, {
      uTime: 6.28,
      duration: 1,
      repeat: -1,
      ease: "linear",
    });
  }
  getType() {
    // 返回材质类型
    return "RadarMaterial";
  }
  getValue(time, result) {
    result.uTime = this.params.uTime;
    // 返回材质值
    return result;
  }
  equals(other) {
    // 判断两个材质是否相等
    return other instanceof RadarMaterialProperty && this.name === other.name;
  }
}


3、使用

// 导入雷达材质文件
import RadarMaterialProperty from './lib/RadarMaterialProperty'
// 将椭圆添加雷达材质,并贴地:
let rader = viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(113, 22),
  name: '雷达扫描',
  ellipse: {
    semiMajorAxis: 1000,
    semiMinorAxis: 1000,
    material: new RadarMaterialProperty('雷达图'),
    height: 60,
    heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
  }
})
viewer.flyTo(rader)


4、如果觉得颜色太绚丽,可以使用下面的着色器代码替换上面的代码,同时支持传入颜色和速度:

import * as Cesium from "cesium";
import gsap from "gsap";
export default class RadarMaterialProperty {
  constructor(name, color, speed) {
    this.name = name;
    this.color = color;
    this.speed = speed
    this.definitionChanged = new Cesium.Event();
    Cesium.Material._materialCache.addMaterial("RadarMaterial", {
      fabric: {
        type: "RadarMaterial",
        uniforms: {
          color: this.color,
          speed: this.speed
        },
        source: `
          uniform vec4 color;
          uniform float speed;
          #define PI 3.14159265359;
          czm_material czm_getMaterial(czm_materialInput materialInput){
            czm_material material = czm_getDefaultMaterial(materialInput);
            vec2 st = materialInput.st;
            vec2 scrPt = st * 2.0 - 1.0;
            float time = czm_frameNumber * speed / 1000.0 ;
            vec3 col = vec3(0.0);
            mat2 rot;
            float theta = -time * 1.0 * PI - 2.2;
            float cosTheta, sinTheta;
            cosTheta = cos(theta);
            sinTheta = sin(theta);
            rot[0][0] = cosTheta;
            rot[0][1] = -sinTheta;
            rot[1][0] = sinTheta;
            rot[1][1] = cosTheta;
            vec2 scrPtRot = rot * scrPt;
            float angle = 1.0 - (atan(scrPtRot.y, scrPtRot.x) / 6.2831 + 0.5);
            float falloff = length(scrPtRot);
            material.alpha = pow(length(col + vec3(.5)),5.0);
            material.diffuse = (0.5 + pow(angle, 2.0) * falloff ) * color.rgb;
            return material;
          }
          `,
      },
    });
    this.params = {
      uTime: 0,
    };
    gsap.to(this.params, {
      uTime: 6.28,
      duration: 1,
      repeat: -1,
      ease: "linear",
    });
  }
  getType() {
    // 返回材质类型
    return "RadarMaterial";
  }
  getValue(time, result) {
    result.uTime = this.params.uTime;
    // 返回材质值
    return result;
  }
  equals(other) {
    // 判断两个材质是否相等
    return other instanceof RadarMaterialProperty && this.name === other.name;
  }
}


5、使用的时候多传个颜色和动画速度:

let rader = viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(113, 22),
  name: '雷达扫描',
  ellipse: {
    semiMajorAxis: 1000,
    semiMinorAxis: 1000,
    material: new RadarMaterialProperty('雷达图', Cesium.Color.YELLOW, 20),
    height: 60,
    heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
  }
})