移动设备 WebGL 优化

移动设备的GPU性能限制主要体现在两个方面:着色器计算和带宽,所以移动设备的 webgl 优化也主要围绕这两个方面进行。

减少带宽使用

关于带宽的问题,我的理解是,为了让设备发挥最大性能,肯定是需要处理器满载的,满载需要有源源不断的数据从存储运进去,同时把结果运回存储,如果你的处理器很强,但是带宽不够,那就无法发挥性能,或者说如果你的程序需要大量的访问数据,那么在带宽上就很容易形成瓶颈。带宽的瓶颈在桌面平台还好,移动设备就非常明显。距离来说带宽最大的,是独立显卡,独立的显存和图形处理器之间的数据交换可以达到几百GB每秒,然后是核显,会弱一些,最弱的是移动设备,显示数据是共享设备的内存的,高带宽的使用甚至会影响整个soc的性能表现。

在webgl应用中可以通过不同方法减少带宽使用。

1 在webgl canvas合成期间保证没有额外的副本和操作存在,context的获取设置中。preserveDrawingBuffer总是false。alpha不需要就不开。

2 尽可能减少材质和帧缓存的分辨率。如果材质都是一些低频的内容,降低分辨率并不会在视觉上造成显著影响。现在移动设备,屏幕分辨率都非常高,小小的手机屏幕的像素数量甚至超过桌面屏幕, 所以牺牲显示效果,减少帧缓存的分辨率也能起到作用。

3尽可能的减少后处理的步骤,最好压缩成一个,最好没有后处理。

关于 preserveDrawingBuffer:webgl 的canvas使用双缓冲区进行工作,preserveDrawingBuffer 默认是关的,就是正常的双缓冲工作模式: 一个用来显示,一个用来绘制,下一帧这两个buffer会交换,显示上一帧绘制的,画上一帧用来显示的。如果 preserveDrawingBuffer 设置为 true,那么就不会发生交换,而是把上一帧绘制的buffer,复制到显示的buffer一遍,在带宽上具有很大开销。 preserveDrawingBuffer也并不是没用的东西,比如如果需要读取像素,或者复用绘制到主屏幕上的图像,比如实现脏矩形渲染优化,那么就非开不可。

优化着色器执行

通过将shader替换成最简单的shader,可以立刻确认webgl应用的性能瓶颈是否在shader执行上。具体的shader优化是一门大学问,这里只提几个通用的点。关于着色器优化我想我会在其他文中集中总结。

1.退而求其次,使用简单的着色和光照模型。这一点就不多说了,就是牺牲效果换取性能。

2.在 CPU 端对drawcall进行深度排序,缓解 overdraw。 但是要注意的是,这可能将渲染的瓶颈转移到CPU端,除了排序本身的成本,另外主要是不恰当的排序会导致gl状态不必要的切换。drawcall 排序也是一门学问,关于drawcall排序的内容应该也需要单独总结。

3.降低shader精度,但是有没有效果,完全取决于具体硬件。