《魔灵召唤:克罗尼柯战记》 US(WW) 和 KR by Com2uS 专门利用 Vulkan 在 Android 上进行渲染,可将性能提升高达 30%。
Vulkan 是一种现代化的跨平台 3D 图形 API,旨在最大限度减少设备图形硬件与您的游戏之间的抽象。与 OpenGL ES 相比,Vulkan 的 CPU 开销更低,并且 Vulkan 提供更广泛的功能。
![](https://developer.android.google.cn/static/images/cards/distribute/stories/com2us_game.png?authuser=7&hl=fi)
呈现功能
Com2uS 为《魔灵召唤:克罗尼柯战记》开发了高级渲染功能,包括:
- 自定义延迟渲染系统,具有预渲染灯具剔除功能,并且视图视锥中同时有多达 16 个活跃光源
- 间接渲染实例化方法(称为
Clay
),用于一次性绘制多个网格、材质和纹理 - 为预渲染任务广泛使用计算着色器
- 能够根据相机移动、图形选项和运行时性能动态调整主动阴影渲染和后处理效果
移动设备硬件配件
《魔灵召唤:克罗尼柯战记》对 Android 设备、个人计算机和专用游戏机使用相同的渲染程序。为了在移动硬件上实现最佳性能,Com2uS 调整了渲染设置,包括绘制深度和密度。为了适应搭载 Android 11(API 级别 30)及更低版本的某些设备,Com2uS 创建了一些着色器的替代版本,并减少了实例数量。《魔灵召唤:克罗尼柯战记》还使用 Android 上的自适应性能功能,根据设备热条件动态调整图形选项。
仅使用 Vulkan 的原因
Com2uS 出于多个原因将 Vulkan 仅用于《魔灵召唤:克罗尼柯战记》:
- 设备最低要求排除了缺少 Vulkan 支持、功能较弱的旧设备
- 自定义 Unity 引擎的内置渲染管线 (BiRP) 必需的功能,这些功能仅在游戏的 Vulkan 后端中提供
- 利用计算着色器输出和着色器存储缓冲区对象 (SSBO) 的渲染功能的实现可以在 Vulkan 上完成,但不能在 OpenGL ES 上完成
计算工作负载
《魔灵召唤:克罗尼柯战记》会执行大量计算着色器工作,以生成用于渲染的数据。计算着色器可用于:
- 对象挑选
- 碰撞检测
- 动画任务
- 间接渲染数据生成
将生成的计算数据写入 Unity 引擎 RWBuffer 对象。为了实现最佳性能,《魔灵召唤:克罗尼柯战记》会通过单个调度运行其所有计算作业,这需要同时使用多个 RWBuffer。这种方法只能使用 Vulkan,因为 Unity BiRP OpenGL ES 后端一次仅支持使用一个 RWBuffer。
为渲染生成的数据集通常大于统一缓冲区对象 (UBO) 的设备大小限制。《魔灵召唤:克罗尼柯战记》则改为使用着色器存储缓冲区对象 (SSBO),这些对象具有更大的容量限制。但是,将 SSBO 绑定到顶点阶段操作需要只读 SSBO 支持。OpenGL ES 仅支持读写 SSBO,而 Vulkan 可以将 SSBO 标记为只读。
使用 Clay 进行间接实例渲染
针对《魔灵召唤:克罗尼柯战记》,Com2uS 开发了一种方法,通过一次绘制调用将多种材质、网格和纹理批量处理。Com2uS 将该系统称为 Clay。通过显著减少绘制调用次数,Clay 将游戏性能提升了 30%。
Clay 从剔除和碰撞阶段开始,首先构建一个兼容的可见可渲染对象列表。然后,Clay 会将每个识别的对象的渲染信息生成到 SSBO 中。此过程是使用计算着色器执行的,这些着色器支持使用 Unity 渲染程序 DrawMeshInstancedIndirect 函数来使用间接实例渲染。采用间接渲染方式时,实例信息和实例计数参数直接在 GPU 上生成。在绘制对象时,Clay 会绑定一个圆锥网格,而不是绑定传统的对象网格,如下图所示:
![](https://developer.android.google.cn/static/images/cards/distribute/stories/com2us_cone.png?authuser=7&hl=fi)
然后,Clay 使用计算着色器生成的顶点转换数据的绑定 SSBO,在顶点着色器中转换圆锥网格。将 SSBO 绑定到顶点阶段需要使用 Vulkan。Clay 可以使用多个变形圆锥来渲染单个对象。对象的复杂程度决定了圆锥的数量。
![](https://developer.android.google.cn/static/images/cards/distribute/stories/com2us_cone_usage.png?authuser=7&hl=fi)
对象的 Material 数据在计算着色器生成的另一个缓冲区中批量处理。缓冲区会绑定到 fragment 着色器。要绘制的对象的纹理是在纹理数组中配置的。对象纹理的数组索引包含在对象的 Material 数据中。在理想情况下,Clay 可以通过最多七次绘制调用进行渲染:
- 静态对象
- 动画对象
- 阴影(4 次迭代)
- 反思体会
Unity 与 Vulkan
《魔灵召唤:克罗尼柯战记》表明,Unity 游戏引擎与 Vulkan 图形 API 的强大组合使开发者能够将游戏机级画质的高级图形引入到 Android 设备上。