次世代手游美术资源如何优化?
“次世代”一词源自日本,意为下一个时代、未来的时代。常见的“次世代科技”,指的是尚未广泛应用的先进技术。后来,这个词逐渐成为一种习惯用语,被用来代表某类具备特定属性的游戏类型。
随着科技的发展,手机硬件不断升级,使得在移动端实现次世代游戏的画面效果成为可能。然而,我们仍面临硬件限制的瓶颈,无法像制作主机游戏那样“肆意挥霍资源”。因此,必须对各种美术资源进行优化处理,以确保在不同平台和硬件终端上都能提供良好的游戏体验。
性能瓶颈分析
对于一款游戏而言,主要有两种计算资源:CPU和GPU。它们相互协作,确保游戏能在预期的帧率和分辨率下运行。其中,CPU负责帧率相关的计算,GPU则主要处理与分辨率相关的任务。
CPU 瓶颈
- 过多的 Draw Calls:CPU 调用底层图形接口的次数过多,会导致其负担过重。例如,若场景中有上千个物体,每个物体的渲染都需调用一次底层接口,CPU 就要进行大量工作。
- 复杂的脚本或物理模拟:这类操作的计算量较大,会占用 CPU 大量资源。
GPU 瓶颈
- 填充率:即图形处理单元每秒渲染的像素数量。
- 像素复杂度:如动态阴影、光照、复杂的 shader 等,都会增加 GPU 的处理难度。
- 几何体复杂度:主要取决于顶点数量,顶点数越多,GPU 处理的工作量越大。
- GPU 显存带宽:显存带宽不足会影响数据传输速度,进而降低 GPU 的性能。
优化技术介绍
CPU 优化
CPU 的主要限制因素是 Draw Calls。Draw Calls 是 CPU 调用底层图形接口的操作,过多的 Draw Calls 会使 CPU 不堪重负。例如,在渲染场景时,若不同物体使用不同的材质和 shader,CPU 就需要频繁重新准备顶点数据、设置 shader,这一过程非常耗时,会导致 Draw Call 增多,影响帧率和游戏性能。此外,物理、布料模拟、粒子模拟等操作也会给 CPU 带来较大的计算负担。
减少 Draw Call 数量
- 批处理(Batching):批处理是将使用同一材质的物体合并处理的方法。由于同一材质的物体仅顶点数据不同,因此可以将这些顶点数据合并后一起发送给 GPU,从而完成一次批处理。
在 Unity 中,批处理分为动态批处理和静态批处理两种方式:
- 动态批处理:这种方式是自动进行的,无需手动操作,且物体可以移动。但它的限制较多,容易因不满足条件而导致批处理失败。Unity 进行动态批处理的条件包括:物体使用同一材质;顶点属性的最大限制为 900;物体需使用相同的缩放尺度(可以是非统一缩放,但所有物体的非统一缩放必须相同);使用 lightmap 的物体、多 passes 的 shader 以及接受实时阴影的物体不会进行动态批处理。
- 静态批处理:自由度较高,限制较少,但可能会占用更多内存,且批处理后的物体无法移动。使用时,只需勾选物体的“Static Flag”即可。
以下是一些批处理的使用建议:
- 优先选择静态批处理,但要注意内存消耗。
- 若使用动态批处理,需注意上述限制条件。例如,尽量减少符合动态批处理条件的物体数量,并减少其顶点属性;避免使用统一缩放,或使所有物体使用不同的非统一缩放。
- 对于游戏中的小道具,可以采用动态批处理。
- 对于包含动画的物体,可将其中不动的部分标识为“Static”。
此外,为避免因物体使用不同纹理而打破批处理规则,可将多张小纹理合并到一张大纹理中。
GPU 优化
顶点优化
- 优化 Mesh,减少顶点数量:在 3D 游戏建模时,应尽量减少模型中三角形的数量,去除对模型外观无影响或肉眼难以察觉差异的顶点。
- LOD 技术:类似于 Mipmap 技术,LOD 为模型建立了一个金字塔结构。根据摄像机与对象的距离,选择不同精度的模型进行渲染,从而在适当的时候大量减少需要绘制的顶点数目。不过,该技术需要占用更多内存,且若距离设置不当,可能会导致模型显示的突变。在 Unity 中,可以通过 LOD Group 来实现 LOD 技术。
- 遮挡剔除(Occlusion culling)技术:该技术用于清除被其他物件遮挡而不可见的物件,避免资源浪费在不可见顶点的计算上,从而提升性能。
像素优化
- 控制绘制顺序:像素优化的关键在于减少 overdraw(一个像素被多次绘制)。在 Unity 中,可通过查看 overdraw 视图来判断物体的遮挡情况。为避免 overdraw,应尽量从前往后绘制物体,这主要得益于深度检验的作用。在 PC 上,为获得准确的渲染结果,通常从后往前绘制不透明物体,再绘制透明物体进行混合;但在移动平台上,这种方式会导致大量 overdraw,因此应采用从前往后的绘制顺序。在 Unity 中,可将物体的队列设置为“Geometry”,以确保其从前往后绘制。
- 警惕透明物体的使用:透明物体的渲染需要从后往前进行,且会抛弃深度检验,容易导致 overdraw。因此,应尽量减少场景中透明物体的使用,尤其是多层覆盖的透明对象和透明粒子效果。若无法避免使用大量透明物体,可通过减少 GUI 所占面积、将 GUI 绘制和三维场景绘制交给不同摄像机等方式来降低 overdraw。同时,可在代码中对机器性能进行判断,根据性能情况开启或关闭特效功能。
- 尽量避免实时光照:实时光照在移动平台上是一项开销较大的操作。若场景中包含多个光源且使用了多 Passes 的 shader,可能会导致性能下降,甚至在某些机器上出现 shader 失效的情况。此外,逐像素的光源会增加 Draw Calls 和 overdraw,并且会中断批处理。
带宽优化
- 使用 Texture Atlas:将多个小纹理合并到一个大纹理中,可减少 Draw Calls。同时,纹理的长宽比最好为正方形,且长度值为 2 的整数幂,以充分发挥优化策略的效果。
- Generate Mip Maps:该技术会为同一张纹理创建不同大小的小纹理,形成一个纹理金字塔。在游戏中,可根据距离物体的远近动态选择使用合适的纹理,从而节省大量访问像素的数目。但该技术需要占用更多内存。
- 优化纹理尺寸大小和压缩格式:
- 纹理尺寸大小:通过 MaxSize 设置纹理的长宽值,若纹理本身超过最大值,Unity 会对其进行缩小处理。同样,纹理的长宽比最好为正方形,长度值为 2 的整数幂。
- 压缩格式:通过 Format 设置纹理的压缩格式。一般可选择自动模式,Unity 会根据不同平台选择合适的压缩模式。对于 GUI 类型的纹理,可根据画质要求选择是否压缩。此外,还可根据不同机器选择不同分辨率的纹理,以确保游戏在老机器上也能正常运行。例如,在安卓平台上可采用 RGB Compresses ETC 4 Bits 压缩模式,在 iOS 平台上可采用 RGB Compresses PVRTC4 Bits 压缩模式。
通过以上对 CPU 和 GPU 的优化策略,可以有效提升次世代手游的性能,为玩家提供更好的游戏体验。