我是James Fulop, 《激战2》项目团队高级引擎程序员。 DirectX11的支持是一个酝酿许久的项目。在这篇文章中,我会和大家一起来回顾一些复杂的技术层面的决策制定,这些决策确定了整个项目的雏形。同时,会和大家展示图像运行时,DirectX11提升的渲染效果和性能表现。
DirectX11的beta测试将于9月24日开启,届时,你可在系统设置 – 图像选项中进行勾选加入测试。首次勾选后,需要重启游戏选项才会生效。
那为什么我们首先决定升级DirectX11?客户端性能是我们的首要任务, 我们希望每一位玩家都可以在高帧数的情况下进行游戏。我们知道目前在游戏运行时,玩家会因为游戏渲染而造成卡顿的现象。《激战2》至今已经上线9年了,如果能将一些需要依赖DirectX11才能工作的功能实装,那这款游戏随着时间的推移画质将仍然会十分出彩。
DirectX11同样会我们提供许多DirectX9无法支持到的先进技术选项的可能。所有完成DirectX11的支持,能让我们在将来做更多酷炫的事情。
在经过仔细的研究,我们决定将开源图像渲染库BGFX集成到《激战2》中。 BGFX 是一种十分出色的编译写法,支持各类图像处理,并且在游戏业内被广为使用。你可以访问他们的 官方网站 了解更新信息。
随着计算机行业图形生态系统的不断发展,BGFX像是使一群渲染工程师在一起合作工作,而不是在各自的工作室闭门造车。 ArenaNet已经并将继续使用BGFX并且做出一份自己的贡献。
我们之所以选择DirectX11,而不是DirectX12或是Vulkan,是因为我们发现切换至BGFX的DirectX11已经能为游戏的图像渲染性能带来显著的提升,图像渲染处理不会再是限制客户端性能的因素。DirectX11的表现十分稳定并且已经经历了众多游戏的检验。它操作系统支持最低需求是Windows Vista,而如果使用Vulkan那操作系统最低需要Windows 7,如果使用DirectX12,则最低需要Windows10。就图像的特性而言,从DirectX9跳至DirectX11将会为我们在今后为游戏添加更多有趣的功能提供了大量的可能。而且过多的图像渲染器会加大我们的QA工作量,也不会为游戏本身质量带来更多的益处。
目前DirectX9的渲染功能并未做任何重大的变动。我对该项目的初衷是将DirectX9和DirectX11 的功能架构设计的尽量相同。这样我对2者同时做一些改动,就能更清晰的看出二者的变化与区别。当DirectX11变得完全稳定后,DirectX9就可以光荣退休了。
什么是“帧”
现在,让我来介绍DirectX11是如何来影响游戏的表现的。从最基础的开始,所有的电子游戏就如同电影一样,你所看到的所有动作是由许多张静态图片在你面前快速翻过。我们称每一张静态图片为一帧。这也是帧数(“frames per second”FPS)的来源。当帧数越高的时候,你所看到的动作会越流畅,直到达到你显示器的刷新率的最大上限。不断的对游戏输入指令(通过键盘和鼠标)并生成帧的过程,这就是游戏运行中的循环。
接着就是对一定时间线上的游戏中的循环进行可视化。 我在游戏菜单 – 系统设置 – 图像选项选择了游戏图像的最 佳效果,并选择狮子拱门上图的位置获取数据。
我选择这个地方是因为这里有大量的图像需要渲染。这里有城市的全貌,并且我们的通过技术手段将城市在湖面中呈现出倒影效果,这倒影等于需要渲染出第二座城市。
这次测试,我使用了 Intel I7-6700 CPU 和 Nvidia 1080 GPU。
上图是我们使用的可视化检测工具(Telemetry,由RAD Game Tools研发)的检测数据截图。它将游戏运营时,CPU的分配情况进行了可视化。 处理用时由水平行的数据呈现。这里显示了游戏逻辑中的2帧。我去掉了一些不相干的内容,这样能看起来更清晰。
每一个水平行表示一个逻辑线程。我们根据CPU所支持的线程总数调整了工作线程的总数。我有一个可以同时支持8线程运行的芯片,所以,游戏占用了一条线程,渲染占用了一条线程,另外还有如你们所见的6条工作线程。需要注意《激战2》同时还会有其他线程需要运行,但是我在这里暂不做展示。那些线程的工作并不特别占用CPU也与本文主要说的DirectX11无关。
在线程中的各个区块表示正在处理的工作。线程中空白的部分,意味着那时处于空闲状态,没有任何游戏有关的工作在处理或执行。在那些空白处,线程有可能在接收并处理电脑上的其他应用程序。
这里一帧既是我们所说的游戏循环开始的地方。图片中的垂直线既是一帧的开始。也就是说在这里,玩家可能点击了鼠标或者是敲打了键盘。
这里是图像和每帧动作循环交互的地方。由于刚接收到的一帧动作提交但还未被渲染成图像,电脑会将上一帧渲染的部分图像再次放入到下一帧中,这样我们就有时间可以尽可能多的并行渲染工作。但在有些时候,你必须等到最后一帧图像刷新,才能提交并开始下一帧的渲染工作。这里你也许已经注意到了主线程中工作的红色区块,他们与渲染线程上某些工作结束的时间对齐。这就是我们想要解决的问题。游戏线程永远不应该等待渲染线程工作完成再提交下一帧的渲染需求。
旁白:在主线程上还有着数个更小的红色区块。这是主线程在等待其他线程的工作完成。
这里我们圈出渲染线程中要执行的详细指令列表。当渲染需求出现后,它们将会进入渲染线程。
在渲染线程中,它们会被分配到特定的图像处理端完成图像渲染工作(OpenGL 或 DX9)。
DX11 渲染测试结果
这是在新的渲染器检测到的数据。
这里占用的线程数量相同。
主线程不再需要等待渲染线程的工作完成!这是由于BGFX的架构下,图片的渲染指令会在游戏线程上完成收集并分配(当然也会工作线程上,我们会做到这点的)。接着当一帧动作结束后,BGFX就会立刻开始处理那些渲染指令而不是等待现有渲染线程中的工作完成。这样我们就会有更多的时间来渲染图像!
将在渲染线程队列中的渲染指令,通过BGFX分配到其他空闲的工作进程中进行并行工作。
就是这样!这一切对我来说太有趣了。我十分期待《激战2》之后更多的技术更新。
我们十分欢迎收集到更多关于DirectX11的测试反馈。
让我们在泰瑞亚见!
-James Fulop