4.9 带宽优化
带宽优化的目的是减少CPU与GPU之间的数据传输。
4.9.1 LOD(Level Of Detail)
LOD即细节层次,根据物体在画面的大小选用不同级别的资源,以减少渲染和带宽的消耗。LOD在图形渲染中应用广泛,适用的对象有模型LOD,地表LOD,材质LOD,植被/树LOD,灯光LOD,纹理LOD(MipMaps)等等。下图所示的是物体离相机越来越远,采用不同LOD的物体,其中LOD0精度最高,LOD2精度最低。
Unity引擎是通过LODGroup组件实现模型LOD的。(下图)
4.9.2 GPU Instance
GPU Instance技术应用于绘制相同Mesh的多个实例,每个实例都可以有独自的参数(如Color/Position/Scale等)。这种技术可以减少带宽,只需传入一份Mesh数据,就可以绘制任意多个实例。常用于绘制建筑,地表装饰物,粒子,草,树,植被等等。
上图所示的场景共有1900多个小球,但Batch数只有24,这就是开启了GPU Instance的效果。但它对平台有一定要求:
4.9.3 GPU Skin
CPU Skin最基本的角色动画实现方式,它可以方便地实现很复杂的动画操作,如融合/渐隐/组合/串接等等。但它的缺点也显而易见,占用大量CPU计算性能,难以并行计算,每帧需传送模型顶点数据到GPU,增加带宽负载。
GPU Skin的做法是将骨骼矩阵列表作为Uniform传入Shader,然后在Vertex Shader中对模型顶点进行蒙皮计算。它可以并行计算,减轻CPU负载,此外,由于每帧传入GPU的数据是骨骼矩阵,不是顶点数据,极大降低了带宽负载。
当然,GPU Skin也有缺陷。它会提高GPU负载,最高骨骼数往往受限于平台(如OpenGL ES 2.0不能超过250个Vector4数据量),而且也不利于做复杂的动画操作。Unity引擎可以在PlayerSettings面板开启GPU skin(下图)。
此外,GPU Skin还可以结合GPU Instance技术,以渲染大量相同角色的骨骼动画。详见这里。
4.9.4 GPU粒子
GPU粒子的优缺点和GPU Skin类似,支持粒子的并行运算,减少带宽负载,但它同样难以实现粒子的高级特性(软粒子/碰撞等)。Unity对模型粒子做了特殊优化,支持GPU Instancing(下图)。
4.9.5 正确使用Buffer标记
OpenGL的Buffer标记有以下几种:
GL_STREAM_DRAW
GL_STREAM_READ
GL_STREAM_COPYGL_STATIC_DRAW
GL_STATIC_READ
GL_STATIC_COPYGL_DYNAMIC_DRAW
GL_DYNAMIC_READ
GL_DYNAMIC_COPY
1. DRAW:Buffer数据将会被送往GPU进行绘制。
2. READ:Buffer数据会被CPU应用程序读取。
3. COPY:Buffer数据会被用于绘制和读取。
4. STATIC:一次修改,多次使用。可用于静态模型顶点数据。
5. DYNAMIC:多次修改,多次使用。可用于带动画的模型顶点数据,粒子系统的数据。
6. STREAM:多次修改,一次使用。可用于特殊场合,比如编辑器数据。
Buffer的标记各有用途,所以选择合适的类型可以减少带宽负载和显存占用。