Origin
zhuanlan.zhihu.com
Tags
性能优化
渲染
经验分享
开放世界
项目
荒野大嫖客2
收藏夹
创建时间
收藏类型
Cubox 深度链接
更新时间
原链接
描述

froxel

froxel 也是技术创造的名词:这个的缩写 frustum voxel;
notion image
也是用 voxel 的形式,存储低精度的场景 volume 信息,然后用于低频信息渲染,比如 scattering; 《荒野大镖客 2》中的存了三种信息:
  • shadow
  • material
  • lighting : 结合前两者来计算
notion image
shadow volume,注意这个不是阴影算法的 shadow volume,就是存放 shadow 的 volume 信息,包括了普通 shadow 和 cloud shadow;
中间使用了 temperal filtering 来处理稳定的问题;
notion image
material volume,各种材质信息,也带上了 wind 交互等等(让我想起了战神的风力存在 volume 中)。
也有 temperal filter。

ray marching

notion image
可能有的读者对 ray marching 还不是特别熟悉,ray marching 特别常用于 volume 类的渲染中,鉴于一些计算硬件和数据的限制,有些情况难以很容易的使用 ray trace 的方式寻找交点,比如 local reflection 中要对 depth buffer 找交点。那么就用步进的方式来找交点,这种方法就是 ray marching;这里的步长的选择是应用 ray marching 的时候需要具体斟酌的地方。
notion image
回到《荒野大镖客 2》,ray marching 的步长策略选择也是颇费心思:
  • 考虑到场景深度,ground plane,cloud dome
  • 另外要仔细考虑到云层的厚度信息 即便这样也很容易跳过比较薄的云层。

ray marching 优化

先看下最终的性能
notion image
可以看到 ray march 是占据着性能的大头,而且这还是经过优化过之后的结果。
这里优化就基于两个大的策略:low resolution + temperal,也就是在低分辨率上做 raymarch 计算,然后通过多帧来重建。
这个部分很精彩,我们多展开。
notion image
这里 raymarch 的起点是在 froxel 的末端,带上 blue noise(可以理解成一个频率较高的 noise 了,感兴趣可查下)做偏移。
半分辨率大小,然后分 4 帧来计算。

raymarch reconstruct

notion image
由于是分 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 分布
notion image
可以看到在 frame2 里面,min/max 就错了,这个会导致误判。
尝试 2,checkerboard 方式
能处理的 case 好很多,
notion image
但是这种情况下还是不行:
notion image
总之局部的分布策略总是有 cover 不住的情况了,还是要引入整体的信息才行。
尝试 3:checker board+depth neighborhood analysis
先是拿到 3x3tile(每个 tile 是 2x2 像素)的 depth min/max, 然后每一个 tile 中和其余的 8 个点比,如果其余的 8 个都是 min,那么这个就取一个 max depth 的点。
up scaling
notion image
notion image
up scale 这里是 4taps dither,depth 连续就平均,不连续就取最近

效率

notion image
长的 raymarch 部分是最消耗的。 > 本文由简悦 SimpRead 转码