games202:六,实时光线追踪RTRT:Temporal Filtering、联合双边滤波、Outlier Removal、SVGF、RAE

RTRT现状

光线追踪能实现软阴影、反射、ao、diffuse全局光照等接近真实的效果,随着18年NVIDIA的RTX(硬件)架构发布,光线追踪在实时领域也可以进行了。

  • RTX----一种硬件架构,每秒可以计算100亿根光线与包围盒的求交和加速,实际应用中大概每帧可以计算1spp(sample per pixel),但在games101里我们都知道1spp的结果根本不能看,全是noise,而RTRT最关键技术就是通过实时的方法来为1spp的光追结果做降噪。(因此rtx的光追技术并没有变化,重点在denoiseing)
  • 1SPP path tracing = 1 rasterization + 1 ray visibility + 1secondary bounce + 1secondary visibility

下边左图:1spp过程示意;右图:1spp结果+denoiseing
在这里插入图片描述在这里插入图片描述
「注意这里的降噪与DLSS无关,DLSS可以与RTRT同时进行,本质是提高分辨率,不是降噪」

这里的降噪,我们既想要高质量又想要实现实时(<2ms),那很多方法比如:切变滤波(Sheared filtering)系列(SF,AAF,FSF,MAAF)、一些离线滤波(IPP,BM3D,APR……电影用)、深度学习(CNN、Autoencoder—时间不行)等降噪方法就都不适用了。「OpyiX API上用了他们的一个简化版深度学习方法,时间几十ms」因此针对RTRT的降噪很难,我们这节课介绍两种思路:Temporal Accumulation和Spatial Filtering。

实时降噪方法

一,Temporal Filtering时间降噪方法

Temporal Accumulation----时间累积的滤波

  • 核心思路:
    1. 认为前一帧永远是滤波后的结果,并且每帧是连续的
    2. 用motion vectors去寻找上一帧的位置并复用结果
    3. 通过复用等同于增加spp(递归增加,累积多帧的结果)
  • G-Buffer:Geometry buffer,(延迟渲染中获取的)屏幕空间信息,包括深度图、法线、albedo、世界坐标、直接光照结果等。

1,back projection法计算motion vectors

  • 获取屏幕某点世界坐标s:
    1. 在G-Buffer里保存世界坐标s,从屏幕中直接读取
    2. 将屏幕空间的某点坐标加上深度坐标,用公式变换到世界坐标 s = M − 1 V − 1 P − 1 E − 1 x s = M^{-1}V^{-1}P^{-1}E^{-1}x s=M1V1P1E1x,相当于MVP的逆运算,其中E是viewport变换,x是屏幕坐标
  • 计算该点在上一帧的世界坐标: s ′ = T − 1 s s' = T^{-1}s s=T1s,这里的T是上下帧的世界坐标的变换
  • 获取该点在上一帧的屏幕坐标 x ′ = E ′ P ′ V ′ M ′ s ′ x' = E'P'V'M's' x=EPVMs
    「与光流法不同,光流是仅凭两帧结果的内容找对应,本方法是计算的对应,绝对真实;并且光流速度也不行」

2,将上一帧与当前帧结果线性混合

C ˉ \bar C Cˉ表示已经滤波过的, C ~ \widetilde C C 表示还没滤波」

C ˉ ( i ) = F i l t e r [ C ~ ( i ) ] \bar C^{(i)} = Filter[ \widetilde C^{(i)}] Cˉ(i)=Filter[C (i)](空间降噪)
C ˉ ( i ) = α C ˉ ( i ) + ( 1 − α ) C ˉ ( i − 1 ) \bar C^{(i)} = α\bar C^{(i)} + (1-α)\bar C^{(i-1)} Cˉ(i)=αCˉ(i)+(1α)Cˉ(i1)(时间降噪)
「一般α=0.1~0.2,也就是大部分用上一帧的结果」

最终效果如下图。「注意:滤波不会改变能量守恒,降噪前的图看起来暗是因为显示器将结果clamp到0-1了,如果是HDR显示器结果不会这么暗。」

在这里插入图片描述在这里插入图片描述

算法缺陷/问题temporal failure

  1. Switching Scenes:如果切换场景或者灯光、镜头(电影转场)等突然变化,本方法需要先累积一些“上一帧结果”,那第一帧显然效果就不好,

  2. Screen Space Issue:本帧物体点在上一帧没有或超出屏幕范围了,比如经典的walking backwards in a hallway后退走、disocclusion上一帧被遮挡的物体本帧突然出现等,会出现legging的问题,如下图
    在这里插入图片描述

  3. Shading Failure:对于静态物体动态shading的情况,由于motion vector为0,阴影和反射等常常会滞后产生拖尾现象(detached shadows),如下图光源改变阴影错误及物体移动,地面反射滞后。
    在这里插入图片描述在这里插入图片描述

缺陷解决方法

  1. clamping:当上一帧的结果与当前帧差距过大时,把上一帧结果clamp到当前帧结果的近似处(类似均值方差小范围误差内),再做混合。
  2. detection:加一步检测以确定是否使用上一帧的结果。给场景中物体的加一个Object ID以区分颜色,如果ID突变,则判定出现temporal failure,这时去调整α(可以选非0即1,也可以根据id的值调整系数)。但这样会重新引入噪声(之前的累积没用上了),如下图。
    在这里插入图片描述

二,Spatial Filtering 空间降噪方法

上边讲了时间降噪的方法,但空间降噪还没讲,本节就是空间降噪的方法。 C ˉ ( i ) = F i l t e r [ C ~ ( i ) ] \bar C^{(i)} = Filter[ \widetilde C^{(i)}] Cˉ(i)=Filter[C (i)]里的Filter,滤波核是K。

对于RTRT的应用场景噪音多是高频信息,因此低通滤波就可以,最简单的是使用高斯滤波,但高斯完的图像边缘也变糊了,损失了部分有用的高频信息,由此我们引入更复杂的滤波核。

2.1 bilateral filtering双边滤波

核心思路:颜色变化大的地方认为是边界、贡献越小。
公式如下,与高斯滤波核相似,只是加入了颜色权重,其中 I ( ) I() I()是像素颜色:
在这里插入图片描述

  • 效果:
    在这里插入图片描述
  • 然而事实上,颜色差异大不能区分两点是在边界还是噪声,这是双边滤波的固有问题,到SVG部分讲解决方法。

2.2 Joint/Cross bilateral filtering联合双边滤波

  • 高斯滤波权重----像素距离;
  • 双边滤波权重----位置距离+颜色差;
  • 联合双边滤波权重----G-buffer信息(不采样光栅化免费得到并且没有噪音)辅助加权(用什么信息可以主观设置—记得归一化,深度、法线、坐标、object id、颜色等都行)+ 任何距离衰减函数(高斯、cos、Exponential等都行)

在这里插入图片描述

  • tips:
    1. G-buffer的每个信息由其对应的σ控制重要程度,需要调参(不黑盒)
    2. G-buffer的信息怎么用没有标准,有时需要探索一个合理的指导维度

2.2.1 滤波核优化加速

  • Separate Passes:滤波核本来是NxN大小,但全遍历一次开销大;可以把滤波核拆分至水平和竖直方向的两个一维滤波核,改为遍历2*N次。「注意只有高斯核可拆分,其他滤波核有损失,不过半径小(小于32)的话也看不出来」

∫ ∫ F ( x 0 , y 0 ) G 2 D ( x 0 − x , y 0 − y ) d x d y = ∫ { ∫ F ( x 0 , y 0 ) G 1 D ( x 0 − x ) d x ) } G 1 D ( y 0 − y ) d y \int\int F(x_0,y_0)G_{2D}(x_0-x,y_0-y)dxdy = \int \{\int F(x_0,y_0)G_{1D}(x_0-x)dx)\}G_{1D}(y_0-y)dy ∫∫F(x0,y0)G2D(x0x,y0y)dxdy={F(x0,y0)G1D(x0x)dx)}G1D(y0y)dy

  • ****:

  • Progressively Growing Sizes(A-Trous Wavelet):把一个核拆成多个小核做多pass计算,这些小核逐步增长滤波步长间隔

在这里插入图片描述
在这里插入图片描述
在这个方法下,采样间隔是2的i次方可以不发生“走样”,原因是在第2个pass上的采样间隔相当于对信号进行搬移,正好搬移的间隔就是上一次pass留下来的最高频率(右图),然后再一次滤波。
在这里插入图片描述)

  • tips:
    1. 快速傅里叶变换在GPU优化很差,不如cpu速度,不如咱们讲的这两种优化
    2. 实际中常常第一个pass是不太干净的,导致之后的搬移也有点问题,可以最后再做一次小滤波

增加G-buffer信息又会增加计算量,因此需要对滤波核进行优化。

2.3 Outlier Removal 噪点移除(and temporal clamping)

Outlier指采样中出现的一些亮度极其高的噪点,滤波后它的亮度会贡献到周围导致形成亮斑,所以应该在滤波前使用clamp的方式将这些Outlier去除。(去除后能量不守恒,但也这么做了)。

  • 具体方法:

    1. 对每个像素取周围7x7的均值μ和方差σ
    2. 取一个范围比如 [ μ − k σ , μ + k σ ] [μ-kσ,μ+kσ] [μ,μ+],k取1~3,认为这个范围外的样本是异常的
    3. 把异常值clamp到上述区间内
  • tips

    1. 对于第一节的Temporal Filtering里的clamp也采用这种办法, C ( i ) = α C ˉ ( i ) + ( 1 − α ) C ( i − 1 ) C^{(i)} = α\bar C^{(i)} + (1-α)C^{(i-1)} C(i)=αCˉ(i)+(1α)C(i1)—> c l a m p ( C ( i − 1 ) , μ − k σ , μ + k σ ) clamp(C^{(i-1)},μ-kσ,μ+kσ) clamp(C(i1),μ,μ+)(把上一帧结果clamp到当前帧)
    2. 工业界的clamp会更复杂,可能在某种颜色空间上进行,并且范围可能是3d的颜色空间等----TAA的实现
    3. 为避免很小的光源被去掉,可以前渲染没有光源的场景再加光源

2.4 Spatiotemporal Variance-Guided Filtering(SVGF)时空差异引导滤波

SVGF比上述的时空降噪又多了偏差分析等内容。(也是联合双边滤波)
3 factor-Guided filtering:

  • 1,深度
    w z = e x p ( − ∣ z ( p ) − z ( q ) ∣ σ z ∣ ∇ z ( p ) ⋅ ( p − q ) ∣ + ε ) w_z = exp(-\frac{\vert z(p)-z(q) \vert}{σ_z\vert \nabla z(p) \cdot (p-q) \vert + ε}) wz=exp(σz∣∇z(p)(pq)+εz(p)z(q))
    分母的 ε ε ε是防止除0用, σ z σ_z σz是控制深度的影响程度。 ∇ z ( p ) \nabla z(p) z(p)是指深度的梯度(沿着法线、垂直法线),这样如果两点有深度差异但实际在同一个侧面时(下图),可以通过分母减少深度差异带来的权重。
    在这里插入图片描述

  • 2,法线
    w n = m a x ( 0 , n ( p ) ⋅ n ( q ) ) σ n w_n = max(0,n(p)\cdot n(q))^{σ_n} wn=max(0,n(p)n(q))σn
    σ n σ_n σn是控制法线权重的放大系数。「如果使用法线贴图,则用贴图应用前的法线

  • 3,亮度(luminance)
    w l = e x p ( − ∣ l i ( p ) − l i ( q ) ∣ σ l g 3 × 3 ( V a r ( l i ( p ) ) ) + ε ) w_l = exp(-\frac{\vert l_i(p)- l_i(q) \vert}{σ_l\sqrt{g_{3×3}(Var(l_i(p)))} + ε}) wl=exp(σlg3×3(Var(li(p))) +εli(p)li(q))
    这里的亮度通过颜色得出的灰度判断,但容易受噪点异常干扰,就需要这里的Variance。

  • Variance计算:

    1. 计算7x7内的方差
    2. 按时域的方法,通过motion vector计算上一帧对应像素的方差,取平均(时域上平滑)
    3. g 3 × 3 g_{3×3} g3×3表示在周围3x3内再做一次空间平均滤波

就是spatial filter → temporal filter → spatial filter 从而得到P点精准的variance

问题----会造成over blur

2.5 Recurrent AutoEncoder(RAE)

基于神经网络对蒙特卡罗路径追踪的结果进行reconstruction,在时域上基于Gbuffer和1SPP的渲染图降噪。

如图AutoEncoder(U-Net)加上每层对参数复用,就相当于用了上一帧的结果。至于中间过程是不可知的(但未来发展可能会更好)
在这里插入图片描述
目前rae有了更多发展,但速度还是不足以在RTRT中使用(但这里说明了SIGGRAPH的看重方向,也许是未来大势)
在这里插入图片描述

一些工业界解决方案

三,Anti-Aliasing抗锯齿/反走样

3.1,TAA(Temporal Anti-Aliasing)时域抗锯齿

(先有taa才有上边的时域滤波的,几乎一样的思路)
「抗锯齿的根本解决方案还是要增加采样数」
方法:把每个像素分为4个部分,在每部分的固定位置逐帧轮换采样并复用上一帧上一位置的结果,相当于在时域上把采样率增加了2x2。「注意实际中这里每个部分的采样位置固定比随机效果更好」如果场景物体移动了,如同上边的时域滤波方法----用clamp。
在这里插入图片描述

3.2,MSAA(Multisample)、SSAA(Supersampling)

  • SSAA相当于把场景按照几倍的分辨率采样完了在降采样的方式(暴力采样,效率线性上升)
  • MSAA同一结构体只采样一次,还可以复用采样点,以这种方式增加采样数(游戏里可以设置渲染百分比,120%、200%等,就是MSAA。但代价也大)
    在这里插入图片描述

3.3,image based AA

  • 发展:FXAA->MLAA(Morphological AA)->SMAA(Enhanced subpixel morphological AA)

SMAA原理如下图(和FXAA好像啊),速度大概1ms,效果也不错,工业界常用
在这里插入图片描述
tips:G-buffer千万不能做抗锯齿,应该保留锯齿,因为要保留信息

四,Temporal Super Resolution时域超分辨率

DLSS1.0:信息只有图像,结果全靠猜(提前学一些常见的场景)
DLSS2.0:有Temporal信息(核心思想就是应用TAA)

但DLSS2.0也有问题:如果有temporal failure,则不能clamp了(这样就变得很糊,与超分违背),因此对temporal信息有更高的要求。所以DLSS2.0告诉的其实是“上一帧的对应信息应该怎么用(smarter than clamping)”这点

  • DLSS是NVIDIA的,其他厂商类似功能:
    1. AMD:FidelityFX Super Resolution
    2. Facebook:Neural Supersampling for Real-time Rendering (像DLSS1.0,工业界不用)

五,提升shading效率

5.1 Deferred Shading延迟渲染

延迟渲染是一种节省shading时间的方法。

  • 一般光栅化过程:三角形->fragments->深度测试->着色->像素;在极端情况下每个fragment都要shade一次,复杂度是O(fragment * light)-----因为深度测试是逐渐更新的,很多fragment到最后其实是不可见的

  • 那能不能只渲染可见的fragment呢?可以:把场景光栅化2次,第一次不shading,只写入深度缓存;第二次才根据深度shading----depthprepass(这是建立在光栅化rasterization比shading开销小的基础上),复杂度是O(visible.frag * light)
    「不能做加采样AA,只能做TAA或屏幕空间AA」

5.2 Tiled Shading(forward+)

原理:在 Deferred Shading的基础上,把屏幕分成比如32x32个小块,然后分别shading。

  • 亮点:节省对每个光源的计算(因为一般的光源都有关于距离平方的衰减,范围可以理解为下图的圆),可以只计算影响到该Tile的光源,复杂度是O(visible.frag * avg.light-pretile)

在这里插入图片描述

5.3 Clustered Shading

原理:在 Tiled Shading把屏幕分块的基础上,在根据深度对其切片(3d grid网格),如下图

  • 亮点:进一步减少每个网格需要计算的光源,复杂度是O(visible.frag * avg.light-precluster)

在这里插入图片描述

六,LoD(Level of Detail)

lod是在不同计算层级下选择不同层级的方式,以减少计算。(Mipmap也是)在工业界也叫做“cascaded”(级联)。

  • 应用举例:

    1. Cascaded shadow maps----相机近处用高分辨率 shadow maps,远处用低分辨率的,高低分辨率转换处有一个过渡区域需要overlapping和blending,如下图
      在这里插入图片描述
    2. Cascaded LPV(Light Propagation Volumes光传播体积)----越远格子越大
      在这里插入图片描述
    3. geometric LoD—一系列高模低模,根据距离远近选择,或通过计算动态的使三角形大于1像素。(UE5Nanite的实现原理----动态选取LOD)
  • 难点:

    1. 切换levels的时候缝隙怎么办?
    2. 动态加载不同levels时缓存、带宽怎么动态调度?
    3. 用几何纹理(games102)做geometry LoD比三角形面更简单
    4. 使用clipping和culling会更快

七,Global Illumination Solutions

各种GI方法都有各自的问题,除了真的做RTRT,但又太慢了。因此工业界会使用hybrid solutions综合解决方案:先做SSR得到近似的GI,在SSR不行的地方用硬件或软件的方式做ray tracing。

  • 软件方式:近处用高质量SDF(shader里做tracing),远处用低质量SDF覆盖整个场景;用RSM处理很强的平行光或点光;Probes探针存储光照计算(Dynamic Diffuse GI,DDGI)
  • 硬件方式:用简化模型替代高模做ray tracing;RTRT结合Probes----RTXGI
  • 上边加粗的四条就是UE5的Lumen

老师的课程完结总结

  • 老师更喜欢思考理论算法,而不是工程实现----放弃思考等于自杀;但实现不重要吗?NO!非常重要(相信我们大多数人受自身硬软件限制都更适合做应用,而不是科研)

  • 还有很多没讲的话题:

    1. SDF贴纹理
    2. 透明物体和order-independent transparency
    3. 粒子渲染
    4. 后处理
    5. 生成和应用随机数、蓝噪声(blue noise)
    6. Foveated rendering比如VR中人眼看的地方投入更多算力
    7. Probe based GI
    8. ReSTIR,Neural Radiance Caching等先进技术
    9. 多光源理论和light cuts、VPL
    10. Participating media,SSSSS
    11. Hair表现
  • GAMES203广告:3d vision结合了计算机视觉和图形学,分三块:3d重建、3d信息表示、3d信息识别(语义)

  • 老师自己的GAMES2XX离线渲染课程广告:

    1. 采样和光线传播理论
    2. appearance modeling
    3. 先进研究

参考资料

1,GAMES202高质量实时渲染-个人笔记:实时光线追踪
2,GAMES202 笔记-实时光线追踪
3,Spatiotemporal Variance-Guided Filter, 向实时光线追踪迈进

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值