Cesium: Primitive vs Entity
Primitive vs Entity
Entity
Cesium Sandcastle: Variety of available entities
更高级别的数据驱动 API,它使用一致性设计的、高级别对象来管理一组相关性的可视化对象,其底层也是使用的 primitive
。
多个类型的实体可以结合使用(如 billboard + label),但同一种实体不能存在多个(如多个 billboard 只能分别创建 entity 实例)。
⚠️ 当在场景中实例化并加载上万个 entity 时,加载速率和性能往往没有有效组织 primitive 来的高。
// i.e. 加载图标
viewer.entities.add({position: position,billboard: {image: "./static/blueCamera.png",verticalOrigin: Cesium.VerticalOrigin.BOTTOM,},
});
Cesium 支持的 Entity
实体类型 | 说明 |
---|---|
BillboardGraphics | 点,广告牌,图片标注 |
LabelGraphics | 点,文字标注 |
PointGraphics | 点,或者填充颜色的圆 |
CorridorGraphics | 走廊:沿着地表的多段线(垂直于表面的折线),且具有一定的宽度,可以拉伸到一定的高度 |
CylinderGraphics | 圆柱、圆锥或者截断的圆锥 |
EllipseGraphics | 椭圆或者拉伸的椭圆 |
EllipsoidGraphics | 椭球体 |
RectangleGraphics | 矩形或者正柱体 |
PlaneGraphics | 平面 |
PolygonGraphics | 多边形,可以具有空洞或者拉伸一定的高度 |
PathGraphics | 多段线,以路径方式呈现,可随时间移动 |
PolylineGraphics | 多段线,可以具有一定的宽度 |
PolylineVolumeGraphics | 多段线柱体 |
BoxGraphics | 立方体 |
WallGraphics | 墙 |
ModelGraphics | gltf 3d 模型 |
Cesium3DTilesetGraphics | 3d tiles tileset |
Primitive
Cesium Sandcastle: Variety of available primitives
主要由两部分组成:Geometry
(几何结构) 和 Appearance
(GLSL 顶点着色器、片段着色器和渲染状态)
面向图形开发人员的底层 API,暴露最小限度的抽象,更多使用图形学术语,具有更大的灵活性。
图元(Primitive)代表场景中的几何体。 几何可以来自单个
GeometryInstance
,也可以来自实例数组,即 geometry 来自不同的几何类型。图元将 geometry 实例与描述完整着色的 appearance 相结合,包括 Material 和 RenderState。
粗略地说,geometry 实例定义了结构和位置,appearance 定义了视觉特征。 解耦 geometry 和 appearance,允许我们混合和匹配它们中的大部分,并相互独立地添加新的 geometry 或 appearance 。
将多个实例组合成一个原语称为批处理,可显着提高静态数据的性能。 实例可以单独挑选,Scene#pick
返回它们的GeometryInstance#id
。使用PerInstanceColorAppearance
设定实例的外观,每个实例可以具有唯一的颜色。
Geometry
可以在 web worker 或主线程上创建和批处理。
其具有以下优势:
- 性能:绘制大量 Primitive 时,可以将其合并为单个
Geometry
,减轻 CPU 负担,更好使用 GPU。 - 灵活:
Geometry
和Appearance
解耦,两者可独立修改。
同样的,使用 primitive
就意味着需要编写更多代码,以及对图形学深入的了解。
var instance = new Cesium.GeometryInstance({geometry : new Cesium.EllipseGeometry({center : Cesium.Cartesian3.fromDegrees(-100.0, 20.0),semiMinorAxis : 500000.0,semiMajorAxis : 1000000.0,rotation : Cesium.Math.PI_OVER_FOUR,vertexFormat : Cesium.VertexFormat.POSITION_AND_ST}),id : 'object returned when this instance is picked and to get/set per-instance attributes'
});scene.primitives.add(new Cesium.Primitive({geometryInstances : instance,appearance : new Cesium.EllipsoidSurfaceAppearance({material : Cesium.Material.fromType('Checkerboard')})
}));
内置几何集合(collection)
⚠️ 为方便使用,cesium 内部提供了一部分常用的可渲染集合对象,在无法满足的情况下再考虑自定义构造
// i.e. 加载多个图标
this.billboards = viewer.scene.primitives.add(new Cesium.BillboardCollection()
);for(let i = 0; i < 10000; i++) {this.billboards.add({position: position,image: require("./images/blueCamera.png"),verticalOrigin: Cesium.VerticalOrigin.BOTTOM,});
}
Cesium 内部提供的可渲染图形集合
图形集合 | 说明 |
---|---|
BillboardCollection | 图标。为了获得最佳性能,最好选择几个系列,每个系列都有许多图形,而不是许多系列,每个系列只有零星的图形。组织图形,使具有相同更新频率的图形位于同一集合中,如不更改的图形应位于一个集合中,每一帧都变化的图形应该在另一个集合中。 |
LabelCollection | 文字。为了获得最佳性能,参考 BillboardCollection |
PointPrimitiveCollection | 点。为了获得最佳性能,参考 BillboardCollection |
PolylineCollection | 多段线。为了获得最佳性能,参考 BillboardCollection |
CloudCollection | 云特效 |
Geometry - 几何体
Cesium 支持的 Geometry
几何图形 | 轮廓几何图形 | 类别 | 说明 |
---|---|---|---|
BoxGeometry | BoxOutlineGeometry | 立方体 | 立方体 |
CircleGeometry | CircleOutlineGeometry | 圆形 | 圆形或者拉伸的圆形,圆圈或挤压圆 |
CorridorGeometry | CorridorOutlineGeometry | 走廊 | 走廊:沿着地表的多段线(垂直于表面的折线),且具有一定的宽度,可以拉伸到一定的高度 |
CylinderGeometry | CylinderOutlineGeometry | 圆柱、圆锥 | 圆柱、圆锥或者截断的圆锥 |
EllipseGeometry | EllipseOutlineGeometry | 椭圆 | 椭圆或者拉伸的椭圆 |
EllipsoidGeometry | EllipsoidOutlineGeometry | 椭球体 | 椭球体 |
RectangleGeometry | RectangleOutlineGeometry | 矩形 | 矩形或者拉伸的矩形 |
PolygonGeometry | PolygonOutlineGeometry | 多边形 | 多边形,可以具有空洞或者拉伸一定的高度 |
PolylineGeometry | SimplePolylineGeometry | 多段线 | 多段线,可以具有一定的宽度 |
PolylineVolumeGeometry | PolylineVolumeOutlineGeometry | 多段线柱体 | 多段线柱体 |
SphereGeometry | SphereOutlineGeometry | 球体 | 球体 |
WallGeometry | WallOutlineGeometry | 墙 | 墙 |
Geometry Instances - 几何体实例
相当于 Geometry 的容器,而多个 Instance 可以公用一个 Geomotry 并利用 GeometryInstance.modelMatrix
提供多种属性信息。
var geometry = Cesium.BoxGeometry.fromDimensions({vertexFormat: Cesium.VertexFormat.POSITION_AND_NORMAL,dimensions: new Cesium.Cartesian3(1000000.0, 1000000.0, 500000.0)
});var instanceBottom = new Cesium.GeometryInstance({geometry: geometry,modelMatrix: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)},id : 'bottom'
});var instanceTop = new Cesium.GeometryInstance({geometry: geometry,modelMatrix: Cesium.Matrix4.multiplyByTranslation(Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 3000000.0), new Cesium.Matrix4()),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA)},id : 'top'
});
Combing Geometries - 合并几何图形✨
我们可以合并多个 Instance 为一个 Primitive,提高我们的性能。
⚠️ 但是不同类别的几何图形不能放一起!如 Outline 为一类 geometryInstances,非轮廓的为另一类
// 填充面几何实例
var instances = [Instance1, Instance2, Instance3, ……];
scene.primitives.add(new Cesium.Primitive({geometryInstances: instances, //合并// 某些外观允许每个几何图形实例分别指定某个属性,例如:appearance: new Cesium.PerInstanceColorAppearance({translucent: false, closed: true})
}));// 轮廓几何实例
var outlineInstances = [OutlineInstance1, OutlineInstance2, OutlineInstance3, ……];
scene.primitives.add(new Cesium.Primitive({geometryInstances: outlineInstances, //合并// 某些外观允许每个几何图形实例分别指定某个属性,例如:appearance: new Cesium.PerInstanceColorAppearance({translucent: false, closed: true})
}));
更新单个 Instance 属性
在添加到 Primitive 后,我们仍然可以通过 Id 获取指定 Instance 并修改其属性。
var circleInstance = new Cesium.GeometryInstance({geometry: new Cesium.CircleGeometry({center: Cesium.Cartesian3.fromDegrees(-95.0, 43.0),radius: 250000.0,vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT}),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color( 1.0, 0.0, 0.0, 0.5 )),show: new Cesium.ShowGeometryInstanceAttribute(true) //显示或者隐藏},id: 'circle'
});var primitive = new Cesium.Primitive({geometryInstances: circleInstance,appearance: new Cesium.PerInstanceColorAppearance({translucent: false,closed: true})
});
scene.primitives.add(primitive);var attributes = primitive.getGeometryInstanceAttributes('circle'); //获取某个实例的属性集
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha: 1.0
}));
Appearance - 外观
⚠️ 注意:有些外观和几何是不兼容的。 例如 EllipsoidSurfaceAppearance
与 WallGeometry
就不能搭配,原因是后者是垂直于地表的。即使外观与几何图形兼容,它们还必须有匹配的顶点格式(vertex formats)—— 即几何图形必须具有外观可以作为输入的数据格式,在创建 Geometry
时可以提供 VertexFormat
。
Cesium 支持的 Appearance
外观 | 描述 |
---|---|
MaterialAppearance | 支持各种 Geometry 类型的外观,支持使用材质来定义着色。支持材料描述阴影。 |
EllipsoidSurfaceAppearance | MaterialAppearance 的一个版本。假设几何图形与地表是平行的,并且依此来进行顶点属性(vertex attributes)的计算。和 Material Appearance 一样,就像一个多边形,并且使用这个假设来通过程序上计算许多顶点属性来节省内存。 |
PerInstanceColorAppearance | 让每个实例使用自定义的颜色来着色,使用每个实例的颜色来遮蔽每个实例。 |
PolylineMaterialAppearance | 支持使用材质来着色多段线。支持材料遮蔽 Polyline。 |
PolylineColorAppearance | 使用每顶点或者每片段(per-vertex or per-segment )的颜色来着色多段线—使用每顶点或每段着色来遮蔽折线 |
Appearance 定义了需要在 GPU上 执行的 GLSL 着色器,这部分一般只有在自定义外观时需要修改。
render state
用来在绘制 Primitive 的时候控制 GPU 状态,一旦外观被创建,render state
就不能再改变了,但是我们可以修改其材质。
//下面的外观可用于定义一个 Viewer 可进入的透视盒子
var appearance = new Cesium.PerInstanceColorAppearance({translucent: true,closed: true
});//下面的代码效果同上
var appearance1 = new Cesium.PerInstanceColorAppearance({renderState: {depthTest: {enabled: true},cull: {enabled: true,face: Cesium.CullFace.BACK}}
});
自定义着色器(示例:雷达动效)
/** 1. 数据准备 */
// 雷达的高度
var length = 400000.0;
// 地面位置(垂直地面)var positionOnEllipsoid = Cesium.Cartesian3.fromDegrees(116.39, 39.9);
// 中心位置
var centerOnEllipsoid = Cesium.Cartesian3.fromDegrees(116.39, 39.9, length*0.5);
// 顶部位置(卫星位置)
var topOnEllipsoid = Cesium.Cartesian3.fromDegrees(116.39, 39.9,length);
// 矩阵计算
var modelMatrix = Cesium.Matrix4.multiplyByTranslation( // 转换矩阵Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid), // 矩阵new Cesium.Cartesian3(0.0, 0.0, length * 0.5), // 要转换的笛卡尔坐标new Cesium.Matrix4() // 返回新的矩阵);/** 2. Geometry: 创建一个圆锥几何图形 */
//1. 构造 geometry
var cylinderGeometry = new Cesium.CylinderGeometry({length: length,topRadius: 0.0,bottomRadius: length * 0.5,vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat
});
//2. 创建 GeometryInstance
var redCone = new Cesium.GeometryInstance({geometry: cylinderGeometry, //geomtry类型modelMatrix: modelMatrix, //模型矩阵 调整矩阵的位置和方向
});**/** 3. shader着色器: 定义glsl代码 */**
const source =
//传入的动态数值
`uniform vec4 color;uniform float repeat;uniform float offset;uniform float thickness;//设置图形外观材质
czm_material czm_getMaterial(czm_materialInput materialInput){czm_material material = czm_getDefaultMaterial(materialInput); //获取内置的默认材质float sp = 1.0/repeat; //重复贴图vec2 st = materialInput.st; //二维纹理坐标float dis = distance(st, vec2(0.5)); //计算距离float m = mod(dis + offset, sp); //间隔float a = step(sp*(1.0-thickness), m);//线条拼色//修改材质material.diffuse = color.rgb;material.alpha = a * color.a;return material;
}`/** 4. appearance */
//1. 自定义material外观材质,修改着色器
const material = new Cesium.Material({fabric: {type: 'VtxfShader1',uniforms: { //动态传递参数color: new Cesium.Color(0.2, 1.0, 0.0, 1.0),repeat: 30.0,offset: 0.0,thickness: 0.3,},source :source},translucent: false
})
//2. 定义appearance外观
const appearance = new Cesium.MaterialAppearance({material:material, // 自定义的材质faceForward : false, // 当绘制的三角面片法向不能朝向视点时,自动翻转法向,从而避免法向计算后发黑等问题closed: true // 是否为封闭体,实际上执行的是是否进行背面裁剪
})/** 5. 创建 Primitive */
//1. 添加 Primitive
var radar = viewer.scene.primitives.add(new Cesium.Primitive({geometryInstances: [redCone],appearance:appearance})
);
//2. 动态修改雷达材质中的 offset 变量,从而实现动态效果。
viewer.scene.preUpdate.addEventListener(function() {let { offset } = radar.appearance.material.uniforms;offset -= 0.001;if (offset > 1.0) {offset = 0.0;}radar.appearance.material.uniforms.offset = offset;
})
参考资料
Cesium | Primitive图元介绍及与Entity对比 - 掘金
Cesium | 海量点的加载与性能优化 - 掘金
Part I: Custom Geometry & Appearances – Cesium
Part II: Geometry and Appearances · CesiumGS/cesium Wiki
Cesium原理篇:Material - fu*k - 博客园
cesium| Primitive图元自定义着色器(1) | 一只咸鱼 | 努力学习最新姿势!!!
Cesium: Primitive vs Entity相关推荐
- cesium学习 之 Entity 画卫星轨道 (一)
cesium学习 之 Entity 画卫星轨道 (一) 最近公司想做个卫星轨迹展示大屏,原型图看上去确实比较逼真,然后我就惨了,开始学习cesium,满满的English文档,看着头大. B站上面有入 ...
- cesium primitive 绘制
primitive 绘制多边形 const viewer = new Cesium.Viewer("cesiumContainer"); const scene = ...
- Cesium Primitive API 实践:绘制一个三角形
与调用官方各种参数化 API 不同,本例直接使用 Geometry 和 Appearance 类进行构造图形,灵活度较大. 文章目录 1 目的与结果 2 实现原理 坐标系统选择 3 踩坑点 3.1 G ...
- Cesium中Primitive与Entity详细介绍
文章目录 1.概述 2.Primitive 2.1Geometry 2.2Appearance 2.3优势与不足 3.Entity Cesium实战系列文章总目录: 传送门 1.概述 Cesium为开 ...
- Cesium 删除primitive和entity
Primiitive的删除,同样用于PrimitiveCollection. let react = scene.primitives.add(new Cesium.RectanglePrimitiv ...
- Cesium Primitive实现风险四色图
一般情况下,点线面用entity去实现显得更加容易,但是当数据量比较大的时候,其页面性能真的让人不敢恭维,被甲方大大看到,大概率会被拉出去阉割了... 所以今天我们使用Cesium底层api,Prim ...
- cesium加载entity图片缩放_Cesium中级教程4 – 空间数据可视化(二)
Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ Viewer中的Entity功能 让我们看看Viewer为操作e ...
- cesium 隐藏entity_cesium entity创建各类实体
html> 创建实体 @import url(../Build/Cesium/Widgets/widgets.css); html, body, #cesiumContainer { width ...
- cesium primitive添加模型
let addModel = true; var model = null const viewer = new Cesium.Viewer("cesiumContainer", ...
最新文章
- 太赞了,Intellij IDEA 竟然把 Java8 的数据流问题这么完美的解决掉了!
- GIS-009-Cesium 使用
- 接口测试用例设计思路
- iOS经典面试题之深入分析block相关高频面试题
- Silverlight 2 Beta 1版本缺陷列表
- React 第十二章 React思想
- C语言库文件ctype.h中重要的库函数
- c++判断奇偶_第十一届(今年)蓝桥杯省模拟赛 试题+源码 C/C++详解
- centos查找未挂载磁盘格式化并挂载
- 【Caffe代码解析】SyncedMemory
- wget下载文件命令
- 创龙基于Xilinx Kintex-7系列高性价比FPGA开发板SMA端子、电源接口和拔码开关
- 用VS2019编译librdkafka库
- mysql8初始化 2021-12-18版本 设置mysql大写
- Google earth 生成研究区适量边界(研究区边界从哪来?)
- 两片8-3优先编码器转化为16-4线优先编码器真值表--python实现
- 二进制里的「逢二进一」是什么意思
- 【每天读一点英文】叶芝诗歌《当你老了》赏析——特别喜欢的一首诗,水木年华《一生有你》歌词来源
- 王微:愤怒,是我创业初始的驱动力
- Gerrit使用教程
热门文章
- MySQL中查询两个日期之间的天数
- 通用串行总线USB接口——基础总结(USB版本演进、接口类型、电气特性、拓扑结构、USB硬件接口实现)
- DRF 中Request对象中获得数据
- cad 怎么取消绘图界限?cad怎么调整图形界限
- 线卡(line card)
- Css background背景语法
- 哼啊啊啊啊啊啊啊啊啊
- 超级计算机 26010,[转载]太湖之光和神威26010有多牛
- 华为OD机试题 - RSA 加密算法(JavaScript)| 机考必刷
- 王者显示重连服务器失败,最强王者三国手游服务器连接失败 最强王者三国手游曹操学什么技能_游戏频道_中华网...