侠盗猎车手V -图形研究 (之前的中文版)
技术文库图文教程技术文章3D建模
显示全部 9
1444 11
实名

通过了实名认证的内容创造者

发布于 2022-12-19 10:43:56

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 首席游骑兵 于 2018-8-2 08:27 编辑

侠盗猎车手V -图形研究
gtav_logo.jpg
[url=]侠盗猎车手[/url]系列已经走了很长的路从第一作品早在1997年就出来了。大约2年前,[url=]明星[/url]发布[url=]侠盗猎车手V[/url]。这个游戏是一个即时的成功,在第一个24小时销售1100万台,立即[url=]了7个世界纪录[/url].
在PS3上我印象深刻的波兰和游戏的技术质量。
没有什么比加载屏幕更杀死浸:侠盗猎车手V可以玩几个小时,驱车数百公里变成一个巨大的开放没有一个中断。考虑到大量流和资产[url=]PS3的规格[/url](256 mb内存和256 mb的视频内存)我很惊讶这个游戏不会崩溃后20分钟,这是一个真正的技术实力。
在这里,我将讨论举11中的PC版模式下,吃了几个gb的内存从RAM和GPU。PC-specific即使我的观察,我相信很多在一定程度上可以适用于PS4,PS3。
  • [url=]第1部分:解剖一个框架[/url]
  • [url=]第2部分:LOD和反思[/url]
  • [url=]第3部分:伴生[/url]
解剖一个框架
这是我们将研究的框架:迈克尔,在他面前的快速GT,Los Santos在后台的美丽的城市。
00_final_frame.jpg
侠盗猎车手V使用[url=]延迟渲染管道[/url],工作很多HDR缓冲区。这些缓冲区不能正确显示原有监控,所以我用一个简单的进行后期处理[url=]Reinhard运营商[/url]带他们回每通道8位。
环境Cubemap
作为第一步,游戏呈现[url=]cubemap[/url]的环境。这cubemap是在每一帧实时生成的,它的目的是帮助以后呈现现实的反映。这部分是forward-rendered。
这种cubemap呈现怎么样?对于那些不熟悉的技术,这就像在现实世界中你会做拍摄全景照片时:把相机安装在三脚架上,想象你站在中间的一个大立方体,立方体的射击6面临着,一个接一个,每次旋转90°。
这就是游戏是:每个面呈现成128 x128 HDR纹理。第一个脸呈现如下:













重复同一过程的剩余5的脸,我们终于获得cubemap:
多维数据集从外面
视图从多维数据集


(拖改变视图方向)

每个面呈现与大约30画调用,网格非常低多边形只有“风景”是吸引(地形、天空,某些建筑),字符和汽车不呈现。
这就是为什么在比赛中你的车反映了环境很好,但是其他的汽车没有反映,也不是字符。
Cubemap Dual-Paraboloid地图
环境cubemap然后转换为我们获得[url=]dual-paraboloid地图[/url].
多维数据集是投射到一个不同的空间,类似于投影[url=]sphere-mapping[/url]但随着2“半球”。
Dual-Paraboloid地图

为什么这样一个转换?我猜是关于优化(像往常一样):用cubemap片段着色器可以访问128 x128 texel的面孔,dual-paraboloid地图带来这128 x128“半球”。更好:因为相机是大部分时间在车顶,大部分的访问将半球顶部完成。
dual-paraboloid投影保留的细节反映正确的顶部和底部,为代价的。侠盗猎车手很好:汽车屋顶和兜帽通常是面对,他们主要需要从顶部反射看起来不错。
另外,cubemaps可以有问题的边缘周围:如果每个脸mip-mapped独立一些接缝将明显边界,和老一辈不支持gpu过滤过的脸。dual-paraboloid地图不遭受这些问题,它可以mip-mapped轻易不创建。
更新:在下面的评论中指出,似乎gta4也依靠dual-paraboloid地图,除了不执行从cubemap后处理:网格扭曲的直接由一个顶点着色。
扑杀和水平的细节
这一步是由处理[url=]计算着色器[/url],所以我没有任何说明。
根据其距离相机,一个对象将较低或higher-poly网,或不画。
例如,超过一定距离的草或花从来没有呈现。所以这一步计算每个对象如果它将呈现的LOD.
这实际上是管道不同PS3(缺乏计算着色器支持)和PC或PS4:在PS3上所有这些计算必须在细胞或spu上运行。
G-Buffer代
这里发生的“主要”呈现。所有可见网格绘制一个接一个,而是立即计算阴影,绘制调用只是一些shading-related信息输出到不同的缓冲区G-Buffer。侠盗猎车手V使用[url=]捷运[/url]所以每个画调用可以输出到5渲染目标。
后,所有这些缓冲区相结合来计算每个像素的最终阴影。因此得名“递延”反对“转发”的每个画调用计算最终的阴影像素的价值。
这一步,只绘制不透明的物体,透明的像玻璃网格需要特殊治疗的递延管道和将在稍后处理。
G-Buffer代:15%





扩散


正常的


镜面


辐照度


G-Buffer代:30%





扩散


正常的


镜面


辐照度


G-Buffer代:50%





扩散


正常的


镜面


辐照度


G-Buffer代:75%





扩散


正常的


镜面


辐照度


G-Buffer代:100%





扩散


正常的


镜面


辐照度



所有这些渲染目标是存贷比缓冲区(RGBA每通道8位)存储不同的信息后参与最后的阴影的计算值。
缓冲区:
  • 漫反射贴图:它存储网格的“固有色”。它代表一个属性的材料,在理论上是不受灯光的影响。但你注意到汽车的引擎盖上的白色亮点吗?有趣的是侠盗猎车手V计算产生的阴影的太阳定向光输出之前扩散映射。
    阿尔法通道包含特殊的“混合”信息(稍后将进行更详细的讨论)。
  • 法线贴图:它存储每个像素的法向量(R,G,B)。alpha通道也使用了虽然我不确定在哪个方向:它看起来像一个二进制掩模对某些植物靠近相机。
  • 镜面映射:它包含相关信息高光/反射:
    • 红色:高光强度
    • 格林:光泽度(平滑)
    • 蓝色:菲涅耳强度(通常是恒定的所有像素属于同一材料)
  • 辐照度地图:红色通道似乎包含每个像素接收来自太阳辐照度(基于像素的正常位置,太阳照射方向)。我不是100%确定绿色通道,但是它看起来像一个光源的辐照度。蓝色是发射属性的像素(零的霓虹灯,灯泡)。大多数不使用alpha通道除了标记像素对应于人物的皮肤或植被。
所以,我之前在谈论同时输出到5渲染目标,但我只给4。
最后呈现的目标是一个特殊的depth-stencil缓冲区。这就是它看起来像这个月底通过:

深度


钢网


  • 深度地图:它存储每个像素的相机的距离。
    直觉你所期望的像素是白色(1)深度和更紧密的像素暗。这并非如此:侠盗猎车手V似乎使用[url=]对数Z-buffer[/url],扭转z为什么这样做?由于他们的编码方式,浮点数精度更接近0时。这里,扭转Z导致更精确存储非常遥远物体的深度,因此大大减少了[url=]Z-fighting[/url]考虑到长画距离比赛的技巧是必要的。这是[url=]没有什么新鲜的[/url]不过,《正当防卫2》为例使用类似的技术吗.
  • 模板:它是用于识别不同的网格,将相同的ID分配给某个类别的所有像素网格。例如,一些模板值:
    • 0x89:玩家控制的角色
    • 0x82:车辆由球员
    • 0x01:npc
    • 0x02:车辆喜欢汽车,自行车…
    • 0x03:植物和树叶
    • 0x07:天空

所有这些缓冲区生成大约在1900年绘制调用。
注意现场呈现“前后”,这是一种优化呈现由于“早期Z拒绝”:现场了,越来越多的碎片深度测试失败了,因为他们都被我们仔细像素画。当已知像素的深度测试就会失败,GPU可以自动丢弃它甚至没有执行像素着色器。当你有沉重的像素着色器,渲染(或“颠倒”[url=]画家的算法[/url])是最坏的选择属性,另一方面“前后”是最优的。
小的题外话现在,来解释漫反射贴图的alpha通道的作用。看一看下面的截图:

变焦漫反射贴图

你注意到一些像素失踪吗?尤其可见的树木,就像他们的精灵缺乏一些texel。
我注意到这些工件在PS3上几次,我当时感到困惑。可能是混叠当纹理雪碧真的很小吗?我现在可以看到他们都是mip-mapped正确它不是这样。
这种模式是特定的,像一个棋盘,有没有可能…游戏跳过1出2像素的渲染吗?
确保,我看着D3D字节码。当然,这是在这里:
片段着色器总成
dp2r1.y,v0.xyxx,l(0.5,0.5,0.0,0.0)// Dot product of the pixel's (x,y) with (0.5, 0.5)frcr1.y,r1.y// Keeps only the fractional part: always 0.0 or 0.5ltr1.y,r1.y,l(0.5)// Test if the fractional part is smaller than 0.5


分散的Alpha通道


所有这些指令只是相当于测试(x + y) % 2 == 01出2像素总是通过。(x和y是像素的坐标)
这只是几个条件导致丢弃一个像素之一(另一个是拥有一个α< 0.75),但这已足以解释抖动模式。
记住哪些网格绘制在这种“犹豫模式”,信息存储在阿尔法通道扩散的地图,这看起来像右图。
为什么一些模型画呢?可能是为了节省不仅或阴影计算?不是因为gpu没有这样的粒度:2 x2的像素阴影在广场,而不是个人。这不是关于性能,它是关于LOD转型:这种抖动模式使不透明的网格看起来有点透明的钟表之间的过渡。
这种技术实际上是调用[url=]α点彩[/url].
阴影
游戏中使用CSM(级联阴影地图):4阴影生成映射到一个1024 x4096纹理。每一个阴影映射为不同的创建相机平截头体,截头越来越大,包括更高的部分场景随着迭代。这确保球员附近的阴影存储有更高的分辨率,而阴影更远更少的细节。这里的深度信息的概述4地图:

阴影地图

这一步可能会有一个高成本自现场需要重现的4倍,但frustum-culling避免呈现不必要的多边形。这里的CSM代是大约在1000年绘制调用实现的。
从这个深度信息,我们可以计算每个像素上的阴影。引擎影子信息存储在一个渲染目标:太阳阴影的定向光在红色通道,投下的大气中的云是红色和绿色通道。
阴影地图是采样抖动模式(如果你仔细看看下面的纹理,红色通道显示一些checkerboard-like工件),这是让影子边界平滑。
这些工件然后纠正:太阳阴影和云阴影被组合到一个缓冲区,执行一些depth-aware模糊结果存储到镜面的alpha通道地图。

太阳阴影(绿色色调)
云阴影(灰色色调)




模糊的影子



注意模糊操作:它非常昂贵,因为它需要从多个纹理做很多水龙头。为了减轻负载,在执行模糊之前,创建一个“早期”结构:影子缓冲1/8th缩减规模,和一个轻量级的模糊是由像素着色器4要求[url=] Gather()[/url]。这能给一个大致的估计像素完全点燃。当执行完整的depth-aware模糊,第一步在于阅读本“早期”缓冲:如果当前像素似乎完全点燃了像素着色器立即输出1,跳过所有沉重的模糊计算。
平面反射贴图
我不会去太多细节由于反射解释更多的细节[url=]第2部分[/url]在这个场景效果几乎不可见,但这一步生成海洋表面的反射贴图。
基本上现场再次吸引(650年绘制调用)为一个小小的240 x120纹理,但“倒转”,出现像水面上的倒影。
屏幕空间环境闭塞
一个线性版本的计算深度缓冲,然后从它[url=]SSAO[/url]创建地图。

生成第一个嘈杂的版本,然后depth-aware模糊是应用于2连续传球(横向和纵向)来消除结果。

所有的工作已经完成一半的原始分辨率以提高性能。

SSAO地图(噪声)



SSAO地图(模糊)




G-Buffer组合
时间终于将所有这些缓冲区已生成!
一个像素着色器获取来自不同的缓冲区的数据和计算最终的阴影像素值在HDR。
的夜景,灯光和辐照度现在也会添加一个接一个的现场。

扩散


正常的


高光+阴影


辐照度


深度


钢网


SSAO


反射




结合G-Buffers

它开始成形好,虽然我们仍然失踪的海洋,天空,透明物体…
但首先,迈克尔的外观需要加强。
地下散射
SSS(前)



SSS(后)




迈克尔的皮肤的材质有点:脸上有非常黑暗的区域,如果他的身体是厚厚的塑料而不是肉做的。
这就是为什么通过[url=]瑞士[/url]被执行时,模拟传输的光在皮肤内。后看他的耳朵或嘴唇:瑞士光现在出血穿过他们,给了一个红色的色彩这正是你会在现实世界里发生。
瑞士只应用于迈克尔?第一只提取他的轮廓。这是可能由于模板缓冲区生成:迈克尔的所有像素的值0x89。所以我们可以得到迈克尔的像素,不错,但我们想SSS只适用于皮肤,而不是衣服。
实际上,所有G-Buffers结合时,除了阴影数据存储在RGB,一些数据被写入到alpha通道。更准确地说,辐照度映射和镜面映射alpha通道被用来创建一个二进制掩码:像素属于迈克尔的皮肤和一些植物在alpha通道设置为1。其他像素的衣服有一个α0。
所以瑞士可以通过提供应用作为输入简单组合G-Buffer目标和depth-stencil缓冲区。
现在,你可能会认为这相当于很多计算只是一个微妙的,当地的改进。你是正确的,但不要忘记,当玩游戏时,作为人类我们本能地倾向于看人物的脸很多改进——任何渲染的脸是一个很大的胜利的感觉浸。在游戏中SSS应用于你的性格和npc。
这一幕,但仍没有多少水,我们海洋,一些游泳池。
侠盗猎车手V渲染的水处理[url=]反射[/url][url=]折射[/url].
对数Z-buffer先前创建用于生成第二个版本:线性这一次,在一半的分辨率。
海洋和池是一个接一个地在捷运模式下,输出几个目标:

水分散


水不透明度


  • 水分散地图:内在的水的颜色。
  • 水不透明度映射:红色通道似乎储存一些水的不透明属性(例如海洋永远是0.102,池总是0.129)。绿色通道存储像素有多深的水面(深像素更不透明的水扩散映射的一个强有力的贡献,而水浅像素几乎是透明的)。
    注意,所有池是无条件地呈现,即使他们最终隐藏在另一个网格在现场,他们都出现在红色通道。然而,对于绿色通道只计算像素真的可见,唯一的“水”像素,使它成为最终的图像。
我们现在可以把前面的缓冲区创建和生成一个折射地图:

水折射地图


在这种折射地图,池注满水(蓝的水越深),[url=]焦散线[/url]还补充道。
我们现在可以进行最终渲染的水:再一次的所有网格海洋,池表面绘制一个接一个,但这一次一起结合反射和折射,有一些凹凸映射到扰乱表面法线。

平面反射


折射


凹凸贴图




水(前)



水(后)



大气
光轴


一个[url=]light-shaft[/url]地图创建-也称为“体积阴影”:它的作用是使大气/雾并不是直接由太阳照射。
地图生成分辨率的一半,由ray-marching每个像素和评估对太阳阴影地图。
获得了第一次吵的结果后,缓冲区是模糊的。
下一步由雾效果添加到我们的场景:它方便隐藏缺乏低多边形建筑在远处的细节。
这从light-shaft通过读取地图(在这张照片几乎没有影响)和深度缓冲输出雾信息。
然后天空呈现,其次是云。

基地



基地+雾



基地+雾+天空



基地+雾+天空+云



天空穹顶


天空是呈现在一个画叫:所使用的网格是一个巨大的圆顶覆盖整个场景。(见右边)
这个步骤使用作为输入一些纹理相似[url=]Perlin的噪音[/url].
云渲染&#65533;&#65533;&#65533;类似的方式:大网格,戒指的形状,呈现在地平线上。一个法线贴图和一个密度地图用来渲染云:这些都是巨大的2048 x512纹理,这也是无缝(他们在左右循环)。


云密度


云正常


透明的物体
这个步骤呈现透明物体的场景:眼镜,挡风玻璃,周围的尘埃粒子飞行…

透明的对象(前)



透明的对象(后)



这一切仅在11个draw-calls执行,实例化粒子被大量使用。
犹豫不决平滑
还记得我们[url=]小的题外话[/url]以前一些树木在犹豫扩散地图吗?
是时候解决这些构件:像素着色器执行后处理效果,阅读的原始颜色缓冲区和alpha通道扩散地图,知道哪些像素一直犹豫不决。2邻居对于每一个像素,像素可以采样来确定最终的“平滑”颜色值。

平滑(前)



平滑(后)



这是一个很好的技巧,因为只有一个通过形象是“治愈”:成本是不变的,它是独立于场景中的几何量。
注意这个过滤器虽然并不完美:PS3和电脑屏幕上我注意到一些棋盘模式没赶上在某些情况下,过滤器。
色调映射和开花
我们的渲染图像直到现在已经存储在HDR格式:每一个RGB通道存储为一个16位的浮点数。这允许有巨大的光强度的变化。但是显示器不能显示如此高的价值,他们只输出每通道8位RGB颜色。
[url=]色调映射[/url]在于将这些颜色值从一个HDR异地恋的空间。有[url=]几个函数存在一系列映射到另一个[/url]。一个是广泛使用的经典莱因哈德我实际上是一个用于生成所有之前的截图,它给结果接近游戏的最终呈现。
但GTA V真的使用莱因哈德?又时间来扭转一些材质字节码:
片段着色器总成,色调映射
// Suppose r0 is the HDR color, r1.xyzw is (A, B, C, D) and r2.yz is (E, F)mulr3.xy,r1.wwww,r2.yzyy// (DE, DF)mulr0.w,r1.y,r1.z//  BC[...]divr1.w,r2.y,r2.z// E/F[...]madr2.xyz,r1.xxxx,r0.xyzx,r0.wwww// Ax+BCmadr2.xyz,r0.xyzx,r2.xyzx,r3.xxxx// x(Ax+BC)+DEmadr3.xzw,r1.xxxx,r0.xxyz,r1.yyyy// Ax+Bmadr0.xyz,r0.xyzx,r3.xzwx,r3.yyyy// x(Ax+B)+ DFdivr0.xyz,r2.xyzx,r0.xyzx// (x(Ax+BC)+DE) / (x(Ax+B)+DF)addr0.xyz,-r1.wwww,r0.xyzx// (x(Ax+BC)+DE) / (x(Ax+B)+DF) - (E/F)

嗯嗯嗯…我们这里有什么?
(x(Ax+BC)+DE) / (x(Ax+B)+DF) - (E/F)是典型的方程[url=]tonemapping运营商约翰检使用[/url]2009年在顽皮的狗。这是一个电影tonemapping技术[url=]由Haarm-Pieter小羚羊[/url]2006年,在EA。
原来GTA V不使用Reinhard但未知2运营商也冲淡不了黑色区域。
异地恋的过程将是如下:
  • HDR缓冲区是缩减规模&#188;的决议。
  • 计算着色器是用来计算的平均亮度缓冲区,输出结果1 x1纹理。
  • 新接触计算,控制亮/暗的场景出现。
  • 明亮的缓冲

    bright-pass滤波器用于仅提取像素有一个亮度高于某个阈值(暴露)决定的。
    在这一幕只有几个像素生存过滤器:一些地方有很强的反射亮度的汽车。

  • 布鲁姆

    亮度缓冲一再缩减,模糊到原始大小,百亿资金,然后再高档几次,直到它到达原始大小的一半。

  • 布鲁姆被添加到原来的HDR像素然后未知2 tone-map运营商将颜色转换为异地恋,同时应用伽马校正,使得线性空间的sRGB空间。
最后的结果在很大程度上取决于暴露。这里有一些例子说明该参数的影响:
低暴露
媒体曝光
高曝光


接触实际缓慢进化后帧,有永远不会突然改变。
这是为了模拟人眼行为:你有没有注意到开车后在一个黑暗的隧道,突然退出阳光的环境下在几帧看起来太亮?然后逐渐从“致盲”回到“正常”,而曝光调整到一个新的价值。似乎GTA V甚至也给“暗→明亮”转换更快的接触适应比“亮→暗”,就像人类的眼睛的行为。
抗锯齿和镜头畸变
如果使用反锯齿的方法[url=]FXAA[/url],现在的锯齿状边缘平滑网格执行的。
然后,模拟一个真实的摄像头,一个[url=]透镜畸变[/url]上执行图像通过使用一个小的像素着色器。它不仅扭曲了的形象,也介绍了小[url=]色差[/url]在画面的边缘,微微扭曲更多红色通道相比,绿色和蓝色的。

透镜畸变(前)



透镜畸变(后)



用户界面
最后联系:UI,它仅仅包含在小地图上显示屏幕左下角的角落。地图是分为若干正方形瓷砖,瓷砖的引擎只吸引组可能会显示在屏幕上。每通过一个draw-call瓷砖画。我彩色的瓷砖,这样你就可以看到更好的结构:

小地图

启用了剪刀测试只允许呈现在左下侧的角落,抛弃一切之外。所有的道路矢量化的线框图(见截图),它们呈现为网格,可以在几乎任何看起来不错的缩放级别。
小地图上显示然后卷入主要图像缓冲区,和几个小图标和小部件添加顶部。
好吧,用了一段时间,但这里有:最后一帧的荣耀!
总之有4155电话,1113材质和88年呈现目标。

UI(前)



UI(后)



还想知道更多吗?去[url=]第2部分- LOD和反思[/url].


还没有设置签名!您可以在此展示你的链接,或者个人主页!
使用道具 <
billxu8888  发表于 2018-8-2 09:52:46  
2#
回复 收起回复
使用道具
火炉啊1  发表于 2018-8-2 10:20:46  
3#
回复 收起回复
使用道具
HueCain  发表于 2018-9-20 15:00:28  
4#
大佬  不好意思  我看不下去了
回复 收起回复
使用道具
Ovan  发表于 2018-10-16 02:28:34  
5#
好长,先mark
回复 收起回复
使用道具
changtexiao  发表于 2018-10-16 09:16:52  
6#
666
回复 收起回复
使用道具
┌.┌锋/shui  发表于 2018-10-16 16:01:44  
7#
元素帖子强,满满正能量!
回复 收起回复
使用道具
倪月神似  发表于 2018-11-14 07:57:47  
8#
感谢分享
回复 收起回复
使用道具
youbobi  发表于 2018-11-15 09:59:33  
9#
挺不错的。
回复 收起回复
使用道具
qq_……_BzI  发表于 2018-11-15 10:14:32  
10#
111111111111111111
回复 收起回复
使用道具
qq_衔蝉_wcS  发表于 2018-11-21 00:10:09  
11#
想要成大触,天天上元素
回复 收起回复
使用道具
Shiva希瓦  发表于 2018-11-21 09:16:07  
12#
不错哦
·~
回复 收起回复
使用道具
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表