首页 > 建站教程 > WebGL教程 Threejs教程 >  cesium实现流动管线、cesium流线效果正文

cesium实现流动管线、cesium流线效果

cesium通过fabric着色器,实现cesium流线效果,效果图如下:

cesium实现流动管线、cesium流线效果


具体实现步骤:

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

import * as Cesium from 'cesium'
// 流线颜色取自这张图片,你也可以替换成其他图片
const image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAAgCAYAAABkS8DlAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAADSSURBVHja7NYxEoUgDEDBYM39z2qHtZViwMFxt1FJnF/98ZXWWkRE7LWWOOt5Lsm9q/vsbu9Zdtazs/J19O5bs1XPZrwze/6V31zxbOZs1n905Wt2p3f25GzE7ohv6q3nLQCA3xEAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAA8g4AAAD//wMA4WEFTJOT5UIAAAAASUVORK5CYII='
export default class FlowPictureMaterialProperty {
    constructor(options) {
        this._definitionChanged = new Cesium.Event();
        this._color = undefined;
        this._colorSubscription = undefined;
        this.image = image;
        this.color = options.color;
        this.duration = options.duration;
        this._time = (new Date()).getTime();
    };
    get isConstant() {
        return false;
    }
    get definitionChanged() {
        return this._definitionChanged;
    }
    getType(time) {
        return Cesium.Material.FlowPictureMaterialType;
    }
    getValue(time, result) {
        if (!Cesium.defined(result)) {
            result = {};
        }
        result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
        result.color = Cesium.Property.getValueOrDefault(this._color, time, Cesium.Color.RED, result.color);
        // result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
        result.image = this.image;
        return result
    }
    equals(other) {
        return (this === other ||
            (other instanceof FlowPictureMaterialProperty &&
                Cesium.Property.equals(this._color, other._color))
        )
    }
}
Object.defineProperties(FlowPictureMaterialProperty.prototype, {
    color: Cesium.createPropertyDescriptor('color'),
})
// Cesium.FlowPictureMaterialProperty = FlowPictureMaterialProperty;
Cesium.Material.FlowPictureMaterialProperty = 'FlowPictureMaterialProperty';
Cesium.Material.FlowPictureMaterialType = 'FlowPictureMaterialType';
Cesium.Material.FlowPictureMaterialSource =
    `
  czm_material czm_getMaterial(czm_materialInput materialInput)
  {
    // 使用Cesium提供的函数来获取默认材质。
    czm_material material = czm_getDefaultMaterial(materialInput);
    // 从传入的materialInput中获取二维纹理坐标。
    vec2 st = materialInput.st;
    // 使用texture函数对指定的纹理图像进行采样,并使用fract函数来实现纹理的流动效果。
    // 这里的speed变量控制流动速度,用于实现动态效果。
    vec4 colorImage = texture(image, vec2(fract(st.s - time), st.t));
    // 将采样到的透明度附着给材质的透明度alpha属性
    material.alpha = colorImage.a * color.a;
    // 将采样得到的纹理的rgb值乘以1.5,设置为材质的diffuse颜色。
    // 这里乘以1.5是为了增强颜色的亮度。
    material.diffuse = (colorImage.rgb+color.rgb)/2.0;
    return material;
  }
`
Cesium.Material._materialCache.addMaterial(Cesium.Material.FlowPictureMaterialType, {
    fabric: {
        type: Cesium.Material.FlowPictureMaterialType,
        uniforms: {
            color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),
            time: 1,
            transparent: true,
            image: ''
        },
        source: Cesium.Material.FlowPictureMaterialSource
    },
    translucent: function (material) {
        return true;
    }
})


2、引入 FlowPictureMaterialProperty

import FlowPictureMaterialProperty from "./lib/FlowPictureMaterialProperty"


3、将流线材质应用到polyline的材质上:

viewer.entities.add({
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray([101,30,130,30,130,40,120,40,115,35]),
      material: new FlowPictureMaterialProperty({
        color: Cesium.Color.WHITE,
        duration: 2000
      }),
      // 粗细
      width: 5,
      // 贴地
      clampToGround: true // 设置贴地后,会紧贴地形起伏
    }
  })