优化

正如 PC 一样,iOS 和安卓 (Android) 等移动平台也存在各种性能级别的设备。您可以轻松找到一部渲染效果比其他手机好 10 倍的手机。 缩放方法非常简单:

  1. 确保它在基准配置上正常运行
  2. 在高性能配置上使用更多特效:
    • 分辨率
    • 后处理
    • 多重采样抗锯齿
    • 各向异性
    • 着色器
    • 特效/粒子密度,打开/关闭

注重 GPU

图形性能与填充率、分辨率和几何体复杂度(顶点数)息息相关。如果找到方法剔除更多渲染,那么这三个要素的值都会降低。此时,遮挡剔除可起到有效作用。Unity 会自动剔除视锥外的对象。

在移动平台上,基本上会受到填充率的约束(填充率 = 屏幕像素 * 着色器复杂度 * 透支度),着色器过于复杂是导致问题出现的最常见原因。因此,请使用 Unity 自带的移动着色器或自己设计,但要尽可能简单。如果可行,请将代码移动到顶点着色器中,简化像素着色器。

如果降低质量设置 (Quality Settings) 中的纹理质量 (Texture Quality) 后游戏运行速度加快,那么很可能是受内存带宽所限。此时可压缩纹理、使用贴图细化,降低纹理大小等。

LOD(细节等级)使对象更简单,或移向远方后完全消除。主要目的为减少绘制调用的次数。

出色实践

移动 GPU 对于自身产生多少热量、使用的电量以及尺寸大小或噪音大小有严格限制。与台式机部件相比,移动 GPU 的带宽较小、运算器 (ALU) 性能和纹理功率也较低。GPU 的架构也进行了调整,以尽量使用最小带宽和功率。

Unity 针对 OpenGL ES 2.0 进行了优化,使用 GLSL ES(类似于高级着色语言 HLSL)着色语言。内置着色器大多使用高级着色器语言(即 HLSL,也称之为 Cg)编写。针对移动平台,其被交叉编译成 GLSL ES。如果您想要,也可以直接编写 GLSL,但这样会限制您访问 OpenGL 平台(如移动 + Mac),因为目前还没有 GLSL->HLSL 转换工具。在 HLSL 中使用浮点/半浮点/固定 (float/half/fixed) 类型时,它们在 GLSL ES 中会以 highp/mediump/lowp 精度限定符结尾。

以下列出了一些出色实践:

  1. 尽量使材质数目减至最低,便于 Unity 轻松进行批处理。
  2. 使用纹理精灵(大贴图包含多个子贴图),而非许多单个纹理。使加载速度更快,状态转换更少,批处理简单方便。
  3. 如果使用纹理精灵和共享材质,请用 Renderer.sharedMaterial 代替 Renderer.material
  4. 向前渲染像素灯比较耗性能。
    • 尽量使用光照贴图代替实时灯光。
    • 在质量设置中调整像素灯数目。基本上只有方向灯为逐像素,其他都为逐顶点。当然,这取决于游戏本身。
  5. 在质量设置 (Quality Settings) 中尝试调整灯光的渲染模式 (Render Mode of Lights),以获得正确优先级。
  6. 避免使用抠图(透明度测试)着色器,除非真正有必要。
  7. 将透明(alpha 混合)屏幕的覆盖范围保持在最小。
  8. 努力避免多个灯光照亮任何给定对象的情况。
  9. 努力降低着色器通道(阴影、像素灯、反射)的总数目。
  10. 渲染顺序很关键。一般情况下:
    1. 从前往后完全不透明的对象。
    2. 大致从前往后经 alpha 测试的对象。
    3. 天空盒。
    4. alpha 混合对象(若需要,从后往前)。
  11. 在移动平台上进行后处理性能消耗大,请谨慎使用。
  12. 粒子:减少透支,尽量使用最简单的着色器。
  13. 每一帧都要修改的网格使用双缓存:
void Update (){
  // flip between meshes
  bufferMesh = on ? meshA : meshB;
  on = !on;
  bufferMesh.vertices = vertices; // modification to mesh
  meshFilter.sharedMesh = bufferMesh;
}

着色器优化

检查填充率绑定是否容易:如果降低显示分辨率,游戏运行速度是否加快?若是,即受到了填充率的限制。

尝试使用以下方法降低着色器的复杂度:

注重 CPU

游戏受到 GPU 像素处理限制的情况时有发生。导致最终出现 CPU 未充分使用的情况,多核移动 CPU 尤其如此。将 GPU 中的一些工作移出来,放到 CPU 中处理往往是比较明智的做法(Unity 处理所有这些操作):网格蒙皮、小对象的批处理、粒子几何体更新。

慎用,不要盲目地全放到 CPU 中处理。如果不受绘制调用限制,那么随着剔除效率的降低和更多对象受到灯光影响,批处理的实际性能会变差!

出色实践

物理 (Physics)

物理 (Physics) 占用 CPU 的比重较大。可以通过编辑器 (Editor) 分析器对其进行分析。如果物理似乎占用了太多 CPU 时间,请:

Android

GPU

以下是一些流行的移动平台体系架构。硬件供应商与 PC/控制台空间不同,GPU 架构与“常用” GPU 相比也有很大差异。

  • ImgTec PowerVR SGX – 基于平铺延迟:在小单元内渲染所有内容(如 16x16),只为可见像素着色。
  • NVIDIA Tegra – 经典:渲染所有内容。
  • Qualcomm Adreno – 平铺:在单元内渲染所有内容,在大单元内进行设计(如 256k)。Adreno 3xx 可切换到传统模式。
  • ARM Mali 平铺:在单元内渲染所有内容,在小单元内进行设计(如 16x16)。

抽出一些时间了解不同渲染方法,并相应设计游戏。特别注意排序问题。在开发周期前期定义支持的最低终端设备。设计游戏时开启分析器对其进行测试。

使用针对特定平台的纹理压缩。

进一步阅读

屏幕分辨率

安卓 (Android) 版本

iOS

GPU

只考虑 PowerVR 架构(基于平铺延迟)。

  • ImgTec PowerVR SGX。基于平铺延迟:渲染单元内所有内容,只对可见的像素着色。
  • ImgTec .PowerVR MBX。基于平铺延迟,固定函数 - iPhone 4/iPad 1 之前的设备。

这意味着:

  • 贴图细化并非必须。
  • 反锯齿和反向异性耗费的性能很少,有些情况下 iPad 3 上并不需要。

缺点:

  • 如果每帧的顶点数据(顶点数 * 顶点着色器之后所需的存储空间)超过驱动器分配的内部缓存,那么场景须“分开”,这会耗费性能。之后,驱动器可能会分配更大缓存,或者您可能需要减少顶点数目。非常复杂的着色器上约有 10 万个顶点时,在 iPad2 (iOS 4.3) 上会趋于明显。
  • TBDR 须为平铺和延迟部分分配更多晶体管,理论上留给“原始性能 (raw performance)”的晶体管就较少。在 TBDR 上获得绘制调用的 GPU 时间非常难(几乎不可行),使分析更加困难。

进一步阅读

屏幕分辨率

iOS 版本

动态对象

资源包

iOS 上对同时下载资源包的数目有限制吗?(例如能否同时(或每个帧)安全下载 10 个资源包)?

通过 OS 提供 的不同步 API 实施下载,所以 OS 决定需要创建多少线程以供下载。多个并行下载时应注意可以支持的设备总带宽和空余内存百分比。每个并行下载分配自己的临时缓存,应注意这些缓存未占用完内存。

资源

低级错误列表

有时控制台中未出现任何问题,仅为偶然性崩溃。

Page last updated: 2013-07-08