祖传的和最新的:聊一聊艾尔登法环的渲染系统
godof喷
2022年03月26日 11:28

阅读本文之前:

  • 作者并非FromSoftware员工

  • 本文内容仅基于老头环1.02版本抓帧分析得出

  • 本文仅代表个人观点,而非FS官方观点,故可能包含误导性信息,请注意


关于艾尔登法环的引擎,普遍的观点是“祖传”。这种认知从某种意义上说是正确的:艾尔登法环的渲染系统包括大量祖传的痕迹;但是同时艾尔登法环的渲染系统选型又非常激进:这是一个DX12的引擎。这种祖传与激进混搭导致了艾尔登法环的一大特色:既有渲染性能问题,又有渲染不稳定性问题。前者来自老引擎在应对开放世界大量对象渲染的压力;后者来源于DX12 API自身的使用难度等。

DX12

引擎的API是DX12。没错,并非DX11而是DX12。

需要注意的是,DX12并非DX11的直接后继,两者更像是上下层面的关系。DX11作为一个更高层的API如今依然在更新,并且是一个被广泛使用、兼容性和稳定性都很好的图形API。DX12作为一个更加底层的API,把大量的底层细节交给开发者,也对开发者有更高的要求,同时如果针对游戏的需求进行良好设计,则能获得比DX11更好的性能。

简而言之,DX11像Python,DX12像汇编(仅仅感性层面的比喻)。

而艾尔登法环的引擎是直接使用的DX12。然而从实际绘制层面,并没有太看出充分利用了DX12在性能方面的优势。更像是DX11的引擎按照同样的思路去移植到了DX12。

本人是真的没有看懂为何要这样选型,可能只有FS的R&D团队能够给出内部的理由了。

剔除

引擎并没有像育碧、寒霜那样选择GPU Driven的系统,而是依然在CPU端做剔除,把结果发给GPU,从而让CPU端的压力更大一些。

且,因此剔除做的并不是很好,例如即使人物背对摄像机,依然会绘制人物的胡须等。

全局光照

引擎采用了Image-based lighting做高光反射,用Irradiance Volume Texture做间接光反射

Irradiance Volume Texture 概念图

并且为了完成昼夜转换,需要2套这样的信息,然后根据时间进行插值。

这让我意识到,游戏中其实时刻都在进行两部分的加载:

  • 玩家移动导致的新区块的加载

  • 时间变化导致的新光照信息的加载

这两种加载中的某一个一旦过多,就会卡住读写部分导致卡顿。

阴影

环境阴影是级联阴影贴图,其中远景阴影提前缓存,其余部分每帧绘制

注意右下角人物独立的阴影

似乎是由于阴影贴图分辨率限制,人物的阴影单独分到一个区域,以高分辨率渲染。

所以仔细观察的话,游戏中的人物阴影会显著地比周围的环境清晰。爬梯子的时候能更加明显。

雾气

雾气是艾尔登法环中的重要氛围因素。

游戏中的雾气会被以低分辨率渲染,然后合成到最终的画面内。

地表金黄色的雾气是真正的平滑后的模型

然而,对于近景雾气,低分辨率的雾气纹理是不够的。所以这部分雾气其实是曲面细分后平滑了的雾气粒子。这部分的渲染压力是不容小觑的。

只能说这可能是为了艺术表现力做的妥协。

运动模糊

引擎似乎会对人物再次绘制一次速度向量缓冲区,以应对运动模糊。我不知道二次绘制的原因。但是对性能的影响是显著的。

一些废话

  • 从抓帧结果来看,关闭SSAO和运动模糊也许能显著提升性能

  • 艾尔登法环的开发成员中,美术部分的话语权应该大于程序部分,从而让许多的优化和性能设计必须让位于美术表现力。(这似乎是日厂传统?)

  • 祖传和激进混搭确实是一大奇景,希望老头环收入足够之后,能够让R&D团队彻底更新一下引擎。或者直接迁移到UE5之类的更成熟的商业引擎。