cesium学习(五)-Primitive

什么是 Primitive

Primitive 是 Cesium 中更接近底层渲染的对象。

如果说 Entity 是"业务层对象",那 Primitive 就是"渲染层对象"。

text 复制代码
Entity    = 高层封装,写起来简单,适合业务开发
Primitive = 底层渲染单元,性能更高,适合大量数据

Cesium 最终真正提交给 GPU 绘制的,基本都要落到 Primitive 或 DrawCommand 这一层。

Entity 和 Primitive 的关系

平时我们用 viewer.entities.add() 加点、线、面时,其实不是 Entity 自己在渲染。

真实链路是:

text 复制代码
Entity
  ↓
Visualizer
  ↓
Primitive
  ↓
Scene
  ↓
GPU

比如:

Entity 属性 内部可能使用的渲染对象
point PointPrimitiveCollection
billboard BillboardCollection
label LabelCollection
polyline PolylineCollection / Primitive
polygon Primitive / GroundPrimitive
model Model

所以可以理解为:

text 复制代码
Entity 负责描述业务对象
Primitive 负责真正渲染

Primitive 在 Viewer 中的位置

Primitive 通常加到 viewer.scene.primitives

js 复制代码
viewer.scene.primitives.add(primitive)

它的位置关系是:

text 复制代码
Viewer
 └─ scene
    ├─ primitives
    │  ├─ Primitive
    │  ├─ Model
    │  ├─ Cesium3DTileset
    │  └─ PointPrimitiveCollection
    └─ globe

注意:Primitive 不是加到 viewer.entities,而是加到 viewer.scene.primitives

PrimitiveCollection

PrimitiveCollection 是 Primitive 的集合容器,用来管理一组 Primitive。

其实 viewer.scene.primitives 本身就是一个 PrimitiveCollection

text 复制代码
viewer.scene.primitives
  = Scene 中默认的 PrimitiveCollection

所以平时写:

js 复制代码
viewer.scene.primitives.add(primitive)

本质就是把一个 Primitive 添加到 Scene 默认的 PrimitiveCollection 里。

创建自己的 PrimitiveCollection

实际项目中,通常会自己创建一个 PrimitiveCollection 来管理某一类业务对象。

js 复制代码
const deviceLayer = new Cesium.PrimitiveCollection()

viewer.scene.primitives.add(deviceLayer)

然后把相关 Primitive 加到这个集合里:

js 复制代码
deviceLayer.add(pointCollection)
deviceLayer.add(billboardCollection)
deviceLayer.add(labelCollection)

这样可以把一组 Primitive 当成一个"图层"来管理。

text 复制代码
viewer.scene.primitives
 ├─ deviceLayer
 │  ├─ PointPrimitiveCollection
 │  ├─ BillboardCollection
 │  └─ LabelCollection
 ├─ Cesium3DTileset
 └─ Model

控制显示隐藏

PrimitiveCollectionshow 属性,可以统一控制整组 Primitive 的显示隐藏。

js 复制代码
deviceLayer.show = false

这比一个个设置内部 Primitive 的 show 更方便。

删除整个集合

js 复制代码
viewer.scene.primitives.remove(deviceLayer)

删除集合后,集合里的 Primitive 也会随之从场景中移除。

如果只是清空集合里的内容:

js 复制代码
deviceLayer.removeAll()

什么时候用 PrimitiveCollection

场景 是否适合
管理一组设备点、图标、文字 适合
做业务图层显示隐藏 适合
按模块清理 Primitive 适合
单个 Primitive 没必要
Entity 数据分组 CustomDataSource 更合适

简单理解:

text 复制代码
CustomDataSource 管 Entity 分组
PrimitiveCollection 管 Primitive 分组

为什么 Primitive 性能更好

Primitive 性能更好的原因,不是它"更神奇",而是它少做了很多高层封装工作。

Entity 提供了很多方便能力:

  • Property 动态属性
  • 时间系统
  • 自动插值
  • DataSource 管理
  • 高层事件和可读性

这些能力很方便,但也会带来额外开销。

Primitive 更直接:

  • 更少对象包装
  • 更少运行时更新
  • 更适合批量提交 GPU
  • 更适合静态或半静态大数据
text 复制代码
少量业务对象:Entity 更方便
大量渲染对象:Primitive 更高效

什么时候用 Primitive

场景 推荐
几十个点、线、面 Entity
需要动态时间、轨迹、插值 Entity
上万、十万级点位 PointPrimitiveCollection
大量图标 BillboardCollection
大量文字 LabelCollection
大量线 PolylineCollection
大量静态几何 Primitive
贴地面、贴地区域 GroundPrimitive
贴地折线 GroundPolylinePrimitive
3D Tiles、模型、点云 scene.primitives
自定义材质、底层渲染控制 Primitive + Appearance

简单判断:

text 复制代码
优先用 Entity
性能不够,再换 Primitive

不要一开始就为了"底层"而使用 Primitive。Primitive 写法更复杂,维护成本也更高。

常见 Primitive 类型

类型 作用
PrimitiveCollection Primitive 集合容器,用来做分组管理
Primitive 通用几何渲染
GroundPrimitive 贴地几何
GroundPolylinePrimitive 贴地折线
ClassificationPrimitive 分类 / 遮罩 3D Tiles 或地形
Model glTF / glb 模型
Cesium3DTileset 3D Tiles 数据
PointPrimitiveCollection 大量点
BillboardCollection 大量图标
LabelCollection 大量文字
PolylineCollection 大量线

其中 PrimitiveCollection 是"容器",主要负责管理其它 Primitive;PointPrimitiveCollectionBillboardCollectionLabelCollection 这类是"专用渲染集合",自己负责批量渲染点、图标或文字。

Primitive 的基本结构

通用 Primitive 通常由两部分组成:

text 复制代码
Primitive
 ├─ geometryInstances  描述几何数据
 └─ appearance         描述怎么渲染

也就是:

text 复制代码
Geometry = 形状是什么
Appearance = 长什么样
Primitive = 把形状和样式交给 Cesium 渲染

GeometryInstance

GeometryInstance 用来描述一个几何实例。

它通常包含:

  • geometry:几何形状。
  • modelMatrix:模型矩阵,控制位置、旋转、缩放。
  • attributes:颜色、显示隐藏等实例属性。
  • id:用于拾取时识别对象。
js 复制代码
const instance = new Cesium.GeometryInstance({
  geometry: new Cesium.RectangleGeometry({
    rectangle: Cesium.Rectangle.fromDegrees(116.3, 39.8, 116.5, 40.0),
    height: 0
  }),
  attributes: {
    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
      Cesium.Color.RED.withAlpha(0.5)
    )
  },
  id: 'rectangle-1'
})

常见 Geometry 类型

Geometry 用途
RectangleGeometry 矩形面
PolygonGeometry 多边形面、拉伸体
CircleGeometry / EllipseGeometry 圆 / 椭圆
BoxGeometry 长方体
SphereGeometry / EllipsoidGeometry 球 / 椭球
CylinderGeometry 圆柱 / 圆锥
CorridorGeometry 带宽度的走廊
WallGeometry
PolylineGeometry 折线
GroundPolylineGeometry 贴地折线
*OutlineGeometry 各种形状对应的线框版本

Outline 后缀的 Geometry 只画线框,需要配合 PerInstanceColorAppearance({ flat: true }) 渲染。

如果要给一个面同时画填充和外框,通常做法是创建两个 GeometryInstance:一个用 PolygonGeometry,一个用 PolygonOutlineGeometry,分别放在两个 Primitive 里。

实例属性

attributes 不只是颜色,还可以控制显示和距离显示条件:

属性 类型 作用
color ColorGeometryInstanceAttribute 每个实例的颜色
show ShowGeometryInstanceAttribute 每个实例的显示 / 隐藏
distanceDisplayCondition DistanceDisplayConditionGeometryInstanceAttribute 按距离范围显示
js 复制代码
attributes: {
  color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED),
  show: new Cesium.ShowGeometryInstanceAttribute(true),
  distanceDisplayCondition:
    new Cesium.DistanceDisplayConditionGeometryInstanceAttribute(0, 100000)
}

注意:只有创建时声明过的属性,后续才能通过 getGeometryInstanceAttributes 改。运行时不能新增没声明过的属性。

Appearance

Appearance 决定 Primitive 怎么显示。

常见 Appearance:

Appearance 用途
PerInstanceColorAppearance 每个实例单独设置颜色
MaterialAppearance 使用材质渲染
EllipsoidSurfaceAppearance 贴在椭球表面的材质
PolylineMaterialAppearance 线材质

最常用的是 PerInstanceColorAppearance

js 复制代码
const appearance = new Cesium.PerInstanceColorAppearance({
  translucent: true,
  closed: true
})

几个常用参数:

参数 说明
translucent 是否半透明,决定是否参与混合渲染
closed 几何是否是闭合体(如 box、拉伸 polygon),开启可启用背面剔除
flat 是否平面着色,画线框、贴地几何常用

如果要使用材质(条带、闪烁、流光等),换成 MaterialAppearancePolylineMaterialAppearance

js 复制代码
const appearance = new Cesium.MaterialAppearance({
  material: Cesium.Material.fromType('Color', {
    color: Cesium.Color.RED.withAlpha(0.5)
  })
})

创建一个面 Primitive

下面是一个完整示例:创建一个红色半透明矩形面。

js 复制代码
const instance = new Cesium.GeometryInstance({
  geometry: new Cesium.RectangleGeometry({
    rectangle: Cesium.Rectangle.fromDegrees(116.3, 39.8, 116.5, 40.0),
    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
  }),
  attributes: {
    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
      Cesium.Color.RED.withAlpha(0.5)
    )
  },
  id: 'demo-rectangle'
})

const primitive = new Cesium.Primitive({
  geometryInstances: instance,
  appearance: new Cesium.PerInstanceColorAppearance({
    translucent: true
  })
})

viewer.scene.primitives.add(primitive)

批量创建 Primitive

Primitive 的优势通常体现在批量数据。

多个 GeometryInstance 可以合并到一个 Primitive 里:

js 复制代码
const instances = []

for (let i = 0; i < 1000; i++) {
  instances.push(
    new Cesium.GeometryInstance({
      geometry: new Cesium.RectangleGeometry({
        rectangle: Cesium.Rectangle.fromDegrees(
          116 + i * 0.001,
          39.8,
          116.0005 + i * 0.001,
          39.8005
        ),
        vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
      }),
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(
          Cesium.Color.BLUE.withAlpha(0.4)
        )
      },
      id: `rect-${i}`
    })
  )
}

const primitive = new Cesium.Primitive({
  geometryInstances: instances,
  appearance: new Cesium.PerInstanceColorAppearance({
    translucent: true
  })
})

viewer.scene.primitives.add(primitive)

这样做的核心意义是:

text 复制代码
很多几何实例 -> 合成一个 Primitive -> 更少 draw call / 更少管理开销

合并后每个实例仍然可以通过 id 单独拾取,也可以通过 getGeometryInstanceAttributes(id) 单独改颜色或显隐。

Primitive 常用参数

new Primitive({...}) 除了 geometryInstancesappearance,还有几个常用参数:

参数 默认 说明
asynchronous true 是否异步创建 GPU 资源
allowPicking true 是否参与拾取,关闭可节省一点显存
releaseGeometryInstances true 创建完是否释放 CPU 端几何数据
modelMatrix 单位阵 整体平移 / 旋转 / 缩放
shadows DISABLED 阴影模式
debugShowBoundingVolume false 调试用,显示包围盒

如果在 add 之后需要立刻读取 getGeometryInstanceAttributes,可以把 asynchronous 设为 false,但会阻塞主线程,不适合大批量数据。

用 modelMatrix 整体移动

一旦 Primitive 创建完成,几何顶点很难再改。但可以通过 modelMatrix 整体平移、旋转、缩放:

js 复制代码
const origin = Cesium.Cartesian3.fromDegrees(116.5, 39.9, 0)

primitive.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin)

适合:

  • 整组对象统一偏移
  • 旋转一组对象
  • 编辑器里拖动一个图层

如果是每个对象需要独立移动,仍然要重建 Primitive,或者改用 Entity / Collection 这类更适合频繁更新的方案。

PointPrimitiveCollection

如果只是大量点,不一定要用通用 Primitive,可以用 PointPrimitiveCollection

js 复制代码
const points = viewer.scene.primitives.add(
  new Cesium.PointPrimitiveCollection()
)

for (let i = 0; i < 10000; i++) {
  points.add({
    position: Cesium.Cartesian3.fromDegrees(
      116 + Math.random(),
      39 + Math.random(),
      100
    ),
    color: Cesium.Color.YELLOW,
    pixelSize: 6
  })
}

适合:

  • 海量设备点
  • 监测点
  • 采样点
  • 雷达点
  • 简单散点图

BillboardCollection

大量图标建议用 BillboardCollection

js 复制代码
const billboards = viewer.scene.primitives.add(
  new Cesium.BillboardCollection()
)

billboards.add({
  position: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 100),
  image: '/marker.png',
  scale: 1
})

如果只有几十个标记点,用 Entity 的 billboard 更简单;如果是成千上万个图标,BillboardCollection 更合适。

LabelCollection

大量文字可以用 LabelCollection

js 复制代码
const labels = viewer.scene.primitives.add(
  new Cesium.LabelCollection()
)

labels.add({
  position: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 100),
  text: '北京',
  font: '16px sans-serif',
  fillColor: Cesium.Color.WHITE,
  outlineColor: Cesium.Color.BLACK,
  outlineWidth: 2,
  style: Cesium.LabelStyle.FILL_AND_OUTLINE
})

常用于:

  • 设备名称
  • 区域名称
  • 测点编号
  • 地名标注

PolylineCollection

大量普通折线可以用 PolylineCollection

js 复制代码
const polylines = viewer.scene.primitives.add(
  new Cesium.PolylineCollection()
)

polylines.add({
  positions: Cesium.Cartesian3.fromDegreesArray([
    116.3, 39.9,
    116.4, 39.95,
    116.5, 39.9
  ]),
  width: 2,
  material: Cesium.Material.fromType('Color', {
    color: Cesium.Color.YELLOW
  })
})

注意:

  • PolylineCollection 画的是空间折线,不贴地。
  • 贴地折线要用 GroundPolylinePrimitive,不是 PolylineCollection,也不是 GroundPrimitive

GroundPrimitive

GroundPrimitive 用于贴地几何,常见于贴地区域、地块、范围面。

js 复制代码
const instance = new Cesium.GeometryInstance({
  geometry: new Cesium.RectangleGeometry({
    rectangle: Cesium.Rectangle.fromDegrees(116.3, 39.8, 116.5, 40.0)
  }),
  attributes: {
    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
      Cesium.Color.GREEN.withAlpha(0.4)
    )
  }
})

const groundPrimitive = new Cesium.GroundPrimitive({
  geometryInstances: instance,
  appearance: new Cesium.PerInstanceColorAppearance({
    translucent: true
  })
})

viewer.scene.primitives.add(groundPrimitive)

GroundPrimitive 默认会同时贴在地形和 3D Tiles 表面上。可以通过 classificationType 控制:

js 复制代码
const groundPrimitive = new Cesium.GroundPrimitive({
  geometryInstances: instance,
  classificationType: Cesium.ClassificationType.TERRAIN,
  appearance: new Cesium.PerInstanceColorAppearance({
    translucent: true
  })
})
取值 含义
TERRAIN 只贴地形
CESIUM_3D_TILE 只贴 3D Tiles
BOTH 都贴(默认)

注意:

  • GroundPrimitive 适合平面形状(矩形、多边形、圆)。如果是带高度的体(拉伸 polygon、box)要做"分类"效果,要用 ClassificationPrimitive
  • 贴地效果依赖地形和深度能力,不同浏览器、不同地形数据下表现可能有差异。

GroundPolylinePrimitive

贴地折线要用 GroundPolylinePrimitive,配合 GroundPolylineGeometry

js 复制代码
const instance = new Cesium.GeometryInstance({
  geometry: new Cesium.GroundPolylineGeometry({
    positions: Cesium.Cartesian3.fromDegreesArray([
      116.3, 39.9,
      116.4, 39.95,
      116.5, 39.9
    ]),
    width: 4
  }),
  attributes: {
    color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
  }
})

const polylinePrimitive = new Cesium.GroundPolylinePrimitive({
  geometryInstances: instance,
  appearance: new Cesium.PolylineColorAppearance()
})

viewer.scene.primitives.add(polylinePrimitive)

适合:

  • 道路、路网
  • 行政边界
  • 电力线、管线在地表的投影

GroundPolylinePrimitive 同样支持 classificationType

ClassificationPrimitive

ClassificationPrimitive 用于对地形或 3D Tiles 做分类显示。

比如:

  • 给某一块地形区域着色
  • 高亮 3D Tiles 中某个区域
  • 做地下管线、建筑分类遮罩

它不是简单"画一个面",而是把这个几何体投射到地形或 3D Tiles 上做分类效果。

text 复制代码
普通 Primitive = 自己显示
ClassificationPrimitive = 影响地形 / 3D Tiles 的显示

Model 也是 Primitive

加载 glTF / glb 模型时,底层也是 Primitive 层的对象。

js 复制代码
const model = await Cesium.Model.fromGltfAsync({
  url: '/models/car.glb',
  modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(116.39, 39.9, 0)
  ),
  scale: 1
})

viewer.scene.primitives.add(model)

如果是少量业务模型,也可以用 Entity 的 model

js 复制代码
viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(116.39, 39.9, 0),
  model: {
    uri: '/models/car.glb'
  }
})

简单判断:

text 复制代码
业务模型、需要属性和时间控制 -> Entity model
大量模型、需要底层控制       -> Model Primitive

Cesium3DTileset 也是 Primitive

3D Tiles 也加到 scene.primitives

js 复制代码
const tileset = await Cesium.Cesium3DTileset.fromUrl('/tileset/tileset.json')

viewer.scene.primitives.add(tileset)
viewer.flyTo(tileset)

所以不要把 3D Tiles 加到 viewer.entities

text 复制代码
Entity             -> viewer.entities
Primitive / Model / 3D Tiles -> viewer.scene.primitives

Primitive 拾取

Primitive 可以通过 scene.pick 拾取。

js 复制代码
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)

handler.setInputAction((movement) => {
  const picked = viewer.scene.pick(movement.position)

  if (!Cesium.defined(picked)) {
    return
  }

  console.log(picked.id)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)

如果是 GeometryInstance,通常可以通过 id 标识业务对象。

js 复制代码
const instance = new Cesium.GeometryInstance({
  geometry,
  id: {
    type: 'area',
    id: 'area-001',
    name: '测试区域'
  }
})

拾取后:

js 复制代码
console.log(picked.id)

picked.primitive 和 picked.id 的区别

scene.pick 返回的对象通常包含两个常用字段:

字段 含义
picked.primitive 命中的渲染对象本身(如 PrimitiveModelPointPrimitiveBillboard 等)
picked.id 业务标识,对应 GeometryInstance / Entityid

简单理解:

text 复制代码
picked.primitive = 是哪个 Primitive 渲染出来的(渲染层)
picked.id        = 命中的具体业务对象是谁(业务层)

几个常见情况:

  • 普通 Primitive + GeometryInstancepicked.primitive 是这个 Primitive 实例,picked.idGeometryInstance 上设置的 id(可以是字符串,也可以是对象)。
  • PointPrimitiveCollection / BillboardCollection / LabelCollectionpicked.primitive 是集合里的具体那一项(PointPrimitive / Billboard / Label),没有 picked.id,业务字段通常自己挂在对象上(如 picked.primitive.customData)。
  • Entitypicked.id 是 Entity 实例本身,可以直接 picked.id instanceof Cesium.Entity 判断。
  • Cesium3DTileset :拾取结果是 Cesium3DTileFeature,通过 picked.getProperty('xxx') 读属性,没有常规的 id

所以一般写拾取逻辑可以这样区分:

js 复制代码
const picked = viewer.scene.pick(movement.position)

if (!Cesium.defined(picked)) return

if (picked.id instanceof Cesium.Entity) {
  // Entity
} else if (picked instanceof Cesium.Cesium3DTileFeature) {
  // 3D Tiles 要素
} else if (picked.id) {
  // GeometryInstance
} else if (picked.primitive) {
  // PointPrimitive / Billboard / Label / Model 等
}

修改 Primitive 样式

Primitive 创建后,不像 Entity 那样方便动态修改。

如果使用 GeometryInstance 的颜色属性,可以通过 getGeometryInstanceAttributes 修改部分属性:

js 复制代码
const attributes = primitive.getGeometryInstanceAttributes('demo-rectangle')

attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
  Cesium.Color.YELLOW.withAlpha(0.8)
)

注意:

  • 这里的 'demo-rectangle' 对应的是 GeometryInstanceid
  • 只有创建 GeometryInstance 时声明过的 attributes 才能在运行时通过 getGeometryInstanceAttributes 修改。没声明过的属性运行时加不上。
  • 如果 Primitive 还在异步创建(asynchronous: true,默认),getGeometryInstanceAttributes 可能拿不到结果,需要等 Primitive 就绪。

如果要频繁更新位置、几何形状、材质,Primitive 可能并不适合。频繁变化的业务对象可以继续用 Entity,或者自己设计数据更新策略。

删除 Primitive

删除 Primitive 使用 scene.primitives.remove()

js 复制代码
viewer.scene.primitives.remove(primitive)

删除所有 Primitive:

js 复制代码
viewer.scene.primitives.removeAll()

但要小心,removeAll() 会把场景里的 Primitive 都删掉,包括你可能添加的模型、tileset、collection。

更推荐保存引用,按需删除:

js 复制代码
const primitive = viewer.scene.primitives.add(...)

// later
viewer.scene.primitives.remove(primitive)

Primitive 的生命周期

Primitive 一般经历这几个阶段:

text 复制代码
创建 Geometry / Appearance
      ↓
创建 Primitive
      ↓
add 到 scene.primitives
      ↓
Cesium 异步创建 GPU 资源
      ↓
参与每帧渲染
      ↓
remove 后释放资源

几点注意:

  • Primitive 默认 asynchronous: trueadd 后并不会立刻就绪。
  • 异步阶段调用 getGeometryInstanceAttributes 可能拿不到属性。
  • 需要立即可用时可以设置 asynchronous: false,但会阻塞主线程,不适合大批量数据。
  • releaseGeometryInstances 默认是 true,意味着 CPU 端的几何在上传 GPU 后会被释放,无法再读取顶点。如果之后还要查询顶点数据,需要显式设置成 false

和 Entity 的对比

对比项 Entity Primitive
抽象层级
使用难度 简单 较复杂
性能 适合中小数据 适合大数据
动态属性 支持好 需要自己处理
时间系统 支持 不直接支持
批量渲染 一般
拾取 简单 需要 id / feature
适合场景 业务对象 渲染优化、大规模静态数据

常见问题

  1. 为什么 Primitive 加了没显示?

    常见原因是坐标错误、几何范围太小、相机没飞到目标区域、appearancevertexFormat 不匹配,或者 Primitive 还没 ready。

  2. 为什么颜色不生效?

    如果使用 PerInstanceColorAppearance,geometry 需要配置对应的 vertexFormat

    js 复制代码
    vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
  3. 为什么贴地面看不到?

    GroundPrimitive 依赖地形和深度能力,部分几何类型、浏览器环境或地形数据可能影响显示。可以先用普通 Primitive 验证几何是否正确。

  4. 为什么修改 Primitive 不方便?

    Primitive 面向底层渲染,创建后很多几何数据已经进入 GPU 资源。它适合批量静态数据,不适合频繁改变形状。

  5. 为什么大量 Entity 卡顿?

    Entity 有 Property、Visualizer、事件、时间系统等高层封装。数量上来后 CPU 开销会明显增加,可以考虑改成 Primitive 或 Collection。

  6. scene.primitives.removeAll() 为什么把模型也删了?

    因为 Model、3D Tiles、PointPrimitiveCollection 等都在 scene.primitives 里。实际项目中不要随便调用 removeAll(),最好自己维护引用。

  7. Primitive 和 3D Tiles 是什么关系?

    3D Tiles 在 Cesium 中也是 Primitive 层对象,加载后加入 scene.primitives。但它内部有自己的 tile 树、LOD、请求调度和缓存机制。

小结

Primitive 是 Cesium 的底层渲染对象,适合大规模、静态或半静态数据。

实际开发中可以按这个顺序选择:

场景 推荐
普通业务点线面 Entity
大量点 PointPrimitiveCollection
大量图标 BillboardCollection
大量文字 LabelCollection
大量静态几何 Primitive
大量线 PolylineCollection
贴地区域 GroundPrimitive
贴地折线 GroundPolylinePrimitive
分类地形或 3D Tiles ClassificationPrimitive
glTF / glb 模型 Model 或 Entity model
城市级三维数据 Cesium3DTileset

一句话总结:

text 复制代码
Entity 负责好用,Primitive 负责高性能。
相关推荐
悟空瞎说1 小时前
Git Worktree 实战:多 AI 编码代理并行开发,彻底解决分支切换冲突痛点
前端·git
悠哉摸鱼大王1 小时前
cesium学习(四)-相机
前端·cesium
zeqinjie2 小时前
Skills-Flutter 内测泄漏审核
前端·flutter·app
村上小树3 小时前
非常简单地学习一下shareDB的原理
前端·javascript
认真的薛薛3 小时前
阿里云: A记录 & CNAME
服务器·前端·阿里云
2301_815645383 小时前
css基础
前端·css
Hilaku3 小时前
求求你们🙏 ,别再换打包工具了?
前端·javascript·程序员
用户新3 小时前
V8引擎 精品漫游指南--Ignition篇(下 二) JavaScript 栈帧详解
前端·javascript
账号已注销free3 小时前
box-shadow完整用法
前端