重读Cesium(五):Primitive相关介绍(一)

在Cesium中, EntityPrimitive 两个接口是用于绘制几何图形的重要接口,我们在平时开发中会经常调用。

今天我们就来详细了解一下Primitive接口。

PS:当然后续也会聊一聊 DrawCommand 这个接口。

1.Entity与Primitive

这里会有一个疑问,为什么要有两套绘制图形的接口呢?

Entity
是Cesium封装的较高级的绘图接口,适用于普通的开发人员,即使你没有图形开发技术,你能快速使用Entity在场景中绘制各种几何形状。

Primitive
是Cesium封装的低级的绘图接口,它的绘图方式接近渲染引擎底层,但又可以不直接使用WebGL底层的接口,主要面向图形开发人员。

这里也就意味着使用Primitive进行图形绘制时需要具备一定的图形相关开发知识。

2.Primitive的构成


const circle = new Cesium.CircleGeometry({
      center: Cesium.Cartesian3.fromDegrees(110.0, 30.0, 500),
      radius: 200.0
  });
  const geometry = Cesium.CircleGeometry.createGeometry(circle); 
  const instance = new Cesium.GeometryInstance({
      geometry: geometry, 
  });
  viewer.scene.primitives.add(new Cesium.Primitive({
      geometryInstances: instance,
      appearance: new Cesium.MaterialAppearance({
          material: new Cesium.Material({
              fabric: {
                  type: "Color",
                  uniforms: {
                      color: Cesium.Color.BLUE
                  }
              }
          })
      })
  }));

上面的实例是使用Primitive创建圆并渲染到场景中,通过这个实例我们发现创建一个Primitive必须设置 geometry 与 appear
ance 两个属性,才能在场景中渲染出来。

3.Geometry与Appearance

geometry : 代表要显示的几何形状。

appear ance : 代表该几何的外观样式。

即 geometry 形成一个骨架, appear ance 表示对 geometry 上色。

一个Primitive中可以包含多个Geometry,但是只能有一个Appearance

比如下方的案例代码:


let p = [110.0, 30.0];
    let instances = [];
    for (let i = 0; i < 10; i++) {
        const instance = new Cesium.GeometryInstance({
            geometry: new Cesium.EllipseGeometry({
                center: Cesium.Cartesian3.fromDegrees(p[0], p[1]),
                semiMinorAxis: 2000.0,
                semiMajorAxis: 2000.0,
                height:1000*i
            })
        });
        instances.push(instance);
    }
    viewer.scene.primitives.add(new Cesium.Primitive({
        geometryInstances: instances,
        appearance: new Cesium.EllipsoidSurfaceAppearance({
            material: Cesium.Material.fromType('Color')
        })
    }));

每个Geometry是通过GeometryInstance来进行实例化的,通过GeometryInstance对Geometry进行实例化,同一个Geometry可以被实例化多次。
这对于展示大量数
据时很有用,比如有10万个BoxGeometry需要被显示,我们只需要创建一个BoxGeometry,然后通过GeometryInstance来设置每一个的大小、位置、颜色等。



let p = [110.0, 30.0];
    let instances = [];
    let boxGeometry = Cesium.BoxGeometry.fromDimensions({
            dimensions: new Cesium.Cartesian3(100, 100, 100)
        })
    for (let i = 0; i < 100000; i++) { 
        const instance = new Cesium.GeometryInstance({
            geometry: boxGeometry,
            modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(p[0] + Math.random() , p[1] + Math.random()  , 200+Math.random()*100))//通过modelMatrix设置不同的位置
        });
        instances.push(instance);
    }
    viewer.scene.primitives.add(new Cesium.Primitive({
        geometryInstances: instances,
        appearance: new Cesium.EllipsoidSurfaceAppearance({
            material: Cesium.Material.fromType('Color')
        })
    }));

我们还可以通过对GeometryInstance设置一些属性来进行Geometry的识别,当一个Primitive中装载有多个Geometry时,我们在鼠标交互的时候如果希望知道拾取到
的是那个Geometry,那么就可以通过GeometryInstance设置一个id,这样我们就知道拾取到的是哪个Geometry。


let p = [110.0, 30.0];
      let instances = [];
      let boxGeometry = Cesium.BoxGeometry.fromDimensions({
        dimensions: new Cesium.Cartesian3(100, 100, 100)
      })
      for (let i = 0; i < 100000; i++) {
        const instance = new Cesium.GeometryInstance({
          geometry: boxGeometry,
          modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(p[0] + Math.random(), p[1] + Math.random(), 200 + Math.random() * 100)),
          id: "BoxGeometry" + i
        });
        instances.push(instance);
      }
      viewer.scene.primitives.add(new Cesium.Primitive({
        geometryInstances: instances,
        appearance: new Cesium.EllipsoidSurfaceAppearance({
          material: Cesium.Material.fromType('Color')
        })
      }));
      new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas).setInputAction(e => {
        let pick = viewer.scene.pick(e.position);
        console.log(pick);
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

需要注意的是,因为一个Primitive只能设置一个Appearance,所以当一个Primitive装载有多个Geometry时,这些Geometry只能具有相同的外观。我们可以通过PerInstanceColorAppearance类型的外观为每个Geometry实例设置一个颜色。


let p = [110.0, 30.0];
      let instances = [];
      let boxGeometry = Cesium.BoxGeometry.fromDimensions({
        dimensions: new Cesium.Cartesian3(100, 100, 100)
      })
      for (let i = 0; i < 100000; i++) {
        const instance = new Cesium.GeometryInstance({
          geometry: boxGeometry,
          modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(p[0] + Math.random() / 10, p[1] + Math.random() / 10, 200 + Math.random() * 100)),
          id:"BoxGeometry" + i,
          attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({ alpha: 1 }))
          }
        });
        instances.push(instance);
      }
      viewer.scene.primitives.add(new Cesium.Primitive({
        geometryInstances: instances,
        appearance: new Cesium.PerInstanceColorAppearance({
          flat: true,
          translucent: false
        })
      }));

4.Primitive的优缺点

优点: 1.灵活度高,因为Primitive由Geometry和Appearance构成,我们可以单独修改它们。

2.性能好。使用Primitive可以将多个Geometry合并为一个大的Geometry来减少CPU的使用,利用GPU。

3.自定义渲染强,我们有很大的可编程性。可以操作顶点着色器与片元着色器。

缺点:

1.对于动态数据不友好,使用primitive组合多个geometry时无法更新geometry。

2.使用复杂。编写代码增加,需要图形学知识。

大家可以使用Entity与Primitive分别去创建100万条数据进行性能测试,对下对比,会发现使用Primitive创建图形编写代码会比Entity方式编写代码量多很多。但是Primitive与Entity渲染出来的效果会相差更多,帧率也会相差很大。

5.Primitive的分类

Cesium中除了Primitive类以外,还有一些以Primitive结尾的类。

1. new Cesium.GroundPrimitive (options)

贴地Primitive,将几何图形贴地使用。适用于平面类型的Geometry,如:CircleGeometry,PolygonGeometry,RectangleGeometry。

贴地Primitive通过设置 classificationType 来设置贴的目标。

2. new Cesium.ClassificationPrimitive (options)

分类Primitive,将几何体贴模型高亮显示,常用于高亮显示模型。比如倾斜摄影分层单体化或者分户单体化。

3 . new Cesium.GroundPolylinePrimitive (options)

贴地线Primitive

4. new Cesium.PointPrimitive ()

通过调用PointPrimitiveCollection#add创建点并设置其初始属性。 不要直接调用构造函数。

5. new Cesium.PointPrimitiveCollection (options)

点集合

6 . new Cesium.VoxelPrimitive (options)

体渲染

7 . new Cesium.DebugCameraPrimitive (options)

相机可视化Primitive,常用于调试相机的相关参数,这个后面涉及到折射反射等功能。

6.Primitive的几何类型

Geomtry常用的一共有12中类型,每一种类型都有对应的边线模型的Geometry。

CESIUM EPSG::900913 是指Cesium中常用的投影坐标系,也被称为Web墨卡托投影(Web Mercator)。该投影使用了EPSG:3857的代码。它是一种等距投影,用于在Web地图中显示经纬度坐标。Web墨卡托投影将地球表面投影到一个平面上,使得在地图上的距离与实际距离近似相等,从而方便进行地理数据的可视化和分析。 要在Cesium中使用EPSG::900913投影,您可以在代码中使用相应的坐标系转换库(例如proj4)来将其他坐标系转换为EPSG::900913。您还可以查找提供的地理数据文件(如geojson或json文件)中的"crs"字段,查找与EPSG::900913或EPSG::3857相关的字段名称。 请注意,虽然EPSG::900913常用于Web地图应用程序中,但它实际上是一个非正式的投影代码,因此更推荐使用EPSG::3857来表示Web墨卡托投影。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Cesium出现Unknown crs name: urn:ogc:def:crs:EPSG:xxxx](https://blog.csdn.net/weixin_43972992/article/details/127066824)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [ol-cesium:OpenLayers-Cesium集成](https://download.csdn.net/download/weixin_42121086/14949890)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GIS肆月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值