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);
      }
   
    });
相关推荐
格林威6 小时前
工业相机参数解析:曝光时间与运动模糊的“生死博弈”
c++·人工智能·数码相机·opencv·算法·计算机视觉·工业相机
格林威8 小时前
工业相机图像采集:Grab Timeout 设置建议——拒绝“假死”与“丢帧”的黄金法则
开发语言·人工智能·数码相机·计算机视觉·c#·机器视觉·工业相机
格林威1 天前
工业相机图像高速存储(C++版):RAID 0 NVMe SSD 阵列暴力提速,附海康实战代码!
开发语言·c++·人工智能·数码相机·计算机视觉·工业相机·堡盟相机
rit84324991 天前
光场相机成像过程及空间域重对焦仿真
数码相机
YMWM_1 天前
相机端口查看和相机实时显示
数码相机
XuanTao771 天前
【分享】✍️手写生成器|高级版|轻松生成自然逼真手写字体
数码相机·计算机网络·网络安全·智能手机·软件工程
菩提树下的凡夫1 天前
3D相机如何获取高精度的xyz
数码相机·3d
格林威1 天前
工业相机图像高速存储(C++版):RAID 0 NVMe SSD 阵列方法,附堡盟相机实战代码!
开发语言·c++·人工智能·数码相机·opencv·计算机视觉·视觉检测
He BianGu2 天前
【项目】Vision Master OpenCV 4.0 版本发行说明
数码相机
双翌视觉2 天前
高精度视觉对位实现键盘线路薄膜定位纠偏
数码相机·计算机外设