[siggraph19]《荒野大镖客2》的大气云雾技术(3/4)
froxel
froxel也是技术创造的名词:这个的缩写frustum voxel;
也是用voxel的形式,存储低精度的场景volume信息,然后用于低频信息渲染,比如scattering;
《荒野大镖客2》中的存了三种信息:
- shadow
- material
- lighting : 结合前两者来计算
shadow volume,注意这个不是阴影算法的shadow volume,就是存放shadow的volume信息,包括了普通shadow和cloud shadow;
中间使用了temperal filtering来处理稳定的问题;
material volume,各种材质信息,也带上了wind交互等等(让我想起了战神的风力存在volume中)。
也有temperal filter。
ray marching
可能有的读者对ray marching还不是特别熟悉,ray marching特别常用于volume类的渲染中,鉴于一些计算硬件和数据的限制,有些情况难以很容易的使用ray trace的方式寻找交点,比如local reflection中要对depth buffer找交点。那么就用步进的方式来找交点,这种方法就是ray marching;这里的步长的选择是应用ray marching的时候需要具体斟酌的地方。
回到《荒野大镖客2》,ray marching的步长策略选择也是颇费心思:
- 考虑到场景深度,ground plane,cloud dome
- 另外要仔细考虑到云层的厚度信息
即便这样也很容易跳过比较薄的云层。
ray marching优化
先看下最终的性能
可以看到ray march是占据着性能的大头,而且这还是经过优化过之后的结果。
这里优化就基于两个大的策略:low resolution + temperal,也就是在低分辨率上做raymarch计算,然后通过多帧来重建。
这个部分很精彩,我们多展开。
这里raymarch的起点是在froxel的末端,带上blue noise(可以理解成一个频率较高的noise了,感兴趣可查下)做偏移。
半分辨率大小,然后分4帧来计算。
raymarch reconstruct
由于是分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分布
可以看到在frame2里面,min/max就错了,这个会导致误判。
尝试2,checkerboard方式
能处理的case好很多,
但是这种情况下还是不行:
总之局部的分布策略总是有cover不住的情况了,还是要引入整体的信息才行。
尝试3:checker board+depth neighborhood analysis
先是拿到3x3tile(每个tile是2x2像素)的depth min/max,然后每一个tile中和其余的8个点比,如果其余的8个都是min,那么这个就取一个max depth的点。
up scaling
up scale这里是4taps dither,depth连续就平均,不连续就取最近
效率
长的raymarch部分是最消耗的。
[siggraph19]《荒野大镖客2》的大气云雾技术(3/4)
froxel
froxel也是技术创造的名词:这个的缩写frustum voxel;
也是用voxel的形式,存储低精度的场景volume信息,然后用于低频信息渲染,比如scattering;
《荒野大镖客2》中的存了三种信息:
- shadow
- material
- lighting : 结合前两者来计算
shadow volume,注意这个不是阴影算法的shadow volume,就是存放shadow的volume信息,包括了普通shadow和cloud shadow;
中间使用了temperal filtering来处理稳定的问题;
material volume,各种材质信息,也带上了wind交互等等(让我想起了战神的风力存在volume中)。
也有temperal filter。
ray marching
可能有的读者对ray marching还不是特别熟悉,ray marching特别常用于volume类的渲染中,鉴于一些计算硬件和数据的限制,有些情况难以很容易的使用ray trace的方式寻找交点,比如local reflection中要对depth buffer找交点。那么就用步进的方式来找交点,这种方法就是ray marching;这里的步长的选择是应用ray marching的时候需要具体斟酌的地方。
回到《荒野大镖客2》,ray marching的步长策略选择也是颇费心思:
- 考虑到场景深度,ground plane,cloud dome
- 另外要仔细考虑到云层的厚度信息
即便这样也很容易跳过比较薄的云层。
ray marching优化
先看下最终的性能
可以看到ray march是占据着性能的大头,而且这还是经过优化过之后的结果。
这里优化就基于两个大的策略:low resolution + temperal,也就是在低分辨率上做raymarch计算,然后通过多帧来重建。
这个部分很精彩,我们多展开。
这里raymarch的起点是在froxel的末端,带上blue noise(可以理解成一个频率较高的noise了,感兴趣可查下)做偏移。
半分辨率大小,然后分4帧来计算。
raymarch reconstruct
由于是分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分布
可以看到在frame2里面,min/max就错了,这个会导致误判。
尝试2,checkerboard方式
能处理的case好很多,
但是这种情况下还是不行:
总之局部的分布策略总是有cover不住的情况了,还是要引入整体的信息才行。
尝试3:checker board+depth neighborhood analysis
先是拿到3x3tile(每个tile是2x2像素)的depth min/max,然后每一个tile中和其余的8个点比,如果其余的8个都是min,那么这个就取一个max depth的点。
up scaling
up scale这里是4taps dither,depth连续就平均,不连续就取最近
效率
长的raymarch部分是最消耗的。