2015/03/12: 在Reddit 和Slashdot在最后几个小时内杀死了我的带宽,30,000次访问后返回网路。其次是HN。2015/03/11:更新来自Matthijs De Smedt的评论。
原来的Deus Ex是当时最受欢迎的PC游戏之一,我花了无数个小时帮助JC Denton抵御了UNATCO或Illuminati的阴谋。
我从来没有机会玩第二部作品“ 隐形战争 ”,但是当它被释放时,我又对“ 人类革命 ”进行了设计。我可以说的是:它符合预期!
Deus Ex:人类革命是2011年由Square Enix发布的游戏,由EidosMontréal和Nixxes为PC版开发。它使用Crystal Dynamics制造的Crystal引擎的修改版本,并且是支持DirectX 11的最早的游戏之一。当时
它具有出色的图形(仍然看起来不错),它的重量比较轻巧:甚至低预算的视频卡可以顺利运行游戏。
我好奇的渲染过程,所以我花了几个小时逆向工程的游戏(译者注:使用ida正式版来逆向工程,对于源代码反编译可以看出来部分代码),与Renderdoc玩。
以下是我调查的结果。
框架如何呈现
以下是我们将考虑的场景。这是游戏的实际屏幕截图:播放器显示器上显示的最终图像。
乍看之下,Deus Ex HR似乎使用类似于前进+渲染技术的方法。
除了游戏开发前几年,前进+变得流行,实际上它使用前驱技术:“轻量级前通”的方法。
普通+深度预通
游戏渲染所有可见对象,仅输出法线贴图和深度图。
透明对象不呈现。
根据网格,每个三角形将被渲染为平坦表面(与三角形的所有片段相同的法线),或者也可以通过其自己的法线贴图进行调制。例如,浮雕具有自己的法线贴图来调制渲染到缓冲区的最终法线。
在创建法线贴图的同时,每个绘图调用也同时生成深度图:
这个步骤是在166次绘图调用中实现的。
阴影地图
阴影通过PSSM技术产生。
简而言之,场景每渲染一次可以投下阴影一次。在我们的案例中,有两个光源:一个在右边玻璃窗后面的小办公室,一个在手雕顶部。
每个阴影贴图对应于4096x3072纹理内的1024x1024平方。
这个通行证只有52个绘制调用,比渲染完整的场景要少得多。
这是通过将最大的物体标记为阴影脚轮,跳过较小的物体来实现的; 加上一些frustrum剔除可能用于仅渲染从光源可见的对象。
在生成不同的阴影贴图之后,将深度图和阴影贴图组合起来以产生阴影纹理。
读取深度图的每个纹素,并为每个光源计算其可视性。
最终结果被输出到一个像掩码一样的RGBA 8位纹理:
默认值为白色(1, 1, 1, 1)
,这意味着纹素不被任何东西遮蔽。如果一个纹理素材处于某个光源的阴影中,则与该光源对应的字节设置为0.
雕刻手指下方的阴影仅由其上的光产生,而不是办公室光线,这就是为什么它们出现blue-ish:RGBA (0, 1, 1, 1)
。
这种方法能够同时处理4个光源,更多的是使用位掩码而不是字节掩码。
一些小的可见伪像是PCF滤波技术的典型。
更新: Matthijs De Smedt指出,光源的每个通道不仅可以存储0或1(对此使用8位将是浪费的):在此过程中,像素的PCF也被计算并存储在这些8位。
严格来说,它不是真正的掩码:如果完全点亮,我们的值为1,如果完全遮挡(在阴影的中间),值为0,在阴影边缘之间的值为0到1(至给予更平滑的边界)。
屏幕空间环境遮挡
通过采样深度缓冲区,创建SSAO图。通过像素着色器获得第一个“嘈杂”的结果。然后在DirectX 11兼容卡上,使用计算着色器对19x19内核应用模糊并平滑结果。
在旧的卡片上,模糊是用像素着色器完成的。
在生成SSAO纹理之后,其值存储在法线贴图的Alpha通道内。
光通行证
场景的每个点光逐一呈现。
唯一的输入是普通+ SSAO图和深度缓冲区。受光影响的像素仅取决于光的半径和强度。
反射光的材料在这一点上并不重要,而存储在光图中的信息就是场景中每个像素可能反射的光(及其颜色)多少。
之后,这种辐照度信息将有助于计算实际反射的光量取决于网格材料及其镜面特性。
这个场景使用45点灯。
不透明物体的前向渲染
这是“实际”渲染终于发生的地方。
场景的每一个网格都被画到屏幕上。像素的最终颜色由下式计算:
- 正常+ SSAO地图,阴影贴图和掩模,光图
- 对象自己的纹理/材质属性
- 有时候,假的环境地图(128x128纹理立方体)可以增强网格的反射
首先,渲染所有不透明对象:
请注意,在此渲染步骤中,深度测试功能被设置为COMPARISON_EQUAL
而不是COMPARISON_LESS
。
此外,即使深度测试被启用,深度写入也被禁用。
这是提高性能的诀窍:记住,在正常的地图创建过程中,我们已经生成了场景深度缓冲区。所以我们已经知道像素应该具有的最终深度值。通过丢弃具有错误深度的任何片段,我们避免了大量的阴影计算,当一个更靠近相机的新片段以其自己的价值覆盖时,这将会浪费时间。
这有效地实现了0超绘制的渲染。
透明对象
这一步渲染贴花(像墙上的标志,子弹撞击),透明物体(如窗玻璃)或假体积光(点光源的光晕)。
深度函数当然会被转回,COMPARISON_LESS_EQUAL
因为我们目前还没有关于透明对象位置的信息。深度写入保持禁用,以确保靠近相机的透明网格不会取消后面的另一个透明网格的渲染。
体积光看起来很不错:这些只是在场景中处于良好位置的3D渲染的一组“精灵”。他们不是像您所期望的那样,始终面向相机的单精灵广告牌,它们实际上是二十面体 3D网格正确缩放以表示光晕。二十面体的选择是一个折中:近似球体尽可能少的几何。
这些网格也不依赖于任何纹理:“光环”在程序上计算100%。通过对深度图进行采样,像素着色器可以知道当前像素与光源的距离,并且基于该距离计算最终颜色值。
以下是用于创建效果的网格的线框表示:
为了参考,不透明和透明对象的渲染是在253次绘图调用中完成的。
浅棕色
要应用绽放效果,我们需要知道具有非常强的光强度的像素集合。
Deus Ex HR使用简单的LDR工作流程,没有HDR缓冲区可以应用亮通滤波器。
但实际上,在执行上一遍时,对于每个网格,一个额外的信息被输出到alpha通道:网格的发射强度。
这足以创建一个绽放层:这个想法是简单地应用一个大半径的高斯模糊。
图像首先缩小到一半,然后缩小原始大小的四分之一(使模糊更有效),最后模糊。
应用模糊 |
在我们获得明亮区域的模糊之后,我们只需要将它混合在原始场景的顶部。混合是添加剂,因为我们只想增加一些区域的亮度,不会变暗任何东西。
抗锯齿
为了平滑网格边缘上的锯齿状线条,Deus Ex HR支持不同的抗锯齿技术,如DLAA,MLAA,FXAA ...
以下概述了使用FXAA时的更正:
颜色校正
我们几乎完成了现场,它已经看起来不错。
最后一次触摸有一点颜色校正:应用伽玛校正,然后使用特殊的像素着色器给场景提供淡黄色的色调。
黄色的色调,有时被称为“黄金过滤器”,有点像游戏的商标。
对于那些不喜欢它的人来说,有些mod可以禁用它。
用户界面
最后一步是将UI呈现在视图的顶部。这是在317个绘图调用中完成的。
我们完成了 纹理终于被复制到后台缓冲区并呈现给用户。
时间线
只是粗略地了解流程每一步的成本,这里是对处理步骤所需时间的快速比较。
奖金备注
景深
我不认为DoF效果在游戏阶段被使用过,但在电影或对话中始终都是存在的。Deus Ex HR中使用的技术是您可以考虑的最基本的:使用高斯模糊的2层DoF。
我们得到2个版本的场景后:原来的酥脆一个模糊失焦的版本,像素着色器将线性插值 的2层之间,这取决于像素深度。
色差太近或太近,着色器会使用模糊的图像; 但是在对焦距离的右侧,着色器将使用原始图像。
高斯模糊可以在兼容硬件上的计算着色器上执行,并且可以对像素着色器进行回退。
剪影效果
在播放时,可以与场景的各种对象进行交互。游戏指示玩家可以通过将黄色着色并在其周围绘制闪亮的轮廓来操纵的对象。
在一些游戏中,效果是非常基本的:有时,网格被简单地绘制在更大的尺度上,输出恒定的颜色; 有时在整个场景渲染之后,相关网格再次被绘制在最终图像顶部的一些颜色和alpha调制。
但是在Deus Ex HR中,剪影效果是完美集成的:前面的任何封闭器可以影响最终的轮廓。请注意,闪亮的轮廓不仅遵循容器的形状,而且还遵循前面的警察之一。
那么这样的效果如何呢?
这是一个非常简单的技巧。记住包含场景每个像素的所有辐照度信息的光图?我们只需要RGB通道来存储辐照度,不使用alpha通道。而这正是在Alpha通道中,游戏存储有关属于可交互对象的像素的信息。
这是我们需要绘制剪影的唯一信息:场景呈现之后,但在绽放之前,会发生额外的传球。该通道在场景顶部绘制叠加层:标记为交互式的像素以一些三角形图案由纹理调制的黄色调色呈现,最后使用Sobel样边缘检测算子绘制剪影。绘制剪影也会输出到渲染目标的Alpha通道:这是有关亮度的信息所在的位置。绽放效果将使剪影闪耀。
进一步阅读
如果您想了解更多您可以查看以下链接的一些链接,还有很多可以说Deus Ex HR的内容。
Deus Ex在详细资料 - Matthijs De Smedt的GDC 2012演讲。
设计挑战的例外:人类革命 - GDC 2012演讲由FrançoisLapikas。
构建故事驱动的Deus Ex:人类革命的经验 - GDC 2011由Mary DeMarle的演讲。