舫摘

知人者智 自知者明 胜人者有力 自胜者强

0%

《GTA5》的一帧画面是如何制作的?揭秘游戏背后的故事

G-缓冲区:

画面革新的关键就在这里,所有可见网格一个接一个着色,但不会同时进行阴影计算,着色器会将一些简单的相关阴影输出到G-缓冲区,《GTA5》采用的是MRT技术,因此每个着色器单位可以同时渲染五个单位。
  随后,这些在G-缓冲区的阴影将会合计到一起进行像素着色,因此得名递延,在这一步中,绘制的内容只有那些不透明的物体,像玻璃这一类物体需要采用其他递延管道进行处理。

这些渲染的最终目的是为了LDR缓冲(RGBA, 8-BITS每个管道)能够更快地计算出最终有效阴影的数值。

G-缓冲15%效果


G-缓冲30%效果


G-缓冲50%效果


G-缓冲75%效果


G-缓冲100%效果

其中涉及到的渲染内容包括:
 漫反射贴图缓冲区:它的作用是储存“内在颜色”的网格,代表了物体本身的材质,理论上不受光照影响,但你可以注意到汽车引擎盖上的泛白区域,R星在定向输出漫反射贴图之前计算了太阳光的阴影效果。

法线贴图缓冲区:用于储存每一个像素的法线向量(R/G/B)。

镜面贴图缓冲区:里面包括了物体的高光/反射信息:

  • Red:高光强度
  • Green:光泽度(平滑性)
  • Blue:菲涅尔强度(判断所有像素是否属于同一材质)
     发光贴图缓冲区:红色通道包括受太阳光照影响的所有独立像素所反射的光照,蓝色通道则是包括物体受到第二光源的反射,绿色通道则是处理物体本身具有的发光反射(霓虹灯、灯泡)。在这里大多数阿尔法通道是不使用的,除非需要标记对应字符的皮肤或是植被的像素单位。

深度贴图缓冲区:用于储存镜头里每个像素之间的距离。

左为深度缓冲,右为模板缓冲

上述所有缓冲区最终形成需要大约1900左右的draw calls(draw call是openGL的描绘次数,数值越低越好,对于GTA5来说,1900这个数值是非常低了。)注意,在场景渲染中,从前到后的顺序是最明智的,剔除更多不需要渲染的内容,这样一来可以进一步减少显卡压力。

阴影:

《GTA5》采用的阴影技术是CSM(cascaded shadow maps一种比较新的实时阴影渲染技术,专门用于渲染大型场景,效果很好,但是有一个缺点就是场景需要多次渲染,它的中心思想是将屏幕像素分散到多个ShadowMap中,因为近处的东西细节较高,远处的东西细节较低,因此将视椎体分割,并将光源摄像机聚焦到对应的小视锥上),贴图像素为1024X4096,用此技术是为了确保玩家附近的阴影拥有更高的像素,而远处物体的阴影细节则适当减弱。

这一步有很高的性价比,虽然说要进行4倍渲染次数,但其间可以避免大量不必要的多边形裁剪,使得draw calls数值维持在1000左右。
 通过深度信息,计算出每个像素的阴影,进而进行分类,太阳方向的光反射阴影处于红色通道中,而在大气中透过云投射将会分别储存在红色和绿色通道中。

绿色部分为太阳阴影,灰色部分为云朵阴影

同时阴影将采用抖动模糊效果处理,如果你仔细观察下面的贴图,红色管道所呈现出的是类似棋盘状的效果,这是为了边缘更加平滑。(模糊效果处理是非常繁杂的过程,因为它需要处理大量问题贴图,但最终获得的效果能够让阴影更加真实)

模糊处理后得到的阴影图

平面反射贴图:

这属于后期检测的一项步骤,因此在这里不多赘述,简而言之就是还原反射所对应的贴图在一个240X120的图案中(约650draw calls),从而呈现一个面上所反射包含的内容。

SSAO(Screen Space Ambient Occlusion屏幕空间环境遮蔽):

线性版本的缓冲计算结束后,就开始建立SSAO画面。
 首先建立多噪点版本,通过depth-aware模糊技术进行双向排除(横向和纵向)去除画面中的噪点。上述工作都是在原图一半的分辨率下进行的,为了扩展后得到更好的画面表现效果。

多噪点版本


SA模糊技术后效果图

G-缓冲区结合:

是时候把各个缓冲区之间的内容结合了,一个着色器同时获取五个缓冲区的内容,形成最终的HDR图片。


将缓冲区的图片融合,得到初步效果图

这样子最终图片的雏形已经完成,但我们依旧缺少天空,海洋以及一系列透明物体,在此之前,至少我们的麦克还不够完美。

次表面散射(Subsurface Scattering):

麦克皮肤上存在许多不连续的黑点,让他看起来像是用塑料做的而不是人肉。


这时候就轮到SSS技术登场了,模拟皮肤内的光传输,通过SSS后我们可以看到麦克的肌肤内似乎有了血液流淌的痕迹。而SSS技术只会应用在皮肤上而不会衍生到衣服等其他物品上是由于缓冲区计算出麦克皮肤的像素值为0x89,符合这一区域的物体才会收到SSS效果影响,而这个效果将会作用于游戏中主角以及NPC的皮肤上。

水:

在这张例图中虽然没有大面积水域,但还是有一些游泳池等东西,《GTA5》中的水是通过折射和反射两个层面呈现。

通过Z缓冲区导出两个版本的图像,分散出不同的水面内容:

扩散图


不透明属性

水体扩散图像:展示了水的内在颜色。
 水体不透明图像:其中红色管道储存水中的不透明属性,绿色管道区分水的深浅。

注意,在这里所有水都呈现出来了,包括隐藏在物体后面的,都会在红色管道中出现,在这里绿色管道的作用就是剔除那些隐藏的水面,保留视觉可以看到的。随后我们就可以得到下面的水面反射图片。

再结合上面的缓冲区图片内容,我们就可以获得一张带水的画面图。

大气层:

创建光过滤贴图,这也被称为体积阴影,实现光是透过大气层或是雾等气候后的照射效果,而不是太阳直射。这样之后的图像也存在许多噪点,需要进行模糊效果处理,在此之后,添加雾面层,随后是天空,最后加入云彩。

光轴图


基础图


基础+雾效果


基础+雾效果+天空


基础+雾效果+天空+云

天空的构建采用球形单点draw call,参考下图,大规模网状覆盖整个区域。云渲染也采用相似的方式,用前面提到过的法线贴图和密度贴图来渲染体积云,尺寸为2048x512,无缝连接。

云密度


法线云

透明物体:

添加画面中的透明物体,比如玻璃,挡风镜,车窗,以及飞行的尘埃粒子等,这个过程仅仅占用11draw calls,就能够完成大量粒子实体化。

添加前


添加后

抖动平滑:

远景像素点由于渲染程度有限,在放大后像素化叫严重,这时利用着色器进行后期处理,读取原始颜色缓冲区数据并通过阿尔法管道进行扩散,得到像素化严重的色区数值,进行共同抖动处理。PC版本和PS3/版本这方面处理的并不好,抖动过滤器并没有完善使用。


抖动处理前


抖动处理后

曝光度调整:

曝光度永远不能够过快的转换,相邻两帧之间的差别不能够有过高的变化,平缓地转换非常重要,例如你在《GTA5》中驱车从一个山洞驶出,暗到亮的变化需要多点曝光来适应玩家眼球对于视觉差变化的适应程度,暗到亮的曝光速度要比亮到暗的曝光速度更快,这是根据人眼习惯所得出的结论。


左为低曝光度,中间为中等,右为高曝光度

抗锯齿及光学畸变:

如果游戏的抗锯齿方式采用的是FXAA,那么需要紧致网格来达到边缘平滑的效果,随后模拟真实世界的镜头,通过小着色器进行光学畸变,这不仅仅会扭曲整体画面,也会减少边缘纹理的色差。

光学畸变前


光学畸变后

UI:

这里提到的UI仅仅只是改帧画面在左下角地图上的变化,整个地图区域被划分为不同方块区域,通过引擎划分出显示在同一屏幕的区域,得到更好的变化效果图。最后将小地图载入主要缓冲区,添加上小的图标,我们的最终作品就诞生了。


添加地图UI后

这一帧画面总计4155 draw calls,88个渲染目标以及1113个纹理图。
可以看出制作一帧画面,如果厂商用心优化的话,是需要非常麻烦的步骤,一步步改良减少显卡压力,最终让更多玩家的PC能够顺利运行,这方面,本次R星的《GTA5》无疑做的相当出色,期待今后能够为我们带来更加完美的作品。