上篇《WebGL-实例化绘制》我们学习了实例化webgl底层实现原理,基于webgl1.0标准的扩展。这篇博客我们来了解下cesium引擎是如何支持实例化功能的。该篇公众号主要参考了博客:《Cesium原理篇:6 Render模块(6: Instance实例化)》。
假如有这样的需求:有四个不同颜色的点,它们的相对位置(模型坐标)固定,现在要求在不同地面(世界坐标)绘制这四个点。例如下图中的在10个不同位置各绘制出四个点:图略。
四个点相对位置:图略。
在cesium引擎中如何实现呢?
方式一: 通过entity接口逐个点绘制由于cesium封装的entity接口没有现成的这样的几何形状的接口,我们只能逐个点计算出世界坐标再绘制。或者可以自己封装一个这样几何形状的entity接口。
方式二: 自定义实现一个一次绘制四个点primitive接口,然后调用10次大部分人可能考虑到entity接口的效率低,自定义primitive接口来实现一次绘制这样的四个点。这样的话如果绘制更多次的话(10W+)绘制效率可能仍然满足不了。
方式三: 自定义primitive接口,在一个drawcommand命令下绘制所需所有点可能有人更近一步,何不在一个drawcommand命令下绘制所有点呢?这样做当然效率最高,如果没有实例化这个功能,这也是目前最高效最方便的方式。但是有了实例化功能我们大可不必这样,因为这需要计算每个点世界坐标(坐标转换)。再者,如果图形稍微复杂则需要构建索引,那么计算整体顶点的索引也是一个棘手的工作。
方式四:实例化。
可以看到,cesium底层对实例化做了很好的封装,而且考虑到了webgl版本兼容性。
接下来我们用cesium引擎以实例化的方式实现上述例子,至于VBO、VAO、ShaderProgram、uniformMap、DrawCommand等cesium接口这里不详细叙述,因为每个都是cesium的要点,需要精力去熟悉。