CesiumJS PrimitiveAPI 高级着色入门-参数化几何

CesiumJS 是一个非常强大的开源 JavaScript 库,用于在 web 浏览器中创建 3D 地球仪和 2D 地图。它提供了丰富的API,允许开发者构建复杂的地理空间可视化应用。在 CesiumJS 中,PrimitiveAPI 允许你以较低级别的方式渲染几何体,如点、线和多边形等,这为自定义着色和渲染效果提供了可能。

CesiumJS PrimitiveAPI 高级着色入门-参数化几何

Primitive API 还包括 Appearance APIGeometry 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 比较特殊外,其它的几何对象都有其对应的边线几何对象(边线不是三角网格)
  • CoplanarPolygonGeometryPolygonGeometry 两个 API 很像,但是前者是 2018 年 1.48 后来添加的 API,适用于顶点共面的多边形;不共面的顶点在 PolygonGeometry 中可能会引起崩溃,但在这个共面多边形 API 不会(尽管可能会产生一些不可预测的三角形)。在 PolygonGeometry 出现三角形显示不正常、不完整的情况,可考虑用这个共面多边形 API;也支持挖洞。

可见 CesiumJS 对参数几何的支持是比较丰富的。

举例

以下即两个椭球体的实例绘制示例代码:

代码就不详细解释了,需要有一定的 WebGL 基础,否则对 vertexFormatattributes 等字段会有些陌生。

如下图所示:

纯手搓几何

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 高级着色入门-外观材质

CesiumJS PrimitiveAPI 高级着色入门-使用 GLSL 着色器

CesiumJS PrimitiveAPI 高级着色入门-底层知识

NSDT场景编辑器 | NSDT 数字孪生 | GLTF在线编辑器 | 3D模型在线转换 | UnrealSynth虚幻合成数据生成器 | 3D模型自动纹理化工具
2023 power by nsdt©鄂ICP备2023000829号