Cesium保姆教程之图片轨迹线
本教程主要将工作中用的cesium功能特点本着简洁的原则进行总结,尽量对每一步代码进行注释,以此来达到通透理解。本篇是本教程的第二个功能,主要实现图片轨迹线材质的实现和对象展示效果,可将轨迹绘制成一条流动的轨迹线并将轨迹赋予图片纹理,以此来实现图片在流动的效果。
实现效果

实现原理
图片轨迹线的实现原理是通过自定义对应的图像轨迹材质ImageTrailMaterial,借助于Cesium的entity类的polyline对象对轨迹进行绘制,再将材质按照纹理对象附到轨迹线上。
实现过程
材质对象
材质绘制(WebGL)
fragementShader(参考网上教程)
glsl
uniform sampler2D image;
uniform float speed;
uniform vec4 color;
uniform vec2 repeat;
czm_material czm_getMaterial(czm_materialInput materialInput){
czm_material material=czm_getDefaultMaterial(materialInput);
vec2 st=repeat * materialInput.st;
float time=fract(czm_frameNumber*speed/1000.);
//st.s是横轴方向运动,st.t是纵轴,
//vec2(fract(st.s-time),st.t)是横轴按照时间变化而变化,纵轴保持正常不变化
vec4 colorImage=texture2D(image,vec2(fract(st.s-time),st.t));
if(color.a==0.){
material.alpha=colorImage.a;
material.diffuse=colorImage.rgb;
}else{
material.alpha=colorImage.a*color.a;
material.diffuse=max(color.rgb*material.alpha*3.,color.rgb);
}
return material;
}
完整代码
js
import * as Cesium from "cesium"
/**
* 定义Cesium材质对象
*/
class ImageTrailMaterial {
constructor(options = {}) {
this._definitionChanged = new Cesium.Event();
this._color = undefined;
this._colorSubscription = undefined;
this._speed = undefiend;
this._speedSubscription = undefined;
this._image = undefined;
this._imageSubscription = undefined;
this._repeat = undefined;
this._repeatSubscription = undefined;
this.color = options.color || Cesium.Color.fromBytes(0, 0, 255, 255);
this.speed = options.speed || 1;
this.image = options.image;
this.repeat = new Cesium.Cartesian2(
options.repeat?.x || 1,
options.repeat?.y || 1
);
}
get isConstant() {
return falsse;
}
get definitionChanged() {
return this._definitionChanged;
}
getType() {
return Cesium.Material.ImageTrailMaterialType;
}
getValue(time, result) {
if (!result) {
result = {};
}
result.color = Cesium.Property.getValueOrUndefined(this._color, time);
result.image = Cesium.Property.getValueOrUndefined(this._image, time);
result.repeat = Cesium.Property.getValueOrUndefined(this._repeat, time);
result.speed = this._speed;
return result;
}
equals(other) {
return (
this === other ||
(other instanceof ImageTrailMaterial &&
Cesium.Property.equals(this._color, other._color) &&
Cesium.Property.equals(this._image, other._image) &&
Cesium.Property.equals(this._repeat, other._repeat) &&
Cesium.Property.equals(this._speed, other._speed))
);
}
}
Object.defineProperties(ImageTrailMaterial.prototype, {
color: Cesium.createPropertyDescriptor("color"),
speed: Cesium.createPropertyDescriptor("speed"),
image: Cesium.createPropertyDescriptor("image"),
repeat: Cesium.createPropertyDescriptor("repeat"),
});
//材质类型
Cesium.Material.ImageTrailMaterialType = "PolylineImageTrail";
//添加材质到缓冲区中
Cesium.Material._materialCache.addMaterial(
Cesium.Material.ImageTrailMaterialType,
{
fabric: {
type: Cesium.Material.ImageTrailMaterialType,
//uniform变量
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
image: Cesium.Material.DefaultImageId,
speed: 1,
repeat: new Cesium.Cartesian2(1, 1),
},
//
source: fragementShader
},
translucent: function () {
return true;
},
}
);
export default ImageTrailMaterial;
前端调用
js
<template>
<div id="cesiumContainer"></div>
</template>
<script setup>
import * as Cesium from "cesium
import { onMounted } from "vue
import ImageTrailMaterial from "@/ImageTrailMaterial";
let viewer = undefined;
onMounted(() => {
})
const addEntities =(viewer) => {
viewer.entities.add({
polyline: {
clampToGround: true,
//轨迹线的分布位置
positions: Cesium.Cartesian3.fromDegreesArray([
137, 36, 138, 36, 138, 37, 137, 37, 137, 38, 138, 38
]),
material: new ImageTrailMaterial({
//图片的颜色
color: Cesium.Color.RED,
//轨迹运行的速率
speed: 10,
//随意一张图片
image: require("@/star.png"),
//将轨迹分成一行50个图片
repeat: { x: 40, y: 1 },
}),
width: 20,
},
});
}
</script>
<style scoped>
#cesiumContainer {
width: 100%;
height: 100%;
position: relative;
}
</style>
好了,本篇的内容到这里就要结束了,如果有任何问题,请在评论区指出来,在这里也希望这篇文章也能帮助到大家,希望与大家一起进步。