材质和着色器

遵循以下最佳实践来优化在 Android 游戏中使用材质和着色器。

材质和着色器是现代 3D 艺术的核心构建块。在最多设备上运行良好的 3D 游戏始于旨在充分利用图形处理器的 3D 艺术。本指南重点介绍了移动设备上材质和着色器的优化和最佳实践,以使您的游戏性能更高并最大程度地降低功耗。

本文部分内容基于 Arm Limited 贡献和版权的工作。

游戏引擎移动友好着色器

不同的游戏引擎在关联材质和着色器的方式上有所不同。Unity 引擎可以创建多个着色器,但每个材质只能分配一个着色器。虚幻引擎 4 可以根据目标平台将不同的着色器应用于材质。

有关着色器和材质的定义,请参阅 面向艺术家的材质和着色器最佳实践

如果您使用的是 Unity 或虚幻引擎 4 等游戏引擎,请使用为移动硬件设计的内置着色器。这些着色器包含简化的功能实现,可在移动设备上实现更高的性能。如果可能,在配置材质时关闭未使用的功能。这些功能可能是颜色着色或细节贴图等。禁用未使用的功能可以让引擎将它们从最终着色器程序中省略,从而提高性能。

Unity

Unity 包含多个渲染引擎。对于现代移动游戏,最佳选择是 通用渲染管道 (URP)。URP 包含一组标准着色器,这些着色器会根据目标平台自动缩放复杂性。传统 Unity 渲染器包含一组专为移动平台设计的着色器。这些着色器分组在 **移动** 类别中。

虚幻引擎 4

虚幻引擎将根据所选的目标平台选择一个移动着色器。移动着色器的视觉输出可能与默认的着色器模型 5 着色器有所不同。您可以在虚幻编辑器中更改预览渲染级别,以模拟移动着色器的渲染输出。尽管存在一些差异,但虚幻引擎在所有平台上使用相同的材质处理流程,因此移动着色器的视觉效果和行为通常与默认着色器类似。

Setting mobile preview rendering in the Unreal editor
图 1. 在虚幻编辑器中设置移动预览渲染。

最大限度地减少纹理采样器

面向移动设备的游戏应该在其材质中使用尽可能少的纹理。每个添加的纹理都需要额外的纹理采样,这会消耗内存带宽并增加功耗。虚幻引擎 4 建议 在移动设备上运行时,材质纹理最多不超过五个。即使是五个纹理采样器对于许多设备上的广泛使用来说也可能过高。最大限度地减少纹理采样器数量的策略包括

  • 使用纹理打包将单通道纹理组合在一起。有关此技术的更多信息,请参阅 纹理 指南。
  • 用数值常量替换粗糙度或金属等参数的数据,而不是从纹理中读取。
  • 使用非光照着色器或简单的光照模型,以便能够省略支持更复杂光照模型中光照计算所需的纹理。

尽可能禁用光照

光照与非光照是着色器和材质的常见划分。实时光照会涉及着色器中的额外计算。根据所实现的光照系统类型,可能需要材质纹理,这些纹理会使用更多内存空间和带宽。对于移动游戏,特别是面向功能较弱硬件的游戏,最大程度地减少实时光照的使用对于实现最佳性能至关重要。您应该考虑围绕在没有实时光照的情况下效果良好的设计(例如风格化或卡通艺术)来设计您的艺术指导。

A comparison of a model rendered with and without lighting
图 2. 一个模型使用实时光照 (左) 和不使用实时光照 (右) 进行渲染的示例。

最大限度地减少透明度的使用

尽可能使用不透明材质。使用透明度渲染对象始终比渲染等效的不透明对象更昂贵。移动图形硬件的设计使透明度比计算机或游戏机图形硬件上的透明度更昂贵。在您的游戏中绘制许多透明对象,尤其是在彼此之上渲染时,会对性能产生负面影响。

多次绘制相同像素是一个称为过度绘制的问题。应避免多层透明过度绘制。许多游戏具有诊断工具来可视化过度绘制,以帮助检测和消除过度绘制。使用这些工具来提高游戏的性能并识别降低帧速率的问题区域。

An example of the overdraw visualization tool in the Unity editor
图 3. Unity 编辑器中过度绘制可视化工具的示例。
An example of the overdraw visualization tool in the Unreal editor
图 4. 虚幻编辑器中过度绘制可视化工具的示例。

使用适当的 alpha 方法

实现透明度的最常见方法是 alpha 混合和 alpha 测试。

alpha 测试将使对象材质看起来完全不透明或完全透明。您可以为该截止值配置 alpha 值阈值。在 Unity 中,这种类型的透明度称为 **Cutout**。在虚幻引擎 4 中,它被称为 **Masked** 混合模式。

alpha 混合允许对象材质具有透明度范围,并且可以使对象看起来部分透明。Unity 将这种类型的透明度称为 **Transparent**。在虚幻引擎 4 中,它被称为 **Translucent** 混合模式。

A comparison between alpha blending and alpha testing
图 5. 使用 alpha 混合 (中间) 和 alpha 测试 (右边) 渲染的示例图像 (左边)。

alpha 混合通常会产生比 alpha 测试更好的视觉外观。但是,对于某些类型的网格(例如树叶),alpha 混合在网格运动时看起来很奇怪。这是因为感知到叶子和树枝以错误的顺序进行渲染。alpha 测试最大限度地减少了这种影响,但以增加叶子和树枝上的锯齿和尖锐边缘为代价。

alpha 混合和 alpha 测试可能需要不同的时间来渲染相同的网格。对于两种模式都产生可接受的视觉输出的网格,您应该进行基准测试,看看一种方法的性能是否优于另一种方法。

分析着色器复杂度

诸如纹理采样器、灯光和透明度之类的渲染特性都会增加着色器的复杂性并降低渲染性能。您可以使用游戏引擎内置的工具以及外部图形工具来评估着色器的复杂性。

虚幻引擎 4 包含一个**着色器复杂度**视图模式,它提供场景中对象的成本估算。

The Shader Complexity viewmode in the Unreal editor
图 6. 虚幻编辑器中的**着色器复杂度**视图模式。

您还可以使用虚幻的**材质统计**功能在编写材质时分析材质的成本。

The Material Stats display in the Unreal editor
图 7. 虚幻编辑器中的**材质统计**显示。

在顶点着色器中计算

渲染着色器计算通常在顶点着色器和片段(也称为像素)着色器之间进行拆分。渲染的片段数量通常大于顶点数量。如果可以在顶点着色器中执行昂贵的计算,则与在片段着色器中执行相比,它的执行频率会更低。

但是,如果片段着色器使用此数据,则必须从顶点着色器传递它。如果要传输的数据量过大,则在片段着色器中执行计算可能具有更高的性能。您可以使用分析工具来评估磁贴利用率,以确定一组计算的最佳着色器位置。虚幻引擎 4 具有一个自定义 UV功能,可以帮助进行此分析。

避免昂贵的数学运算

数学运算用于着色器程序中以控制着色器输出的行为和外观。常见的运算包括基本算术运算、幂运算、取整运算、对数运算等。数学运算的计算成本并不相同。一个充满了昂贵运算的着色器将执行得更慢,特别是在旧设备上。相对廉价运算的例子包括

  • 加法
  • 减法
  • 乘法

更昂贵的运算包括

  • 除法
  • 超越函数(sin、cos、幂、log、tan)

经常分析性能

您的性能瓶颈可能并不总是显而易见。避免假设问题区域在哪里,并使用分析工具来评估您的渲染性能。在进行任何优化之前和之后进行测试,以准确评估其影响。