Cesium保姆教程之图片轨迹线

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>

好了,本篇的内容到这里就要结束了,如果有任何问题,请在评论区指出来,在这里也希望这篇文章也能帮助到大家,希望与大家一起进步。

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学1 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端