高端 PC 继续通过高性能显卡驱动桌面游戏。 一流的“梦想机器”基于第六代智能 英特尔® 酷睿™ 处理器i7-6700K等 CPU,通常与高端独立显卡配合使用以运行要求最严苛的游戏。 由 Avalanche Studios* 开发、由 Square Enix*发布的 Just Cause 3 就是这样一款游戏。 作为 2015 年末发布的一款广受好评的游戏,JC3提供猛烈的爆炸、茂密的地形和迷人的风景,Rico Rodriguez 特工在一个无比惊艳的广阔世界中战斗、翱翔、滑行和格斗。
虽然游戏机的目标受众很大,但 Avalanche 希望确保游戏能够在尽可能多的 PC 硬件上顺畅运行,包括带集成显卡的系统。 英特尔与 Avalanche 合作完成了一系列使所有 PC 配置受益的一般优化,但并没有就此停止。 他们还组建了一支小型独立团队(大部分成员来自于 Avalanche Studios 的 Engine and Research 事业部),单独开展一个针对英特尔® Iris™ 和英特尔® Iris™ Pro 图形芯片进行优化的项目。 该项目涉及利用第六代智能英特尔® 酷睿™ 品牌 CPU 的新图形功能。
这一团队还使用了针对 Microsoft* DirectX* 12 级硬件(暴露在 DirectX 11.3 API 下)的新图形功能。 通过使用各种专长的英特尔研发工程师提供的额外资源,该团队开发了一款在最新游戏机和高端游戏电脑上呈现出色视觉效果的游戏,这款游戏还吸引玩家使用配有英特尔 Iris 显卡的高性能笔记本电脑。
英特尔集成显卡基本上分为三个级别:主流级别是高清显卡,上一级是高端主流质量的 Iris 显卡。 最高级别的集成显卡是 Iris Pro 显卡,最新版本可在第六代智能 英特尔酷睿处理器上找到。 在这份案例研究中,您将了解到英特尔优化工具如何提供多种改进途径。 我们将深入探索着色器、实例化和低级算术逻辑单元 (ALU) 优化,并说明英特尔和 Avalanche Studios 如何寻找每个性能提升机会。
图 1. 在Just Cause 3中,英雄 Rico Rodriguez 飞过覆盖复杂植被的地形。
英特尔® 图形性能分析器 (GPA) 为帮助优化Just Cause 3的复杂世界提供了一款很好的工具。 Just Cause 3 是这一大受欢迎的游戏系列的第三部。截至 2016 年中期,它在所有平台上的销售量约为 700 万。 从阳光明媚的海滩到白雪皑皑的山峰,该游戏提供 400 平方公里的绝佳地形,评论家将其称之为“为爆炸行动而准备”的开阔运动场。 英特尔和 Avalanche 专注于多重优化,将高级渲染技术推向极限。
英特尔® 图形性能分析器为 Cause 提供鼎力支持
英特尔 GPA 工具套件使游戏开发人员能够充分利用其游戏平台的全部性能潜力。 该工具能够可视化您应用的性能数据,帮助您了解系统级和单帧性能问题,以及实施“假设”实验,以估计优化能够带来的潜在性能提升。
英特尔图形应用工程师 Antoine Cohade 负责领导英特尔方面的 JC3 优化工作。 他时常从其位于慕尼黑的办公室赶往瑞典斯德哥尔摩与 Avalanche 的开发人员会面,包括项目负责人 Christian Nilsendahl 和研究负责人 Emil Persson。 “我们在远程做了很多工作,但我们在现场做了一些繁重的分析工作。 Cohade 表示:“有时候,我们每天都打电话或在线沟通。 我们基本上已经证明,我们可以让最高级、要求最苛刻游戏让英特尔硬件上顺畅运行。 开发人员可以使用这些工具和技术,在各种移动系统上运行其游戏。”
除了其他工具之外,该团队使用了英特尔 GPA 的三个关键部分:
- 系统分析器 – 分析 CPU 图形 API 以及 GPU 性能和功率指标。
- 图形帧分析器 – 对 Microsoft DirectX、OpenGL* 和 OpenGL ES* 游戏工作负载执行单帧分析和优化。
- 平台分析器 – 查看应用在 CPU 和 GPU 上所花费的时间。
图 2. 优化团队首先运行系统分析器,以确定系统是 CPU 限制还是 GPU 限制。
在 6 个月的时间里,该团队调整了下列领域:
- 低级 ALU 优化
- 实例化
- 植被
- 遮蔽
- 动态分辨率渲染
- DirectX 优化,适用于 DX11.3 API
最初,英特尔 GPA 揭示了一些关键挑战。 多个帧中有大量的绘制调用,一些单独的绘制调用在处理能力方面的成本高昂。 聚类的照明着色器和植被是改进的关键领域。
图 3. 图形帧分析器屏幕的高级视图,显示了各个组件的信息可以在哪里找到。
该团队决定实施多个 ALU 优化,以简化昂贵的单个着色器。 他们还调查了大量绘制调用经常使游戏受到 CPU 限制(由于单个 API 调用的成本)的问题。
从底层开始: 调整算术和逻辑单元 (ALU)
许多低级 ALU 优化工作涉及重做数学计算,以生成更少的指令。 这一工作的负责人是 Emil Persson,他在游戏开发者大会上发布了其作品并发表了两篇关于着色和优化的重要文章。 Persson 总结的一些经验非常简单:不要依靠编辑器为您优化,单独的标量和向量工作,并记住低级和高级优化不是相互排斥的——尽量做到两面兼顾。
调查结果显示,着色器编译器没有生成最佳代码,这不是直觉。 Persson 能够进行非常细微的更改,迫使编译器逐步创建更好的代码。 Cohade 如此评价 Persson 的工作:“我觉得很少有人花时间记录它。 很少看到有人做这种工作。 你可以看到优化,但看不到它被记录下来。”
图 4 显示了代码中的“前后对比”示例,以及编译器生成的微操作数量。
图 4. 显示之前情形(左)和之后情形(右,团队将计算拉出循环,从而节省了 30 个操作)的代码片段。
在他们的2016 年 GDC 谈话中,Cohade 和 Persson 表示,降低 ALU 的利用率意味着他们可以节省大约 2 毫秒(共 6 毫秒)。 Persson 还在他之前的一篇优化相关文章中指出,在受其他因素约束的同时将 ALU 利用率从 50% 降低至 25% 可能不会提高性能;它会减少 GPU 的散热量,这仍可以是一个很大的优势。
植被网格的实例化和调整
完成一些 GPU 优化后,该团队开展了一些测试,发现某些场景受到 CPU 限制。 例如,在下面的 GPU 视图截图中,您可以看到,一个 CPU 线程几乎 100% 活跃,而 GPU 执行中有缺口。
图 5. GPU 缺口显示,CPU 成为了当前场景的主要瓶颈。
团队发现 CPU 限制由大量的绘制调用导致后,他们的下一步行动就是尝试实例化。 实例化是指同时渲染场景中相同网格的多个副本。 实例化在创建植被时特别有用,Just Cause 3 就大量采用了实例化技术。此外,实例化也有助于创建人物和常见对象。
通过改变不同的参数(如颜色或骨骼构成),对象和植被可以表示为重复的几何形状,而不会出现不适当的重复。
实现实例化确实对受到 CPU 限制的场景有很大帮助,如下面的图 6 所示。 与图 5 相比,CPU 线程并不总是处于活动状态,这会让团队再一次回到 GPU 成为限制因素的状态(GPU 队列总是满的)。
图 6. 消除 CPU 瓶颈后的游戏同一部分。
在一种情况下,对于有许多实例的一小块植被(4 个顶点和 6 个索引),标准实例将导致波前占有率较低。 为解决这一问题,该团队决定实施手动实例化。 他们在一个较大的索引缓冲区内重复绘制几何图形,允许着色器手动获取数据,一次绘制树的多个副本。 顶点数据的数量保持不变。 数据从纹理中读取,以修改树并创建多个外观,从而减少冗余。 这样使得绘制调用的数量大幅减少,缓冲区更新的数量也有所减少。 该团队之前计算的调用时间为 2.4 毫秒,之后为 0.7 毫秒,有了很大改善。
图 7. 从实例化变为手动实例化的示例。
植被优化: 摊位和森林图层
针对英特尔 Iris 图形进行优化时,该团队发现植被渲染时间似乎太长了,因此他们决定禁用模板写入、改变英特尔 GPA 图形帧分析器中的状态并测量其影响。 他们发现,某些情况下的渲染速度有显著提高(多达 80%)。 其原因在于,在英特尔硬件上,在模板缓冲区中写入可防止硬件使用 early-Z rejection 和创建管线暂停,并避免执行单位过于闲置。
图 8. 图形帧分析器可帮助确定渲染时间似乎太长的“暂停”。
经证明,优化森林图层也是一个挑战。 团队从最低的细节水平 (LOD) 上使用密集的网格(每片 129x129,网格上映射了一个 alpha 纹理,包含使用 alpha 纹理填充细节的森林剪影)对树进行渲染。 在某些场景中,这一渲染工作需要 5 毫秒。 禁用模具也没有帮助。
该团队通过英特尔 GPA 工具发现他们受到了顶点限制,所以他们开始考虑网格优化。 他们添加了 65x65 和 33x33 LOD,从而大幅减少了着色的总顶点数量。 这会产生一个很小的视觉差异,但最高设置下的视觉效果和以前相同。
此外,该团队还进行了几次着色器优化。 他们添加了一个更简单的“无褪色”顶点着色器,并添加了预计算功能,以便“烘焙”缩放到世界矩阵中。 他们重新计算了一些常量,简化了一些数学运算,并测量出处理时间从 5.0 毫秒缩短为 2.5 毫秒。 然后他们重新访问了禁用模板写入,并将它们的渲染时间缩短到 0.5 毫秒。 这是一个很好的例子,说明了每次修复后如何检查,以查看是否有新的瓶颈隐藏在另一个问题背后。
但他们并没有就此停止。他们还重新访问了三角带,并将时间缩短到 0.4 毫秒。 总之,通过坚定追逐每一个机会,他们实现了一个数量级的性能改进。
优化阴影
级联阴影贴图 (CSMs) 通常用于防止角度混叠,这是阴影中的一个常见问题。 基本问题是,最靠近眼睛的对象需要比远处物体更高的分辨率,因此将阴影覆盖划分为多个贴图可支持不同的分辨率。 JC3 在散射更新模式下使用 4 个太阳阴影级联,每个帧仅更新两个级联,这可节省不少时间(毫秒)。 然而这一周期优化在相机翻转时会造成问题,因为阴影在几个帧中弹出。
为了减少弹出,外部阴影已设置在相机的四周,而不是在它的前面:
这种方法迫使 Avalanche Studios 禁用投影剔除,并使用另一个级联来增加阴影范围。 这会在剔除和尺寸方面花费更多的时间,因此他们寻找了一种替代方法。 他们没有找到解决问题的方法,因此恢复到原来的方法,但这次他们引入了一个强制外部级联在相机翻转后的第一个帧进行更新的调整。
该团队还针对低阴影设置禁用了云阴影。
地形和其他调整
为优化JC3中的茂密地形,该团队不断开发地形系统,从一个粗糙的地形计划(只有三个细节层次)改进为一个更精细的补丁系统。 这将较多的绘制调用变为了较少的离屏损耗,并优化了 LOD 调整,根据场景的不同可节省 1-2 毫秒。
该团队还研究了渲染通道之间存在哪些依赖关系,并且小心翼翼地不添加任何新的依赖关系,以便尽可能高效。 这便找到了以下 3 个优化:
- 更好地剔除水箱,在看不到水时可节省一个完整的渲染通道。
- 运动模糊和时间抗混叠被禁用时,禁用速度通道。
- 当他们检测到屏幕空间反射被启用时,他们禁用了平面反射通道。
该团队还试图去除尽可能多的空隙,并针对需要空隙的通道使用硬件的快速清除路径(资源创建过程中未设置清除颜色时为 0,0,0,0 或 1,1,1,1)。
由于 PC 硬件通常具有不同于控制台的 CPU/GPU 平衡,该团队研究了如何重新平衡 CPU 和 GPU 之间的工作,并将一些工作移回到了 CPU。 这帮助他们缩短了着色时间,增加了 CPU 计算量,并提高了效率。
图 9. 优化之前和之后的性能增益。
整体而言,该团队利用集中优化,将英特尔 Iris 显卡上的游戏性能提高了一倍。
DirectX 功能
2015 年,各种新显卡进入市场,其中有几款产品与新的 DirectX 12 (DX12) 应用程序接口 (API) 相一致。 这些显卡支持保守光栅化和光栅化有序视图等新功能。 尽管设计用于 DX12 API,但这些功能在 DX11.3 中才公开,因此适用于 Just Cause 3 工程师。 Avalanche 调整了其引擎,以匹配专门面向游戏 PC 版本的特定新功能。 由于第六代智能英特尔酷睿显卡拥有完整的 DX12 功能支持,该团队决定使用这些显卡,以获得额外的性能提升或图形改进。
在 GDC 2015 上,Avalanche 和英特尔讨论了通过 DX12 实现的 PC 功能,如无规则透明度和光分配的保守光栅化。
光分配的保守光栅化
保守光栅化是“经典”光栅化的替代方案,当三角形覆盖像素的中心时,像素将被光栅化。 保守光栅化意味着至少部分被渲染图元覆盖的所有像素被光栅化。 它可以用于许多情形,包括碰撞检测、遮挡剔除和可见性检测。
正如 Persson 在他的2013 Siggraph 演讲中提出的,Avalanche Studios 的引擎是一个使用集群阴影的延迟渲染器。 集群阴影通常拥有与传统延迟渲染器相同或更好的性能,可改善最糟糕的案例情境,解决传统延迟渲染器的深度连续性问题。
本文中的许多工作在 Kevin Örtegren 和 Emil Persson 的GPU Pro 7 文章 和 Örtegren 名为“集群阴影: 使用保守栅格化分配任意形状的凸光体积”(Blekinge 理工学院出版)的硕士学位论文中有所提及。 基本而言,这种新方法需要将通常在 CPU 上完成的光分配通道替换为使用保守光栅化的 GPU 版本。 这可以针对不同的光形状实现完美聚类。 “GPU Pro 7 的整个源代码”文章发布在 GitHub 上。 Örtegren 的论文与实践方法之间的最大区别在于使用位字段而非链表(这在JC3中可行),因为灯光的最大数量被认为是每种类型 256 个。 经证明,位域方法在重负载下速度更快,在轻负载下仅稍慢一些。 整体而言,保守光栅化方法的增强型光剔除能力带来了高达 30% 的改进。
无规则透明度
无规则透明度是应对实时渲染领域最基本挑战之一的一种方法,经证明在过去几年的许多游戏中是相当成功的。 Marco Salvi 的原始方法和 Leigh Davies 关于 网格 2 的文章详细描述了这一主题。
Avalanche Studios 的引擎过去一直使用 alpha 测试进行快速植被渲染,而该团队看到了一个通过在 JC3中实施类似方法来改进游戏视觉质量的机会。 OIT 代码在几天以后集成到 Avalanche 引擎中,无需任何资产变更,并且极大提高了植被渲染的质量。
图 10. 来自JC3的两个场景,左图未使用 OIT ,右图使用 OIT。
由于上面的链接中已经详细介绍了这一方法,因此本文将介绍原始方法和Just Cause 3方法之间的区别:
- 使用 HDR 的原始方法包含使用一个 32 位缓冲区来存储深度节点,另一个用于颜色和 alpha。 但在这种情况下无法使用 HDR 渲染。 这是通过在深度缓冲区中打包 alpha 的第八位,从而为 R11G11B10F HDR 缓冲区留下另一个缓冲区来解决的。
- 作为一种额外的优化手段,该团队转而使用 Texture2DArray 来存储每个节点(而非结构化缓冲区)。使用少于四个 AOIT 节点(JC3 使用两个)时,该团队获得了一些性能优势。
- 由于 JC3 是一个开放的世界,有很多古老的植被,英特尔和 Avalanche 工程师意识到 Salvi 的方法将耗费大量成本。 为了将性能从高端 PC 提升至带集成显卡的主流系统,开发人员决定为 OIT 添加质量级别,在低设置下使用第一个 LOD 上的 OIT,在高设置下使用所有细节层次。
结论
作为英特尔和 Avalanche 之间的合作成果,整个渲染管道的多重优化使得用户可以在配有英特尔 Iris 显卡的系统上获得与 PS4* 和 Xbox* 1 等领先平台几乎不相上下的笔记本电脑游戏体验。
本文介绍的许多优化不仅有益于配有集成显卡的系统,也对配有独立显卡的高端系统有好处。 毕竟,所有系统都可以从更好地平衡 CPU 和 GPU 工作负载中获益。 不过,为更广泛的受众推出 Just Cause 3 这样的热门游戏是一件令人兴奋的事情。 Microsoft Surface Pro* 4 等中端和高端移动设备的市场份额预计将增长,英特尔® NUC 套件也应当为玩家提供有趣的选项。 NUC6i7KYK 套件代号为“骷髅峡谷”,包含一个非常快速的四核英特尔酷睿 i7 处理器和英特尔 Iris Pro 显卡。 这些移动设备正在为游戏制作者邀请目标,无论图形输出的要求多么苛刻,本文介绍的优化将可帮助影响这些设备。
更多资源
英特尔 GPA 文档: https://software.intel.com/zh-cn/gpa-support/documentation
Formula 1 文章: https://software.intel.com/zh-cn/articles/codemasters-leads-the-pack-in-pc-to-tablet-optimization-with-grid-autosport
Just Cause 3: https://justcause.com
集群着色: http://www.cse.chalmers.se/~uffe/clustered_shading_preprint.pdf