cesium通过fabric着色器,实现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 // 设置贴地后,会紧贴地形起伏 } })