CesiumJS PrimitiveAPI 高级着色入门-参数化几何
CesiumJS 是一个非常强大的开源 JavaScript 库,用于在 web 浏览器中创建 3D 地球仪和 2D 地图。它提供了丰富的API,允许开发者构建复杂的地理空间可视化应用。在 CesiumJS 中,PrimitiveAPI 允许你以较低级别的方式渲染几何体,如点、线和多边形等,这为自定义着色和渲染效果提供了可能。
Primitive API
还包括 Appearance API
、Geometry API
两个主要部分,是 CesiumJS 挡在原生 WebGL 接口之前的最底层图形封装接口(公开的),不公开的最底层接口是 DrawCommand
为主的 Renderer API
,DC 对实时渲染管线的技术要求略高,可定制性也高,这篇还是以 Primitive API
为侧重点。
3D模型在线预览提供多种低代码平台3D模型在线预览解决方案,实现了将多种3D模型格式无缝集成到低代码业务表单中。这意味着用户可以在不离开低代码平台的情况下,直接查看和操作3D模型,极大地提升了数据可视化的效果和用户交互体验。
基础
坐标系基础
这里的“坐标系”特指 WebGL 图形渲染的坐标系。Primitive API
收到的几何数据,默认没有任何坐标系(即最基本的空间直角坐标),想要移动到地表感兴趣的地方,需要借助 ENU 转换矩阵,或者把几何顶点的坐标直接设为 EPSG:4978
坐标(即所谓通俗的“世界坐标”)。
ENU 转换矩阵,用道家八卦的说法类似“定中宫”。它能将坐标转换到这样一个 ENU 地表局部坐标系上:
- 指定一处地表点(经纬度)为坐标原点
- 以贴地正东方(ENU 中的 E)为正 X 轴
- 以贴地正北方(ENU 中的 N)为正 Y 轴
- 以地心到坐标原点的方向(即 ENU 中的 U,up)为正 Z 轴
这样一个 ENU 坐标系上的局部坐标左乘 ENU 转换矩阵后,就能得到标准的 EPSG:4978
世界坐标。
GIS 中的投影坐标、经纬坐标不太适用,需要转换。
合并批次
虽然 WebGL 支持实例绘制技术,但是 Primitive API
减少绘制调用并不是通过这个思路来的,而是尽可能地把 Vertex 数据合并,这个叫做 Batch
,也就是“合并批次(并批)”。
在 CesiumJS 的 API 文档中能看到 new Primitive()
时,可以传递一个 GeometryInstance
或者 GeometryInstance
数组,而 GeometryInstance
对象又能复用具体的某个Geometry
对象,仅在几何的变换位置(通过矩阵表达)、顶点属性(Vertex Attribute)上做差异化。
CesiumJS 会在 WebWorker 中异步地拼装这些几何数据,尽可能一次性发送给底层的 Renderer,以达到尽可能少的 DC。
参数化几何
几何类清单
CesiumJS 内置的参数几何有如下数种:
- 立方体(盒) -
BoxGeometry
&BoxOutlineGeometry
- 矩形 -
RectangleGeometry
&RectangleOutlineGeometry
- 圆形 -
CircleGeometry
&CircleOutlineGeometry
- 线的缓冲区(可设定转角类型和挤出高度) -
CorridorGeometry
&CorridorOutlineGeometry
- 圆柱、圆台、圆锥 -
CylinderGeometry
&CylinderOutlineGeometry
- 椭圆、椭圆柱 -
EllipseGeometry
&EllipseOutlineGeometry
- 椭球面 -
EllipsoidGeometry
&EllipsoidOutlineGeometry
- 多边形(可挤出高度) -
PolygonGeometry
&PolygonOutlineGeometry
- 多段线 -
PolylineGeometry
&SimplePolylineGeometry
- 多段线等径柱体 -
PolylineVolumeGeometry
&PolylineVolumeOutlineGeometry
- 球面 -
SphereGeometry
&SphereOutlineGeometry
- 墙体 -
WallGeometry
&WallOutlineGeometry
- 四棱台(视锥截头体) -
FrustumGeometry
&FrustumOutlineGeometry
- 平面 -
PlaneGeometry
&PlaneOutlineGeometry
- 共面多边形 -
CoplanarPolygonGeometry
&CoplanarPolygonOutlineGeometry
- Esri I3S 专用的几何 -
I3SGeometry
这里有两个特别说明:
- 除了 I3SGeometry 比较特殊外,其它的几何对象都有其对应的边线几何对象(边线不是三角网格)
CoplanarPolygonGeometry
和PolygonGeometry
两个 API 很像,但是前者是 2018 年 1.48 后来添加的 API,适用于顶点共面的多边形;不共面的顶点在PolygonGeometry
中可能会引起崩溃,但在这个共面多边形 API 不会(尽管可能会产生一些不可预测的三角形)。在PolygonGeometry
出现三角形显示不正常、不完整的情况,可考虑用这个共面多边形 API;也支持挖洞。
可见 CesiumJS 对参数几何的支持是比较丰富的。
举例
以下即两个椭球体的实例绘制示例代码:
代码就不详细解释了,需要有一定的 WebGL 基础,否则对 vertexFormat
、attributes
等字段会有些陌生。
如下图所示:
纯手搓几何
CesiumJS 的封装能力和 API 设计能力可谓一绝,它给开发者留下了非常多层级的调用方法。除了 基础部分提到的内置几何体,假如你对 WebGL 的数据格式(VertexBuffer)能熟练应用的话,你可以使用 Geometry + GeometryAttribute
类自己创建几何体对象,查阅 Geometry
的文档,它提供了一个很简单的例子:
然后就可以继续创建 GeometryInstance
,搭配外观、材质对象创建 Primitive 了。
子线程异步生成几何
有部分参数化几何对象经过一系列逻辑运送后,是要在 WebWorker 内三角化、生成顶点缓冲的。
这小节内容比较接近源码解析,不会讲太详细。从 Primitive.prototype.update
方法中模块内函数 loadAsynchronous
看起:
在这个 loadAsynchronous
函数内,会调度一些 TaskProcessor
对象,这些 TaskProcessor 会通过 WebWorker
的消息传递来完成 Geometry 的 Vertex 创建。这个过程很复杂,就不展开了。
如果你感兴趣,打开浏览器的开发者工具,在 “源代码” 选项卡左侧的“页面”中,能看到一堆 “cesiumWorkerBootstrapper” 在运行。每一个,背后都是一个内嵌的 requirejs 在调度额外的异步模块,这些异步模块在默默地为主页面生成数据。
CesiumJS PrimitiveAPI 高级着色入门-索引
CesiumJS PrimitiveAPI 高级着色入门-参数化几何
CesiumJS PrimitiveAPI 高级着色入门-外观材质