首页 > 建站教程 > WebGL教程 Threejs教程 >  cesium 着色器实现水波纹告警动画正文

cesium 着色器实现水波纹告警动画

cesium通过着色器实现水波纹告警动画效果,如下图:

cesium 着色器实现水波纹告警动画


具体实现步骤:

1、新建CircleWaveMaterialProperty.js,加入下面的代码:

import * as Cesium from "cesium";
function CircleWaveMaterialProperty(ob) {
  this._definitionChanged = new Cesium.Event();
  this._color = undefined;
  this._colorSubscription = undefined;
  this.color = ob.color;
  this.duration = Cesium.defaultValue(ob.duration, 1000);
  this.count = Cesium.defaultValue(ob.count, 2);
  if (this.count <= 0) {
    this.count = 1;
  }
  this.gradient = Cesium.defaultValue(ob.gradient, 0.1);
  if (this.gradient === 0) {
    this.gradient = 0;
  }
  if (this.gradient > 1) {
    this.gradient = 1;
  }
  this._time = new Date().getTime();
}
Object.defineProperties(CircleWaveMaterialProperty.prototype, {
    isConstant: {
      get: function () {
        return false;
      },
    },
    definitionChanged: {
      get: function () {
        return this._definitionChanged;
      },
    },
    color: Cesium.createPropertyDescriptor("color"),
    duration: Cesium.createPropertyDescriptor("duration"),
    count: Cesium.createPropertyDescriptor("count"),
  });
  CircleWaveMaterialProperty.prototype.getType = function (_time) {
    return Cesium.Material.CircleWaveMaterialType;
  };
  CircleWaveMaterialProperty.prototype.getValue = function (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;
    result.count = this.count;
    result.gradient = 1 + 10 * (1 - this.gradient);
    return result;
  };
  CircleWaveMaterialProperty.prototype.equals = function (other) {
    const reData =
      this === other ||
      (other instanceof CircleWaveMaterialProperty &&
        Cesium.Property.equals(this._color, other._color));
    return reData;
  };
  // Cesium.CircleWaveMaterialProperty = CircleWaveMaterialProperty
  Cesium.Material.CircleWaveMaterialType = "CircleWaveMaterial";
  Cesium.Material.CircleWaveSource = `
                                    czm_material czm_getMaterial(czm_materialInput materialInput) {
                                      czm_material material = czm_getDefaultMaterial(materialInput);
                                      material.diffuse = 1.5 * color.rgb;
                                      vec2 st = materialInput.st;
                                      vec3 str = materialInput.str;
                                      float dis = distance(st, vec2(0.5, 0.5));
                                      float per = fract(time);
                                      if (abs(str.z) > 0.001) {
                                        discard;
                                      }
                                      if (dis > 0.5) {
                                        discard;
                                      } else {
                                        float perDis = 0.5 / count;
                                        float disNum;
                                        float bl = .0;
                                        for (int i = 0; i <= 9; i++) {
                                          if (float(i) <= count) {
                                            disNum = perDis *float(i) - dis + per / count;
                                            if (disNum > 0.0) {
                                              if (disNum < perDis) {
                                                bl = 1.0 - disNum / perDis;
                                              } else if(disNum - perDis < perDis) {
                                                bl = 1.0 - abs(1.0 - disNum / perDis);
                                              }
                                              material.alpha = pow(bl, gradient);
                                            }
                                          }
                                        }
                                      }
                                      return material;
                                    }
                                    `;
  Cesium.Material._materialCache.addMaterial(
    Cesium.Material.CircleWaveMaterialType,
    {
      fabric: {
        type: Cesium.Material.CircleWaveMaterialType,
        uniforms: {
          color: new Cesium.Color(1, 0, 0, 1),
          time: 1,
          count: 1,
          gradient: 0.1,
        },
        source: Cesium.Material.CircleWaveSource,
      },
      translucent: function (material) {
        return true;
      },
    }
);
export default CircleWaveMaterialProperty


2、引入CircleWaveMaterialProperty

import CircleWaveMaterialProperty from "./lib/CircleWaveMaterialProperty";


3、通过ellipse的材质,将水波纹告警动画加入到场景中:

let circleWave = viewer.entities.add({
  id: '1',
  position:  Cesium.Cartesian3.fromDegrees(116.20, 39.53, 0),
  ellipse: {
    // height: position[2],
    semiMinorAxis: 1000,
    semiMajorAxis: 1000,
    material: new CircleWaveMaterialProperty({
    duration: 3000,
    gradient: 0.5,
    color: new Cesium.Color.fromCssColorString('red'),
    count: 2,
    }),
  },
});