游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2956|回复: 0

《荒野大镖客2》的大气云雾技术

[复制链接]

1万

主题

1万

帖子

3万

积分

论坛元老

Rank: 8Rank: 8

积分
36572
发表于 2020-3-26 10:26:15 | 显示全部楼层 |阅读模式
作者:安柏霖 腾讯互动娱乐 工程师

1.jpg

技术一直行业领先,但是一直低调的Rockstar,终于在SIGGRAPH 2019放了大,做了《荒野大镖客2》(大表哥2,Red Dead: Redemption II)中的大气云雾技术分享。

看得也是近几年最过瘾的一篇了,high点:

  • 是发售游戏中实际使用的、完整的、系统化的技术合集
  • 代表当前最强的大气系统
  • 技术探索&整合nice,积累深厚,运用纯熟
  • 理论、实际开发已经性能优化有很好的平衡,堪称R&D的典范


motivation & overview

这也是很多优秀工作室做事的一个方法,在处理开创性事情的时候,就会列出一些依据来进行“合理突破”。

这里笔者也是深有共鸣,是一个很有章法的做事方式。

Rockstar这里就包括:

2.png

  • 在《荒野大镖客1》中已经有了不错的大气系统,而且这个确实很重要,当然要在2中进一步发展。
  • 受到一些名画的启发,笔者也是在看一些绘画,去一些景色壮观的地方都会带来很强的创作冲动(虽然我是写程序)。
  • 以及基础的atmosphere scattering系统中,现在确实还有很多可以完善的地方。


通篇是分成data model、render、scene integration三个部分。

data model


3.png

这部分是一个知难行易的模块,所以直接列下特性和做法。

  • 云的分布


这块比较类似Horizon Zero Dawn的做法:

https://blog.csdn.net/toughbro/article/details/48844649

4.png

使用分布图来定义云的整体分布:

5.jpg
[ 出来效果这样的,同时可以有多层的云 ]

  • 雾的分布


类似云的分布,雾也是有一个分布:

6.jpg
[ 没有fog map的版本 ]

7.jpg
[ 有fogmap的版本 ]

  • 云的形状定义


这块参考的15年的Horizon Zero Dawn的做法:

https://blog.csdn.net/toughbro/article/details/48844649

基本原理差不多,有一些自己的特色:

8.png

这里定义云的形状:

  • 1个lut定义云的厚度
  • 1x3d noise,2x2d displacement


效果目测要比Horizon Zero Dawn的好一些。

render

接下来我们看第二部分,这部分主要谈渲染部分,包括scattering和lighting的render,相对内容也多一些。

可以说这部分是本篇重点所在。

9.jpg

  • voxel+raymarching


10.png

处理大气效果时候,为了兼顾近处的精度和场景的宏大,使用了混合方案:

  • 近处使用voxelization的方式,得到高精度的渲染结果,reference了刺客信条的一个文章:


https://blog.csdn.net/toughbro/article/details/46706837

  • 远处使用rayMarching的方式,平衡效果和效率


光照模型


11.png

这里最终的光照模型,使用这样的公式列出来,这个比较像大家所熟悉的PhysicallyBasedLighting中的macrofacet公式的模样,其中三项如下:

  • P:phase的缩写,是光通过media时候的scattering的情况
  • V:visibility,我们可以近似理解成shadow类的东西
  • L:lighting,也就是光源,直接光,ambient lighting等等


  • phase项

12.png



这里分成两个层级:

1、基础phase模型,是基于Henyey-Greenstein phase function(简称HG),这个模型对于single forward scattering处理的比较好。

2、多种scattering组合,基于上面的擅长处理single forward scattering的HG(heney-greenstein)模型。

3、==使用多级HG模型来模拟multi scattering

4、==使用一个clamp操作来模拟back scattering

这里稍微贴下HG模型的样子:

13.png

这里g项是[-1,1]之间,代表从back scattering到forward scattering的情况,表示media的属性。

theta就是各个角度,phase function就是关于角度的函数么。

HG函数这部分还是比较物理的,但是multi scattering部分就是比较变通了,是多级HG来模拟multi scattering,各级之间的权重由美术定义。

然后给定g,关于theta就可以预计算出来,放到LUT(look up tabble)贴图中:

14.png

最后放在一起的效果:

只有1级HG function的时候:

15.jpg

2级HG function模拟multi scattering+back scattering:

16.jpg

  • “physically based"的度和变通


这里也是涉及到一个“physically based"的程度问题,原则上我们是要physically based这样会尽可能的物理化,好处现在PBR已经论证的非常好了。

但是实际开发中,我们会遇到各种需要折中的地方,或许是物理模型不够好,或许计算过重等等。

这时候,none-physically-based就还是需要了,这时候建议是,尽可能在高层去做hack和变通,保持底层原子项部分的“physically based"正如phase function这里,底层是HG function,高层是美术来指定的函数。

  • visibility项

17.png



这一项就是光照信息中间被遮挡的情况,和直接光照有点不一样的是,由于这个是一个scattering的过程,所以完整来讲是光线一路射过来中间每一步的visibility情况的叠加。

18.png

落实到实际计算中,就是ray marching中间每一步的visibility情况的叠加。

这里visibility主要针对影响大的两个case:terrain、cloud来做计算。

terrain使用raymarching的方式构建一个shadowmap信息;

cloud使用exponential shadow map的方式,来encode shadow map信息,来达到非常软阴影的信息,一共存了6mips(esm的使用在刺客信条的文章里也有)。

  • lighting项


19.jpg

ambient lighting部分:

  • 远处的ray marching部分,就是sky ambient,把sky scattering存到低精度的paraboloid贴图里面
  • 近处的frustum voxelization部分,sky light+light probe lighting*AO


20.jpg

local light 部分,直接就读light cluster volume。

21.jpg

  • froxel


froxel也是技术创造的名词:这个的缩写frustum voxel;

22.png

也是用voxel的形式,存储低精度的场景volume信息,然后用于低频信息渲染,比如scattering;

《荒野大镖客2》中的存了三种信息:

  • shadow
  • material
  • lighting (结合前两者来计算)


23.png

shadow volume,注意这个不是阴影算法的shadow volume,就是存放shadow的volume信息,包括了普通shadow和cloud shadow;

中间使用了temperal filtering来处理稳定的问题;

24.png

material volume,各种材质信息,也带上了wind交互等等(让我想起了战神的风力存在volume中)。

也有temperal filter。

  • ray marching


25.png

可能有的读者对ray marching还不是特别熟悉,ray marching特别常用于volume类的渲染中,鉴于一些计算硬件和数据的限制,有些情况难以很容易的使用ray trace的方式寻找交点,比如local reflection中要对depth buffer找交点。那么就用步进的方式来找交点,这种方法就是ray marching;这里的步长的选择是应用ray marching的时候需要具体斟酌的地方。

26.png

回到《荒野大镖客2》,ray marching的步长策略选择也是颇费心思:

  • 考虑到场景深度、ground plane、cloud dome
  • 另外要仔细考虑到云层的厚度信息


即便这样也很容易跳过比较薄的云层。

  • ray marching优化


先看下最终的性能

27.png

可以看到ray march是占据着性能的大头,而且这还是经过优化过之后的结果。

这里优化就基于两个大的策略:low resolution + temperal,也就是在低分辨率上做raymarch计算,然后通过多帧来重建。

这个部分很精彩,我们多展开。

28.png

这里raymarch的起点是在froxel的末端,带上blue noise(可以理解成一个频率较高的noise了,感兴趣可查下)做偏移。

半分辨率大小,然后分4帧来计算。

  • raymarch reconstruct


29.png

由于是分4帧来构建,所以每帧只能raymarch 2x2 像素中的一个,另外三个就要从history buffer中拿。

这里用了temperal相关的很多做法,一些在taa中颇为常见。

1、使用了3x3像素color aabb clamp的方式

2、大的深度断裂的地方,临接像素就不考虑了

3、在深度断裂(depth discrepancies)的地方,放更多的ray

这里能正确的判定出来depth discrepancy还是比较棘手的,要做的事情就是在6x6(2x2 ray, 3x3 neighbouhood, 所以一共6x6)像素中,正确的识别depth的min/max;

尝试1,uniform分布

30.png

可以看到在frame2里面,min/max就错了,这个会导致误判。

尝试2,checkerboard方式

能处理的case好很多:

31.png

但是这种情况下还是不行:

32.png

总之局部的分布策略总是有cover不住的情况了,还是要引入整体的信息才行。

尝试3:checker board+depth neighborhood analysis

先是拿到3x3tile(每个tile是2x2像素)的depth min/max,然后每一个tile中和其余的8个点比,如果其余的8个都是min,那么这个就取一个max depth的点。

  • up scaling

33.jpg


34.png



up scale这里是4taps dither,depth连续就平均,不连续就取最近

  • 效率


35.png

长的raymarch部分是最消耗的。

36.jpg

scene integration

第三部分,integration,也就是把计算好的光照等和场景集成起来。

37.jpg

这里是一个integration完整的示意图,我们接下来可以一步步看看。

sky scattering

sky scattering算法上是Precomputed Atmospheric Scattering,三个特点:

  • 考虑了earth shadow
  • 分帧实时更新的
  • 存放在32x16x32的LUT中


38.png
[ 用于sample sky scatter的深度信息 ]

在sample sky scattering信息的时候,就不是raymarch每一步都踩了,否则虽然更加正确,但是太费了。

最终按照depth信息,就依据depth来sample一次。

39.jpg
[ visibility信息 ]

然后visibility信息(类似shadow)信息都是分离的。

放在一起的效果:

40.jpg

  • 光照组成


把前面列的放在这里:

  • frustum volume lookup
  • ray march result
  • sky scattering / transmittance


  • sky irradiance probe


41.png

地图里32x32的3rd order spherical harmonics probe map, 每个probe覆盖(256mx256m),这个用作sky irraidance probe。

总结

ppt本身的总结是有这么几条:

  • volumetric效果是“一等公民”
  • 这是一个统一,基于物理,支持多种材质的scattering/transimitance系统
  • 近处是frustum align的volume based技术
  • 远处是raymarch based的技术


个人的阅读总结:除了第一篇的high点之外,有几点印象非常深刻

  • 对大量的渲染技术运用的如此纯熟灵活,非常给力
  • 能够hold住如此复杂的系统,非常给力


研发的本原的样子

一系列的笔记,可能是解读技术文章以来最多的一次了,笔记部分基本上是大家看了原文之后大致能记住的部分,实际上原文涵盖的内容要更多更杂,然后这背后还有更多的探索和尝试,因为篇幅的原因没有写出来。

读的时候完全没法像一些论文,尤其是少项目而重理论和demo向的,可以简单的做抽象和总结,可以“一句话说清楚”。

实际像《荒野大镖客2》这样的项目,这个就是研发中所面临的问题,理论掺杂着妥协与变通(hack),并且要覆盖极高的复杂度。

实际做的时候,宏观的视野?是的;扎实的理论?是的;扎实的engineering?是的;充分的耐心?是的;灵活的变通?是的;

像我个人之前做《天涯明月刀》《无限法则》相关的技术分享,ppt写的时候往往写得“重点突出”、“易听易懂”甚至还带着两个笑话;

而实际上,做项目开发中,就是一个复杂度高的多,繁杂的多的过程,但是那么来写ppt,往往观众会听得云里雾里,所以最终的结果还是“一句话说清楚”。

《荒野大镖客2》,分享者也足够耐心,列了方方面面,包括raymarching中优化的几个失败案例,确实更像研发原本的样子。


来源:腾讯游戏学院
原地址:https://mp.weixin.qq.com/s/a762JlqC3EszLHbylsfhIw

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-12-4 16:48

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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