之前的最长的一帧系列,我们主要集中在地形和影像服务方面。简单说,之前我们都集中在地球是怎么造出来的,从这一系列开始,我们的目光从GLOBE上解放出来,看看球面上的地物是如何渲染的。本篇也是先开一个头,讲一下涉及到的类结构和整体的流程,有一个系统的,概括的理解。
我们先看看Cesium的渲染队列:
var Pass = { // 环境,比如大气层,月亮,天空盒等 ENVIRONMENT : 0, //之前介绍的ComputeEngine,比如影像服务里面的投影涉及的计算 COMPUTE : 1, // 地球切片 GLOBE : 2, // 贴地的Geometry GROUND : 3, // 不透明的Geometry OPAQUE : 4, // (半)透明的Geometry TRANSLUCENT : 5, OVERLAY : 6, NUMBER_OF_PASSES : 7 };
如上是Cesium的渲染队列,也是Cesium渲染的优先级,非常的清晰。就像画家作画一样,我们先渲染地球,这样就有了一个落脚地(同时也有了深度纹理和模版缓冲区等),然后再画贴地的地物,然后是那些不贴地的且不透明的地物,接着是哪些透明度的地物,这时之前渲染地物的颜色和深度缓冲区,可以方便的进行深度计算和颜色的叠加,最上面的则是Overlay,比如一些公告板。这样一层层的渲染,建立起整个场景的层次感和立体感。
Geometry的难点在于种类繁多,材质类型也不少,技术上如何高效的渲染,根据是否贴地,是否透明等属性来设定渲染的优先级,根据材质和Geometry的类型来打组和实例化。同时Geometry的Type也是多样的,如何调度,并且将参数化的Geometry高效的分解为VBO三角面片,里面的水确实很深。万事开头难,我们先从简单的说起。
var entities = viewer.entities; entities.add({ rectangle : { coordinates : Cesium.Rectangle.fromDegrees(-92.0, 20.0, -86.0, 27.0), outline : true, outlineColor : Cesium.Color.WHITE, outlineWidth : 4, stRotation : Cesium.Math.toRadians(45), } });
这是Cesium提供的添加Geometry的示例代码。So easy,不是吗。Viewer中提供了entities,是一个EntityCollection类,用户创建的不同类型的Geometry,都可以通过add方法添加,其他的就交给Cesium,最终实现屏幕渲染。顺藤摸瓜,我们先列举出相关的类,以及它们之间关系草图:
Viewer
DataSourceDisplay
DataSourceCollection
CustomDataSource
EntityCollection
Entity
先不关注具体的细节,不难理解,当我们调用EntityCollection.add方法时,根据参数会new一个Entity对象,此时EntityCollection充当了一个容器的作用。接着,Cesium内部通过事件的机制,在DataSourceDisplay中根据Entity类型安排具体模块,最终该模块完成对应Entity的解析工作。这里你就会发现,在这个通讯过程中,EntityCollection和DataSourceDisplay是直接进行消息传递的,直接绕开了CustomDataSource,那DataSource模块又有什么鸟用,岂不是站着坑不干活。下面通过一个例子让大家有一个形象了解。
首先,作为一名热爱编码的程序员而言,是否曾经仰天长叹,为什么那个谁谁谁天天不干活,工资还比我高,我不明白。想想自家公司那些占坑不干活的人都是什么角色——管理人员。CustomDataSource并没有参与实际的工作中,当状态变化时,维护一下EntityCollection和DataSourceDisplay两者的关联,保证他们之间消息的畅通。比如初始化时,CustomDataSource把EntityCollection带到DataSourceDisplay处,抛下一句话,以后有什么事情就找他,多多联系,然后立马就闪人了。这时,一脸懵逼的EntityCollection说,我得赶紧接客户去了,要不留个联系方式,有什么事情我好通知你。DataSourceDisplay也是管理层,自然不肯交出手机号,立马找到助理(Visualizer),抛下一句话“以后你俩直接联系”。这样,EntityCollection和Visualizer的通讯渠道就建立起来了。Visualizer我们后面会介绍,这里略过。
DataSourceCollection的作用也大致如此,但不同于CustomDataSource主要是接散户,消极怠慢。DataSourceC