Cesium--Primitive随相机高度缩放的实现

效果就如图所示,这样的效果在cesium中本来是有Cesium.NearFarScalar这样的方法进行实现的,但是奈何考虑的性能问题在加载众多的点要素时,我选择了使用primitive的形式进行效果展现,那在primitive中就没提供Cesium.NearFarScalar属性去实现"近大远小"或者"远小近大"的效果。

不废话了先说思路,然后直接放代码,代码里面注释不多,关键是思路对齐。

我的需求是要实现数千个或者上万个站点的告警闪烁效果(一闪一闪的),所以在前期的实现上我就用Cesium.EllipseGeometry进行几何的加载,并使用着色器加图片的形式进行告警效果。但是出现的问题就是,primitive中的EllipseGeometry无法动态调整semiMajorAxis和semiMinorAxis.......

好吧,就只能换思路,思路也简单,就是根据相机视角的高度动态调整图片的大小即可。

javascript 复制代码
 const collection = new Cesium.PrimitiveCollection({ show:true })
      collection.customName = 'HasOrder'
const axis = 1500;
const instance = new Cesium.GeometryInstance({
               id: Date.now(),
              geometry: new Cesium.EllipseGeometry({
                center: Cesium.Cartesian3.fromDegrees('经度', '纬度', 50),
                semiMajorAxis: axis,
                semiMinorAxis: axis,
                rotation: Cesium.Math.toRadians(0)
              }),
              attributes: {}
            })

const instances = []; 
instances.push(instance)

//关键在这里面
const dynamicWarnGLSL = `
  uniform sampler2D image;
  uniform float scale;

  vec4 czm_getMaterial(vec2 vUv,vec2 viewPort,vec4 fragCoord)
  {

    vec2 st = vUv;
    vec2 center = vec2(0.5, 0.5);

    // 应用缩放
    vec2 translatedSt = st - center;
    vec2 scaledSt = translatedSt / scale;
    vec2 finalSt = scaledSt + center;

    // 使用step函数检查边界,性能更好
    float inBounds = step(0.0, finalSt.x) * step(finalSt.x, 1.0) * 
                    step(0.0, finalSt.y) * step(finalSt.y, 1.0);

    vec4 img = texture(image, finalSt);
    img.a = img.a * inBounds ;
    if(img.a != 0.0){
    img.a = sin(czm_frameNumber/35.0)+0.95;
    }
    return img;
  }
        `

const vertexShaderSource = `
    in vec3 position3DHigh;
    in vec3 position3DLow;
    in vec3 normal;
    in vec2 st;
    in float batchId;
    out vec3 v_positionEC;
    out vec3 v_normalEC;
    out vec2 v_st;

    void main() {
        vec4 p = czm_computePosition();
        v_positionEC = (czm_modelViewRelativeToEye * p).xyz; 
        v_normalEC = czm_normal * normal; 
        v_st = st;

        gl_Position = czm_modelViewProjectionRelativeToEye * p;
    }
`;

const fragmentShaderSource = `
  in vec2 v_st;
  in vec3 v_positionEC;
  in vec3 v_normalEC;
  void main()  {
      vec3 positionToEyeEC = -v_positionEC;
      vec3 normalEC = normalize(v_normalEC);
      czm_materialInput materialInput;
      materialInput.normalEC = normalEC;
      materialInput.positionToEyeEC = positionToEyeEC;
      materialInput.st = v_st;
      //窗口尺寸
      vec2 viewPort = gl_FragCoord.xy / czm_viewport.zw;
      vec4 color = czm_getMaterial(v_st,viewPort,gl_FragCoord);
      out_FragColor = color;
  }
`;

 const primitive = new Cesium.Primitive({
          geometryInstances: noHasOrderList,
          appearance: new Cesium.MaterialAppearance({
            material: new Cesium.Material({
              fabric: {
                type: 'dynamicsPoint',
                uniforms: {
                  image: '图片',
                  scale:1.0
                },
                source: dynamicWarnGLSL
              }
            }),
            vertexShaderSource: vertexShaderSource,
            fragmentShaderSource: fragmentShaderSource,
            flat: true
          })
        })
collection.add(primitive)
        viewer.scene.primitives.add(collection)

//监控相机的变化
   // 监听相机变化(用于改变告警图层点位的尺寸)
    viewer.camera.changed.addEventListener(() => {
      try{
        const cameraHeight = viewer.camera.positionCartographic.height;
        let scale = 1.0;
        if (cameraHeight >= maxHeight) {
            scale = maxScale;
        } else if (cameraHeight <= minHeight) {
            scale = minScale;
        } else {
            const t = (cameraHeight - minHeight) / (maxHeight - minHeight);
            scale = minScale + t * delta;
        }
        const layerName = "HasOrder";//primitive收集器的名称
        //查找需要的primitive
        for (let i = 0; i < viewer.scene.primitives._primitives.length; i++) {
          let primitive = viewer.scene.primitives._primitives[i]
          if (primitive.hasOwnProperty('customName')) {
            if (primitive.customName.indexOf(layerName) != -1) {
              primitive._primitives[0].appearance.material.uniforms.scale = scale;
            }
          }
        }
      }catch(error){
        console.log(error);
      }
   
    });
相关推荐
陈天伟教授14 小时前
人工智能应用-机器视觉:AI 鉴伪 02.虚假人脸生成
人工智能·神经网络·数码相机·生成对抗网络·dnn
博图光电2 天前
应对无序分拣挑战?博图3D视觉智能方案引领柔性制造新变革
数码相机·3d·制造
RoboWizard2 天前
相机报错怎么办 选金士顿Canvas Plus存储卡有备无患
数码相机
格林威2 天前
多相机重叠视场目标关联:解决ID跳变与重复计数的 8 个核心策略,附 OpenCV+Halcon 实战代码!
人工智能·数码相机·opencv·算法·计算机视觉·分类·工业相机
_李小白2 天前
【Android 美颜相机】第十二天:GPUImageFilterGroup 源码解析
android·数码相机
陈天伟教授3 天前
人工智能应用-机器视觉:绘画大师 04.基于风格迁移的绘画大师
人工智能·神经网络·数码相机·生成对抗网络·dnn
一路向阳~负责的男人3 天前
相机标定、手眼标定
数码相机
陈天伟教授3 天前
人工智能应用-机器视觉:绘画大师 05.还原毕加索的隐藏画
人工智能·神经网络·数码相机·生成对抗网络·dnn
线束线缆组件品替网3 天前
Same Sky 标准化音频与电源线缆接口技术详解
人工智能·数码相机·电脑·音视频·硬件工程·材料工程
自然语3 天前
三维场景管理类位姿抖动优化计划
人工智能·数码相机·算法