【Cesium 历史博客】Cesium 中的图形技术:图形结构

翻译有误请指出,规范性转载。@秋意正寒。
原文出处:https://cesium.com/blog/2015/05/26/graphics-tech-in-cesium-stackhtml

Cesium 和普通的图形引擎没什么区别,可是当对地球上事务抽象的逻辑层愈来愈多后,Cesium 中的类设计就愈来愈针对领域化了:虚拟地球。下面要介绍的是 Cesium 在图形技术栈的设计与普通图形引擎的不一样之处。前端

像以前的文章说的同样,最底层是 Renderer,它是对 WebGL 层的封装,用来处理 WebGL 的资源调配以及绘制命令(Draw Command)的执行。命令(Command)通常是 Draw Call 以及其所须要的状态数据(例如着色器、顶点数据等)。算法

译者注:简而言之,Renderer 处理因数据和状态发生变化致使的 WebGL 绘制命令。缓存

构建于 Renderer 层之上的是 Scene,即场景层。它负责将更高级的对象在场景中的改动分配、重排,最终将这些改变计算成 Renderer 层认识的指令,并交给 Renderer 层进行绘制。网络

最顶层是 Primitives (译名:图元层),构建于 Scene 层和 Renderer 层之上,表明的是真实世界的对象。ide

注意,此处的 Scene 特指 Scene.js 导出的 Scene 类。函数

Primitive 是一个具备自我更新功能的对象,这个函数将绘制命令添加到 Scene 的命令列表中。性能

译者注:在源代码中,命令列表彷佛是 frameState 对象的属性,不过帧状态与 Scene 有很大关系。优化

Globe

Globe 渲染了地球本体:地形、卫星影像和动态水面。动画

在游戏引擎中,这些就是环境因素。Cesium 的 Globe 是没有导航限制的,也就是说地图无限大。大多数游戏引擎是针对局部场景作了大量优化并整个加载进内存中进行运行。

Cesium 使用四叉树来组织层次细节模型。QuadtreePrimitive 在发布时不属于 API 的一部分,因此谨慎修改它。地形瓦片包括了几何图形,特定摄像机视角下的那些地形瓦片会很是逼近地球表面。

在 Cesium 运行的时候,多个影像图层的影像瓦片会映射到地形瓦片上,这样尽管在代码上有一些复杂(例如重投影等计算),换来的是对各类开放地图服务标准的支持。这与游戏引擎有很大的不一样,游戏引擎会对地形和纹理进行组合优化成自定义的格式,可是缺乏了灵活性和数据标准的通用性。

译者注:通用通常化和高性能每每是矛盾的

当 Scene 调用 Globe 的更新功能时,遍历四叉树,并返回关于地形瓦片更新的绘制命令。

每一个绘制命令将影像瓦片的纹理引用过来,并由 Cesium 内部生成着色器。这些着色器基于重叠的影像瓦片的数量、光照、后处理操做、动态水面是否开启等信息而来。

调试模式查看绘制命令的代码以下:

viewer.scene.debugShowCommands = true;

你能够在 Cesium Inspector 这个 widget 中查看绘制命令:

上图左边:使用了12个绘制命令渲染的地球;右边:每一个命令可视化显示

上图左边:使用了186个命令来观察较大范围的 Crater Lake 的视野。右边:从不一样的角度看的结果(显示了瓦片的坐标编号)。

地平线的视角难以优化,这也是3D比2D可贵多的缘由之一。

Model

最复杂的图形应该算是 Model 了,它表明传统三维建模的模型,例如使用 Blender、Maya、3dmax 等的建模成果。在游戏引擎中,这些一般被称做模型,而且针对性地优化,制做特定的格式。

Cesium 使用的格式的 glTF,这是 Khronos 组织的一个标准,一个开放性的 WebGL 标准格式。Cesium 很早就注意到了这个格式,而不是选择自定义格式。

当 Scene 调用 Model 的更新功能时,模型会有针对性地遍历其层次结构,并令其全部新的变换(例如 glTF 的动画、模型的坐标转换、外观变化等)生效。有不少种方法能让这一个操做变得更快,例如快速裁剪技术和仅对目标子树设置动画。

译者注:如下两行文字已通过时,当时 Cesium 使用的 glTF 标准是 1.0,如今 2.0 已经没有这些了。

glTF 文件中能够直接获取着色器,对于拾取操做可使用独立的着色器。glTF 的预约义规范(例如 MODELVIEW)被映射到 uniform 状态,并设置其为自动 uniform,例如 czm_modelView

一个模型可能会在更新时返回一个或几百个命令,这取决于命令的编写方式、模型的材质有多少、动画物体的目标节点有多少。

上图左边:Cesium 奶牛车模型。右边:使用 5 个命令进行渲染(图中能够看到3个,车体亮绿色,两个车轮各一个颜色)

Primitive

Cesium 的通用图元对象 —— Primitive,是 Cesium 有别于游戏引擎的最大特色之一。

游戏引擎一般使用尽量少的图元,例如折线、球体、多边形,它们对调试和抬头显示(Head-Up Displays,HUDs)等极端显示比较有用。游戏引擎更专一环境、效果,例如光照、粒子系统和后处理操做。

在另外一方面,Cesium 是一个大型的几何图形库,它能在地球上绘制常见的对象:折线、多边形、带拉伸成体块的形状等。大多数 Cesium 应用程序使用几何图形来绘制大部分它关注的内容。这就是跟游戏引擎大不同的地方。

Cesium 的独特之处还在于,它的几何细分算法与椭球表面(WGS84椭球体)符合,而不是平面直角坐标系。

例如,多边形的三角化以及加面过程时,会加入椭球体的曲率计算。

这些中间计算使用 Web Worker 执行,从而支持 OGC 网络地图服务标准,和参数化几何形状的建立(而不是预先制做好的几何数据)。

为了最小化绘制命令数量,Cesium 将顶点数据格式相同的几何图造成批地推到单个顶点缓冲中,以便数据共享。

举个例子,(坐标+法线)的顶点数据组合不能和(坐标+法线+uv)合批,可能它们在外观上是同样的,可是它们所须要的顶点着色器、片元着色器是不同的。

经过修改外观的顶点、片元着色器以生成最终的着色器,来支持相对于视角的高精度渲染、几何显示隐藏、单位向量压缩等功能。(这句话不知道讲什么)

几何图形流水线会对顶点属性进行相应的修改,例如法线压缩、高低坐标修改等。

Billboards、Labels、Points

在游戏引擎中,Billboard 一般用于产生粒子效果,例如烟火。Cesium 的 billboard 更通用,它一般用于呈现运动的对象,例以下图所示的卫星和滑翔伞:

1.5w个卫星(SpaceBook应用,由 AGI 提供)

跳伞。

Cesium 的 billboard 比较灵活,例如显示、隐藏功能,像素偏移量、旋转等。这会产生一个结果:顶点数据比较大。因此 Cesium 会压缩顶点属性的个数。

着色器使用 GLSL 预处理器来关闭没必要要的功能,例如若是 billboard 没有旋转,那么顶点着色器将不会进行任何旋转运算。Billboard 的顶点着色器很是复杂,可是它的片元着色器比较简单。这个在 Cesium 中很常见。大多数游戏引擎是反过来的,它们的 billboard 的顶点着色器比较简单,而片元着色器比较复杂。

Billboards 能够是静止的,也能够是动态的,也能够介于两者之间。例如 billboard 的 position 每帧均可能会变化,可是其余的属性则不会改变。为了有效解决这个问题,billboard 基于属性的具体用法,将顶点属性动态地分组到顶点缓存中,例如位置变化了其余顶点属性没变,则只更新顶点坐标。

为了减小绘制命令的数量,运行时将建立的和修改后的 billboard 成批地塞进一个集合中。这与游戏引擎是不一样的,游戏引擎是建立的镜头纹理图集。

文本标签是用 billboard 实现的,每一个字符都是一个 billboard。虽然每一个字符都占内存,可是不会生成额外的绘制命令,由于使用了 “同纹理批处理技术”:

同纹理的批处理技术:有点相似于前端中的雪花图。

有时候 billboard 也能用来绘制点,例如上面说起的卫星图。从 Cesium 1.10 版本开始,绘制点用 Primitive API 可能效率更高。Primitive API 中的点对象不如 billboard 同样有广泛性,它的需求比较低,没有索引数据和纹理数据,因此性能较好。

其余

除了上面的 Primitive 外,还有:

  • ViewportQuad.js 中的 ViewportQuad 类
  • SkyBox、SkyAtmosphere、Sun、Moon
  • Polyline:折线,起初实现起来并不容易(貌似是由于 WebGL 关于线的绘制问题?)

参考

[Bagnell13] Dan Bagnell. Robust Polyline Rendering with WebGL. 2013.

[Bagnell15] Dan Bagnell. Graphics Tech in Cesium - Vertex Compression. 2015.

[Ohlarik08] Deron Ohlarik. Precisions, Precisions. 2008.

[Ring13] Kevin Ring. [Rendering the Whole Wide World on the World Wide Web](https://cesium.com/presentations/Rendering the Whole Wide World on the World Wide Web.pptx). 2013.

相关文章
相关标签/搜索