cesium实现飞线特效

效果如下

 另外我这边做了4种飞线特效,是用不同的着色器来实现的

 此效果依赖着色器,主要代码如下:

根据经纬度、高计算飞线数据

computeFlyline (
  point1,
  point2,
  h
) {
  let flyline = getBSRxyz(...point1, ...point2, h)
  return flyline
  // 将数据转换为cesium polyline positions格式
  function getBSRxyz (x1, y1, x2, y2, h) {
    let arr3d = getBSRPoints(x1, y1, x2, y2, h)
    let arrAll = []
    for (let ite of arr3d) {
      arrAll.push(ite[0])
      arrAll.push(ite[1])
      arrAll.push(ite[2])
    }
    return Cesium.Cartesian3.fromDegreesArrayHeights(arrAll)
  }
  function getBSRPoints (x1, y1, x2, y2, h) {
    let point1 = [y1, 0]
    let point2 = [(y2 + y1) / 2, h]
    let point3 = [y2, 0]
    let arr = getBSR(point1, point2, point3)
    let arr3d = []
    for (let i = 0; i < arr.length; i++) {
      let x = ((x2 - x1) * (arr[i][0] - y1)) / (y2 - y1) + x1
      arr3d.push([x, arr[i][0], arr[i][1]])
    }
    return arr3d
  }
  // 生成贝塞尔曲线
  function getBSR (point1, point2, point3) {
    let ps = [
      { x: point1[0], y: point1[1] },
      { x: point2[0], y: point2[1] },
      { x: point3[0], y: point3[1] }
    ]
    // 100 每条线由100个点组成
    let guijipoints = CreateBezierPoints(ps, 100)
    return guijipoints
  }
  // 贝赛尔曲线算法
  function CreateBezierPoints (anchorpoints, pointsAmount) {
    let points = []
    for (let i = 0; i < pointsAmount; i++) {
      let point = MultiPointBezier(anchorpoints, i / pointsAmount)
      points.push([point.x, point.y])
    }
    return points
  }
  function MultiPointBezier (points, t) {
    let len = points.length
    let x = 0
    let y = 0
    let erxiangshi = function (start, end) {
      let cs = 1
      let bcs = 1
      while (end > 0) {
        cs *= start
        bcs *= end
        start--
        end--
      }
      return cs / bcs
    }
    for (let i = 0; i < len; i++) {
      let point = points[i]
      x +=
        point.x *
        Math.pow(1 - t, len - 1 - i) *
        Math.pow(t, i) *
        erxiangshi(len - 1, i)
      y +=
        point.y *
        Math.pow(1 - t, len - 1 - i) *
        Math.pow(t, i) *
        erxiangshi(len - 1, i)
    }
    return { x: x, y: y }
  }
},

用着色器实例飞线材质

getFlylineMaterial (data) {
  // 创建材质,在MaterialAppearance中若不添加基础材质,模型将会透明
  let material = new Cesium.Material.fromType('Color')
  material.uniforms.color = Cesium.Color.ORANGE
  let fragmentShaderSource
  if (data === 1) {
    // 飞线效果-飞线间隔,宽度2
    fragmentShaderSource = `         
                  varying vec2 v_st;    
                  varying float v_width;    
                  varying float v_polylineAngle;
                  varying vec4 v_positionEC;
                  varying vec3 v_normalEC;
                  void main()
                  {
                      vec2 st = v_st;

                      float xx = fract(st.s - czm_frameNumber/60.0);
                      float r = xx;
                      float g = 200.0;
                      float b = 200.0;
                      float a = xx;

                      gl_FragColor = vec4(r,g,b,a);
                  }

          `
  } else if (data === 2) {
    fragmentShaderSource = `
  varying vec2 v_st;
  varying float v_width;
  varying float v_polylineAngle;
  varying vec4 v_positionEC;
  varying vec3 v_normalEC;
  void main()
  {
      vec2 st = v_st;
      float xx = fract(st.s*2.0 - czm_frameNumber/60.0);
      float r = xx;
      float g = sin(czm_frameNumber/30.0);
      float b = cos(czm_frameNumber/30.0);
      float a = xx;

      gl_FragColor = vec4(r,g,b,a);
  }

          `
  } else if (data === 3) {
    fragmentShaderSource = `
  varying vec2 v_st;
  varying float v_width;
  varying float v_polylineAngle;
  varying vec4 v_positionEC;
  varying vec3 v_normalEC;
  void main()
  {
      vec2 st = v_st;
      float xx = sin(st.s*6.0 -czm_frameNumber/5.0) - cos(st.t*6.0);
      float r = 0.0;
      float g = xx;
      float b = xx;
      float a = xx;

      gl_FragColor = vec4(r,g,b,a);
  }
          `
  } else if (data === 4) {
    fragmentShaderSource = `
  varying vec2 v_st;
  varying float v_width;
  varying float v_polylineAngle;
  varying vec4 v_positionEC;
  varying vec3 v_normalEC;
  void main()
  {
      vec2 st = v_st;
      float xx = fract(st.s*10.0 + st.t  - czm_frameNumber/60.0);
      if (st.t<0.5) {
          xx = fract(st.s*10.0 - st.t - czm_frameNumber/60.0);
      }
      float r = 0.0;
      float g = xx;
      float b = xx;
      float a = xx;
      if (st.t>0.8||st.t<0.2) {
          g = 1.0;
          b = 1.0;
          a = 0.4;
      }

      gl_FragColor = vec4(r,g,b,a);
  }
          `
  }
  // 自定义材质
  const aper = new Cesium.PolylineMaterialAppearance({
    material: material,
    translucent: true,
    vertexShaderSource: `
                  #define CLIP_POLYLINE 
                  void clipLineSegmentToNearPlane(
                      vec3 p0,
                      vec3 p1,
                      out vec4 positionWC,
                      out bool clipped,
                      out bool culledByNearPlane,
                      out vec4 clippedPositionEC)
                  {
                      culledByNearPlane = false;
                      clipped = false;
                      vec3 p0ToP1 = p1 - p0;
                      float magnitude = length(p0ToP1);
                      vec3 direction = normalize(p0ToP1);
                      float endPoint0Distance =  czm_currentFrustum.x + p0.z;
                      float denominator = -direction.z;
                      if (endPoint0Distance > 0.0 && abs(denominator) < czm_epsilon7)
                      {
                          culledByNearPlane = true;
                      }
                      else if (endPoint0Distance > 0.0)
                      {
                          float t = endPoint0Distance / denominator;
                          if (t < 0.0 || t > magnitude)
                          {
                              culledByNearPlane = true;
                          }
                          else
                          {
                              p0 = p0 + t * direction;
                              p0.z = min(p0.z, -czm_currentFrustum.x);
                              clipped = true;
                          }
                      }
                      clippedPositionEC = vec4(p0, 1.0);
                      positionWC = czm_eyeToWindowCoordinates(clippedPositionEC);
                  }
                  vec4 getPolylineWindowCoordinatesEC(vec4 positionEC, vec4 prevEC, vec4 nextEC, float expandDirection, float width, bool usePrevious, out float angle)
                  {
                      #ifdef POLYLINE_DASH
                      vec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);
                      vec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);
                      vec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);
                      vec2 lineDir;
                      if (usePrevious) {
                          lineDir = normalize(positionWindow.xy - previousWindow.xy);
                      }
                      else {
                          lineDir = normalize(nextWindow.xy - positionWindow.xy);
                      }
                      angle = atan(lineDir.x, lineDir.y) - 1.570796327;
                      angle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;
                      #endif
                      vec4 clippedPrevWC, clippedPrevEC;
                      bool prevSegmentClipped, prevSegmentCulled;
                      clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, clippedPrevWC, prevSegmentClipped, prevSegmentCulled, clippedPrevEC);
                      vec4 clippedNextWC, clippedNextEC;
                      bool nextSegmentClipped, nextSegmentCulled;
                      clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, clippedNextWC, nextSegmentClipped, nextSegmentCulled, clippedNextEC);
                      bool segmentClipped, segmentCulled;
                      vec4 clippedPositionWC, clippedPositionEC;
                      clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, clippedPositionWC, segmentClipped, segmentCulled, clippedPositionEC);
                      if (segmentCulled)
                      {
                          return vec4(0.0, 0.0, 0.0, 1.0);
                      }
                      vec2 directionToPrevWC = normalize(clippedPrevWC.xy - clippedPositionWC.xy);
                      vec2 directionToNextWC = normalize(clippedNextWC.xy - clippedPositionWC.xy);
                      if (prevSegmentCulled)
                      {
                          directionToPrevWC = -directionToNextWC;
                      }
                      else if (nextSegmentCulled)
                      {
                          directionToNextWC = -directionToPrevWC;
                      }
                      vec2 thisSegmentForwardWC, otherSegmentForwardWC;
                      if (usePrevious)
                      {
                          thisSegmentForwardWC = -directionToPrevWC;
                          otherSegmentForwardWC = directionToNextWC;
                      }
                      else
                      {
                          thisSegmentForwardWC = directionToNextWC;
                          otherSegmentForwardWC =  -directionToPrevWC;
                      }
                      vec2 thisSegmentLeftWC = vec2(-thisSegmentForwardWC.y, thisSegmentForwardWC.x);
                      vec2 leftWC = thisSegmentLeftWC;
                      float expandWidth = width * 0.5;
                      if (!czm_equalsEpsilon(prevEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) && !czm_equalsEpsilon(nextEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1))
                      {
                          vec2 otherSegmentLeftWC = vec2(-otherSegmentForwardWC.y, otherSegmentForwardWC.x);
                          vec2 leftSumWC = thisSegmentLeftWC + otherSegmentLeftWC;
                          float leftSumLength = length(leftSumWC);
                          leftWC = leftSumLength < czm_epsilon6 ? thisSegmentLeftWC : (leftSumWC / leftSumLength);
                          vec2 u = -thisSegmentForwardWC;
                          vec2 v = leftWC;
                          float sinAngle = abs(u.x * v.y - u.y * v.x);
                          expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);
                      }
                      vec2 offset = leftWC * expandDirection * expandWidth * czm_pixelRatio;
                      return vec4(clippedPositionWC.xy + offset, -clippedPositionWC.z, 1.0) * (czm_projection * clippedPositionEC).w;
                  }
                  vec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle)
                  {
                      vec4 positionEC = czm_modelViewRelativeToEye * position;
                      vec4 prevEC = czm_modelViewRelativeToEye * previous;
                      vec4 nextEC = czm_modelViewRelativeToEye * next;
                      return getPolylineWindowCoordinatesEC(positionEC, prevEC, nextEC, expandDirection, width, usePrevious, angle);
                  }

                  attribute vec3 position3DHigh;
                  attribute vec3 position3DLow;
                  attribute vec3 prevPosition3DHigh;
                  attribute vec3 prevPosition3DLow;
                  attribute vec3 nextPosition3DHigh;
                  attribute vec3 nextPosition3DLow;
                  attribute vec2 expandAndWidth;
                  attribute vec2 st;
                  attribute float batchId;

                  varying float v_width;
                  varying vec2 v_st;
                  varying float v_polylineAngle;
                  
                  varying vec4 v_positionEC;
                  varying vec3 v_normalEC;
                  void main()
                  {
                  float expandDir = expandAndWidth.x;
                  float width = abs(expandAndWidth.y) + 0.5;
                  bool usePrev = expandAndWidth.y < 0.0;

                  vec4 p = czm_computePosition();
                  vec4 prev = czm_computePrevPosition();
                  vec4 next = czm_computeNextPosition();
                  
                  float angle;
                  vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, angle);
                  gl_Position = czm_viewportOrthographic * positionWC;
                  
                  v_width = width;
                  v_st.s = st.s;
                  v_st.t = st.t;
                  // v_st.t = czm_writeNonPerspective(st.t, gl_Position.w);
                  v_polylineAngle = angle;


                  
                  vec4 eyePosition = czm_modelViewRelativeToEye * p;
                  v_positionEC =  czm_inverseModelView * eyePosition;      // position in eye coordinates
                  //v_normalEC = czm_normal * normal;                         // normal in eye coordinates
                  }

              `,
    fragmentShaderSource: fragmentShaderSource
  })
  return aper
},

创建飞线对象

addFlyline (point1, point2, h, flyLineType) {
  // 创建长方体对象
  const PolylineGeometry = new Cesium.PolylineGeometry({
    positions: this.computeFlyline(point1, point2, h),
    width: 2
  })
  const instance = new Cesium.GeometryInstance({
    geometry: PolylineGeometry,
    id: 'flyline'
  })
  flylineObj.push(viewer.scene.primitives.add(
    new Cesium.Primitive({
      geometryInstances: [instance],
      appearance: this.getFlylineMaterial(flyLineType),
      depthFailAppearance: this.getFlylineMaterial(flyLineType),
      releaseGeometryInstances: false,
      compressVertices: false
    })
  ))
},

下面奉上完整的页面代码:

<template>
  <div>
    <div id="cesiumDemo"></div>
  </div>
</template>

<script>
import cityFly from './jsonData/city_fly.json'
let viewer
let tiles = null // 官方楼栋集合
let flylineObj = [] // 飞线数组
let modalEntities = null // 模型集合
export default {
  name: 'FlyLine',
  data () {
    return {
    }
  },
  created () {
  },
  mounted () {
    this.getCesiumDem()
  },
  destroyed () {
  },
  methods: {
    // 清除飞线的方法
    deleteFlyLine () {
      for (let i = 0; i < flylineObj.length; i++) {
        flylineObj[i].destroy()
      }
      flylineObj = []
    },
    // 飞线
    flyLine () {
      for (let i = 0; i < cityFly.resdata.length; i++) {
        this.addFlyline(cityFly.resdata[i].positionStart, cityFly.resdata[i].positionEnd, 5, 1)
      }
    },
    lineDemo1 () {
      this.addFlyline([116.69431503049196, 23.38213390594852], [116.70054463128446, 23.381879429938323], 5, 1)
    },
    lineDemo2 () {
      this.addFlyline([116.69432625717093, 23.381243870793053], [116.7004522716169, 23.380978737961268], 5, 2)
    },
    lineDemo3 () {
      this.addFlyline([116.69433258176605, 23.380301392787054], [116.70023417897666, 23.38021634718416], 5, 3)
    },
    lineDemo4 () {
      this.addFlyline([116.69440049015651, 23.379683333117317], [116.70018050436582, 23.379524617418042], 5, 4)
    },
    // 创建飞线对象
    addFlyline (point1, point2, h, flyLineType) {
      // 创建长方体对象
      const PolylineGeometry = new Cesium.PolylineGeometry({
        positions: this.computeFlyline(point1, point2, h),
        width: 2
      })
      const instance = new Cesium.GeometryInstance({
        geometry: PolylineGeometry,
        id: 'flyline'
      })
      flylineObj.push(viewer.scene.primitives.add(
        new Cesium.Primitive({
          geometryInstances: [instance],
          appearance: this.getFlylineMaterial(flyLineType),
          depthFailAppearance: this.getFlylineMaterial(flyLineType),
          releaseGeometryInstances: false,
          compressVertices: false
        })
      ))
    },
    // 飞线开始
    // 根据经纬度、高计算飞线数据
    computeFlyline (
      point1,
      point2,
      h
    ) {
      let flyline = getBSRxyz(...point1, ...point2, h)
      return flyline
      // 将数据转换为cesium polyline positions格式
      function getBSRxyz (x1, y1, x2, y2, h) {
        let arr3d = getBSRPoints(x1, y1, x2, y2, h)
        let arrAll = []
        for (let ite of arr3d) {
          arrAll.push(ite[0])
          arrAll.push(ite[1])
          arrAll.push(ite[2])
        }
        return Cesium.Cartesian3.fromDegreesArrayHeights(arrAll)
      }
      function getBSRPoints (x1, y1, x2, y2, h) {
        let point1 = [y1, 0]
        let point2 = [(y2 + y1) / 2, h]
        let point3 = [y2, 0]
        let arr = getBSR(point1, point2, point3)
        let arr3d = []
        for (let i = 0; i < arr.length; i++) {
          let x = ((x2 - x1) * (arr[i][0] - y1)) / (y2 - y1) + x1
          arr3d.push([x, arr[i][0], arr[i][1]])
        }
        return arr3d
      }
      // 生成贝塞尔曲线
      function getBSR (point1, point2, point3) {
        let ps = [
          { x: point1[0], y: point1[1] },
          { x: point2[0], y: point2[1] },
          { x: point3[0], y: point3[1] }
        ]
        // 100 每条线由100个点组成
        let guijipoints = CreateBezierPoints(ps, 100)
        return guijipoints
      }
      // 贝赛尔曲线算法
      function CreateBezierPoints (anchorpoints, pointsAmount) {
        let points = []
        for (let i = 0; i < pointsAmount; i++) {
          let point = MultiPointBezier(anchorpoints, i / pointsAmount)
          points.push([point.x, point.y])
        }
        return points
      }
      function MultiPointBezier (points, t) {
        let len = points.length
        let x = 0
        let y = 0
        let erxiangshi = function (start, end) {
          let cs = 1
          let bcs = 1
          while (end > 0) {
            cs *= start
            bcs *= end
            start--
            end--
          }
          return cs / bcs
        }
        for (let i = 0; i < len; i++) {
          let point = points[i]
          x +=
            point.x *
            Math.pow(1 - t, len - 1 - i) *
            Math.pow(t, i) *
            erxiangshi(len - 1, i)
          y +=
            point.y *
            Math.pow(1 - t, len - 1 - i) *
            Math.pow(t, i) *
            erxiangshi(len - 1, i)
        }
        return { x: x, y: y }
      }
    },
    // 用着色器实例飞线材质
    getFlylineMaterial (data) {
      // 创建材质,在MaterialAppearance中若不添加基础材质,模型将会透明
      let material = new Cesium.Material.fromType('Color')
      material.uniforms.color = Cesium.Color.ORANGE
      let fragmentShaderSource
      if (data === 1) {
        // 飞线效果-飞线间隔,宽度2
        fragmentShaderSource = `         
                  varying vec2 v_st;    
                  varying float v_width;    
                  varying float v_polylineAngle;
                  varying vec4 v_positionEC;
                  varying vec3 v_normalEC;
                  void main()
                  {
                      vec2 st = v_st;

                      float xx = fract(st.s - czm_frameNumber/60.0);
                      float r = xx;
                      float g = 200.0;
                      float b = 200.0;
                      float a = xx;

                      gl_FragColor = vec4(r,g,b,a);
                  }

          `
      } else if (data === 2) {
        fragmentShaderSource = `
  varying vec2 v_st;
  varying float v_width;
  varying float v_polylineAngle;
  varying vec4 v_positionEC;
  varying vec3 v_normalEC;
  void main()
  {
      vec2 st = v_st;
      float xx = fract(st.s*2.0 - czm_frameNumber/60.0);
      float r = xx;
      float g = sin(czm_frameNumber/30.0);
      float b = cos(czm_frameNumber/30.0);
      float a = xx;

      gl_FragColor = vec4(r,g,b,a);
  }

          `
      } else if (data === 3) {
        fragmentShaderSource = `
  varying vec2 v_st;
  varying float v_width;
  varying float v_polylineAngle;
  varying vec4 v_positionEC;
  varying vec3 v_normalEC;
  void main()
  {
      vec2 st = v_st;
      float xx = sin(st.s*6.0 -czm_frameNumber/5.0) - cos(st.t*6.0);
      float r = 0.0;
      float g = xx;
      float b = xx;
      float a = xx;

      gl_FragColor = vec4(r,g,b,a);
  }
          `
      } else if (data === 4) {
        fragmentShaderSource = `
  varying vec2 v_st;
  varying float v_width;
  varying float v_polylineAngle;
  varying vec4 v_positionEC;
  varying vec3 v_normalEC;
  void main()
  {
      vec2 st = v_st;
      float xx = fract(st.s*10.0 + st.t  - czm_frameNumber/60.0);
      if (st.t<0.5) {
          xx = fract(st.s*10.0 - st.t - czm_frameNumber/60.0);
      }
      float r = 0.0;
      float g = xx;
      float b = xx;
      float a = xx;
      if (st.t>0.8||st.t<0.2) {
          g = 1.0;
          b = 1.0;
          a = 0.4;
      }

      gl_FragColor = vec4(r,g,b,a);
  }
          `
      }
      // 自定义材质
      const aper = new Cesium.PolylineMaterialAppearance({
        material: material,
        translucent: true,
        vertexShaderSource: `
                  #define CLIP_POLYLINE 
                  void clipLineSegmentToNearPlane(
                      vec3 p0,
                      vec3 p1,
                      out vec4 positionWC,
                      out bool clipped,
                      out bool culledByNearPlane,
                      out vec4 clippedPositionEC)
                  {
                      culledByNearPlane = false;
                      clipped = false;
                      vec3 p0ToP1 = p1 - p0;
                      float magnitude = length(p0ToP1);
                      vec3 direction = normalize(p0ToP1);
                      float endPoint0Distance =  czm_currentFrustum.x + p0.z;
                      float denominator = -direction.z;
                      if (endPoint0Distance > 0.0 && abs(denominator) < czm_epsilon7)
                      {
                          culledByNearPlane = true;
                      }
                      else if (endPoint0Distance > 0.0)
                      {
                          float t = endPoint0Distance / denominator;
                          if (t < 0.0 || t > magnitude)
                          {
                              culledByNearPlane = true;
                          }
                          else
                          {
                              p0 = p0 + t * direction;
                              p0.z = min(p0.z, -czm_currentFrustum.x);
                              clipped = true;
                          }
                      }
                      clippedPositionEC = vec4(p0, 1.0);
                      positionWC = czm_eyeToWindowCoordinates(clippedPositionEC);
                  }
                  vec4 getPolylineWindowCoordinatesEC(vec4 positionEC, vec4 prevEC, vec4 nextEC, float expandDirection, float width, bool usePrevious, out float angle)
                  {
                      #ifdef POLYLINE_DASH
                      vec4 positionWindow = czm_eyeToWindowCoordinates(positionEC);
                      vec4 previousWindow = czm_eyeToWindowCoordinates(prevEC);
                      vec4 nextWindow = czm_eyeToWindowCoordinates(nextEC);
                      vec2 lineDir;
                      if (usePrevious) {
                          lineDir = normalize(positionWindow.xy - previousWindow.xy);
                      }
                      else {
                          lineDir = normalize(nextWindow.xy - positionWindow.xy);
                      }
                      angle = atan(lineDir.x, lineDir.y) - 1.570796327;
                      angle = floor(angle / czm_piOverFour + 0.5) * czm_piOverFour;
                      #endif
                      vec4 clippedPrevWC, clippedPrevEC;
                      bool prevSegmentClipped, prevSegmentCulled;
                      clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, clippedPrevWC, prevSegmentClipped, prevSegmentCulled, clippedPrevEC);
                      vec4 clippedNextWC, clippedNextEC;
                      bool nextSegmentClipped, nextSegmentCulled;
                      clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, clippedNextWC, nextSegmentClipped, nextSegmentCulled, clippedNextEC);
                      bool segmentClipped, segmentCulled;
                      vec4 clippedPositionWC, clippedPositionEC;
                      clipLineSegmentToNearPlane(positionEC.xyz, usePrevious ? prevEC.xyz : nextEC.xyz, clippedPositionWC, segmentClipped, segmentCulled, clippedPositionEC);
                      if (segmentCulled)
                      {
                          return vec4(0.0, 0.0, 0.0, 1.0);
                      }
                      vec2 directionToPrevWC = normalize(clippedPrevWC.xy - clippedPositionWC.xy);
                      vec2 directionToNextWC = normalize(clippedNextWC.xy - clippedPositionWC.xy);
                      if (prevSegmentCulled)
                      {
                          directionToPrevWC = -directionToNextWC;
                      }
                      else if (nextSegmentCulled)
                      {
                          directionToNextWC = -directionToPrevWC;
                      }
                      vec2 thisSegmentForwardWC, otherSegmentForwardWC;
                      if (usePrevious)
                      {
                          thisSegmentForwardWC = -directionToPrevWC;
                          otherSegmentForwardWC = directionToNextWC;
                      }
                      else
                      {
                          thisSegmentForwardWC = directionToNextWC;
                          otherSegmentForwardWC =  -directionToPrevWC;
                      }
                      vec2 thisSegmentLeftWC = vec2(-thisSegmentForwardWC.y, thisSegmentForwardWC.x);
                      vec2 leftWC = thisSegmentLeftWC;
                      float expandWidth = width * 0.5;
                      if (!czm_equalsEpsilon(prevEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1) && !czm_equalsEpsilon(nextEC.xyz - positionEC.xyz, vec3(0.0), czm_epsilon1))
                      {
                          vec2 otherSegmentLeftWC = vec2(-otherSegmentForwardWC.y, otherSegmentForwardWC.x);
                          vec2 leftSumWC = thisSegmentLeftWC + otherSegmentLeftWC;
                          float leftSumLength = length(leftSumWC);
                          leftWC = leftSumLength < czm_epsilon6 ? thisSegmentLeftWC : (leftSumWC / leftSumLength);
                          vec2 u = -thisSegmentForwardWC;
                          vec2 v = leftWC;
                          float sinAngle = abs(u.x * v.y - u.y * v.x);
                          expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0);
                      }
                      vec2 offset = leftWC * expandDirection * expandWidth * czm_pixelRatio;
                      return vec4(clippedPositionWC.xy + offset, -clippedPositionWC.z, 1.0) * (czm_projection * clippedPositionEC).w;
                  }
                  vec4 getPolylineWindowCoordinates(vec4 position, vec4 previous, vec4 next, float expandDirection, float width, bool usePrevious, out float angle)
                  {
                      vec4 positionEC = czm_modelViewRelativeToEye * position;
                      vec4 prevEC = czm_modelViewRelativeToEye * previous;
                      vec4 nextEC = czm_modelViewRelativeToEye * next;
                      return getPolylineWindowCoordinatesEC(positionEC, prevEC, nextEC, expandDirection, width, usePrevious, angle);
                  }

                  attribute vec3 position3DHigh;
                  attribute vec3 position3DLow;
                  attribute vec3 prevPosition3DHigh;
                  attribute vec3 prevPosition3DLow;
                  attribute vec3 nextPosition3DHigh;
                  attribute vec3 nextPosition3DLow;
                  attribute vec2 expandAndWidth;
                  attribute vec2 st;
                  attribute float batchId;

                  varying float v_width;
                  varying vec2 v_st;
                  varying float v_polylineAngle;
                  
                  varying vec4 v_positionEC;
                  varying vec3 v_normalEC;
                  void main()
                  {
                  float expandDir = expandAndWidth.x;
                  float width = abs(expandAndWidth.y) + 0.5;
                  bool usePrev = expandAndWidth.y < 0.0;

                  vec4 p = czm_computePosition();
                  vec4 prev = czm_computePrevPosition();
                  vec4 next = czm_computeNextPosition();
                  
                  float angle;
                  vec4 positionWC = getPolylineWindowCoordinates(p, prev, next, expandDir, width, usePrev, angle);
                  gl_Position = czm_viewportOrthographic * positionWC;
                  
                  v_width = width;
                  v_st.s = st.s;
                  v_st.t = st.t;
                  // v_st.t = czm_writeNonPerspective(st.t, gl_Position.w);
                  v_polylineAngle = angle;


                  
                  vec4 eyePosition = czm_modelViewRelativeToEye * p;
                  v_positionEC =  czm_inverseModelView * eyePosition;      // position in eye coordinates
                  //v_normalEC = czm_normal * normal;                         // normal in eye coordinates
                  }

              `,
        fragmentShaderSource: fragmentShaderSource
      })
      return aper
    },
    // 实例cesium
    getCesiumDem () {
      Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxZWFlYjAyYS0xN2JlLTQ0OTItOGNkOC05YWJlNGY0MjI2NmQiLCJpZCI6NDkyMjYsImlhdCI6MTYxNzM0NjA3N30.crkTg0Logk_JUA7BROy0r9RqTJWCi8NZpTyu4qI11Fo'
      viewer = new Cesium.Viewer('cesiumDemo', {
        animation: false, // 是否显示动画控件
        baseLayerPicker: false, // 是否显示图层选择控件
        vrButton: false, // 是否显示VR控件
        geocoder: false, // 是否显示地名查找控件
        timeline: false, // 是否显示时间线控件
        sceneModePicker: false, // 是否显示投影方式控件
        navigationHelpButton: false, // 是否显示帮助信息控件
        navigationInstructionsInitiallyVisible: false, // 帮助按钮,初始化的时候是否展开
        infoBox: false, // 是否显示点击要素之后显示的信息
        fullscreenButton: false, // 是否显示全屏按钮
        selectionIndicator: true, // 是否显示选中指示框
        homeButton: false, // 是否显示返回主视角控件
        scene3DOnly: false, // 如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
        // terrainProvider: Cesium.createWorldTerrain({
        //   // 光照阴影
        //   requestVertexNormals: true,
        //   // 水流效果
        //   requestWaterMask: true
        // }) // 显示地形
        terrainProvider: new Cesium.EllipsoidTerrainProvider({}) // 不显示地形
      })
      this.flyLine()
      this.lineDemo1()
      this.lineDemo2()
      this.lineDemo3()
      this.lineDemo4()
      // 加载官方白膜
      tiles = new Cesium.Cesium3DTileset({
        url: Cesium.IonResource.fromAssetId(96188)
      })
      modalEntities = viewer.scene.primitives.add(tiles)
      modalEntities.style = new Cesium.Cesium3DTileStyle({
        color: {
          conditions: [
            ['true', 'rgba(68,169,255,0.5)']
          ]
        }
      })
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(116.701354, 23.3442229, 400),
        orientation: {
          heading: Cesium.Math.toRadians(0),
          pitch: Cesium.Math.toRadians(-10),
          roll: 0
        }
      })
    }
  }
}
</script>
<style scoped>
#cesiumDemo {
  width: 100vw;
  height: 100vh;
}
/* 隐藏cesium标志 */
.cesium-viewer .cesium-widget-credits {
  display: none;
}
</style>

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值