GAMES202笔记:屏幕空间实时全局光照


本文是GAMES 202的学习笔记,主要内容包括:SSAO、HBAO、SSDO、SSR

1. Screen Space Ambient Occlusion

环境光遮蔽是一个对于全局光照的近似,在屏幕空间意味着从Camera渲染场景得到信息,而非是场景中的所有信息。

1.1 三个假设

  • 假设任何一个shading point上来自任何方向的间接光照(incident lighting)是一个常数
  • 不同位置的Visibility是不同的
  • 假设物体是Diffuse的

下图中左忽略V项,右考虑V项:

下图中红色部分表示被遮挡,黄色部分表示未被遮挡,我们可以明显的得出一个结论,左边的 Shading point要比右边的亮一点:

1.2 理论支持

1.2.1 投影立体角

立体角是单位球上的一个面积,关于cos中的θ,我们认为θ从北极开始到南极是180度,那么立体角 * cosθ 可以把单位球上的面积投影到了单位圆上:

所以\(d x_{\perp}=\cos \theta_{i} \mathrm{~d} \omega_{i}\)

1.2.2 渲染方程拆分

还是从渲染方程开始:

\[L_{o}\left(p, \omega_{o}\right)=L_{e}\left(p, \omega_{o}\right)+\int_{\Omega^{+}} L_{i}\left(p, \omega_{i}\right) f_{r}\left(p, \omega_{i}, \omega_{o}\right)\left(n \cdot \omega_{i}\right) V\left(p, \omega_{i}\right) \mathrm{d} \omega_{i} \]

不考虑自发光,用近似公式将V项拆出去:

\[L_{o}\left(p, \omega_{o}\right) \approx \frac{\int_{\Omega^{+}} V\left(p, \omega_{i}\right)\cos \theta_{i} \mathrm{d} \omega_{i}}{\int_{\Omega^{+}}\cos \theta_{i} \mathrm{d} \omega_{i}} \cdot \int_{\Omega^{+}} L_{i}\left(p, \omega_{i}\right) f_{r}\left(p, \omega_{i}, \omega_{o}\right)\cos \theta_{i} \mathrm{~d} \omega_{i} \]

将前半部分积分中分母的立体角 \(\mathrm{d}\omega_{i}\) 拆成\(\sin\theta\mathrm{d} \theta\mathrm{d}\varphi\)之后对 \(\theta\)\(\varphi\) 分别积分得到的结果是\(\pi\),整个前半部分积分结果我们称其为\(k_{A}\),其实际意义是从一个点往所有方向看去按cos加权平均的平均visibility:

\[k_{A}=\frac{\int_{\Omega^{+}} V\left(\mathrm{p}, \omega_{i}\right) \cos \theta_{i} \mathrm{~d} \omega_{i}}{\pi} \]

因为假设了所有方向的间接光照是一个常数;物体是Diffuse的,BRDF也是常数。最终结果就是漫反射系数×间接光照强度Li。间接光照强度和漫反射系数是可以自定义制定的,所以后半部分完全是自定义的:

\[k_B=L_{i}^{\text {indir }}(p) \cdot \frac{\rho}{\pi} \cdot \pi=L_{i}^{\text {indir }}(p) \cdot \rho \]

所以当前着色点的AO = 加权平均visibility * 自定义颜色。
因为brdf是diffuse的、间接光照也是常数,所以可以将L和BRDF项拆出去,并且转换为以下形式:

\[\begin{aligned} \int_{\Omega} f(x) g(x) \mathrm{d} x & \approx \frac{\int_{\Omega_{G}} f(x) \mathrm{d} x}{\int_{\Omega_{G}} \mathrm{~d} x} \cdot \int_{\Omega} g(x) \mathrm{d} x \\ &=\overline{f(x)} \cdot \int_{\Omega} g(x) \mathrm{d} x \end{aligned} \]

如果\(f(x)\)是常数,那么第一部分相当于取均值,也可以得到相同的结果。

1.3 求Visibility部分

  • 任何一个Shading Point在以自身坐标为圆心,半径为R的球的内部随机撒一些点,然后判断这些点能不能被Shading Point直接看到;
  • 从Camera出发渲染,深度图可以作为场景的一个简单近似,也就是我们从camera看到的下图中的白线,球内部的点是可以投影到Camera然后找之前记录的深度,如果深度更深,则表示在物体内部被遮挡,反之则未被遮挡。

这样做存在一些问题:上图中红色虚线中的红点能够被Shading Point看到的,但是由于是从Camera出发,这里被判断为了看不到;没有考虑法线方向,但渲染方程只考虑法线所在的半球空间。因此SSAO只在整个球采样红点过半的时候才开始考虑AO问题。

1.4 噪声问题

采样数越多,噪声越少。可以用少量的Sample,得到一个noisy的结果;然后再这个noisy的结果上进行一个denoising来实现降噪。降噪的模糊和噪声在和场景中其他效果与光照叠加后就会变得非常不明显,从而在最终的图像上获得比较好的综合效果。

2. Horizon Based Ambient Occlusion

当Screen Pass可以拿到场景法线时,我们就可以进行半球采样了;同时可以根据方向加权(靠近中间大,靠近两边小)。

下面是SSAO与HBAO结果对比:

有效减少了错误遮挡情况。

3. Screen Space Direction Occlusion

屏幕空间方向遮蔽是SSAO的一个升级,AO考虑间接光照是一个常数,而DO里更精确的考虑了间接光照。

3.1 更准确的近似间接光照

  • RSM中通过Shadow Map可以得到用于计算第一次弹射的间接光照光源信息;
  • AO是全局光照的近似,不同颜色的Diffuse会互相照亮,但SSAO/HBAO只能得到明暗变化,得不到Clolor Blending;

3.2 理论支持

3.2.1 基本思路

SSDO的做法与Path Tracing很像,假设在Shading Point的P点,随机的往某一个方向打出一根光线:

  • 如果光线没碰到物体,则认为P点这里接收直接光照;
  • 如果碰到了一个点Q,那么算出Q点接受的直接光照打到P点的贡献,从而求出P点的间接光照;

3.2.2 理论支持

SSAO和SSDO假设完全相反:

  • AO认为红色的框里能接收间接光照,黄色框里无法接收间接光照,然后求出加权平均的visibility值,也就是假设间接光照来自比较远的地方
  • DO认为红色框里接收的是直接光照,而黄色框里才是接收到的间接光照。P点接收到的是来自红色框的直接光照+黄色框里的间接光照,也就是假设间接光照来自比较近的反射物

这两个假设都不是完全正确的,物理真实的情况是这两种的混合:近处的是DO,远距离是AO,因此AO与DO也并没有矛盾。

V=1时是直接光照,而DO的计算是计算间接光照,完全不用去计算:

\[L_{o}^{\operatorname{dir}}\left(\mathrm{p}, \omega_{o}\right)=\int_{\Omega^{+}, V=1} L_{i}^{\operatorname{dir}}\left(\mathrm{p}, \omega_{i}\right) f_{r}\left(\mathrm{p}, \omega_{i}, \omega_{o}\right) \cos \theta_{i} \mathrm{~d} \omega_{i} \]

V=0时也就是间接光照的情况,这是DO应该处理的:

\[L_{o}^{\operatorname{indir}}\left(\mathrm{p}, \omega_{o}\right)=\int_{\Omega^{+}, V=0} L_{i}^{\operatorname{indir}}\left(\mathrm{p}, \omega_{i}\right) f_{r}\left(\mathrm{p}, \omega_{i}, \omega_{o}\right) \cos \theta_{i} \mathrm{~d} \omega_{i} \]

3.3 查找点P的间接光照贡献点

做法与AO一样:考虑点P法线部分的半球,判断从P点往A、B、C、D四个方向看会不会被挡住,由于是屏幕空间的算法,因此这里我们同样不考虑在3D场景中A,B,C,D四点会不会与P连成光线,只考虑从Camera看去A、B、C、D与P连成的光线会不会被挡住。

上图中,ABD三个点的深度比从camera看去的最小深度深,也就是说PA,PB,PD方向会被物体挡住,因此会为P点提供间接光照。下面我们还需要计算这些点对P点的贡献。

3.4 计算Surface patch的间接光贡献

首先需要做的是转换积分域:渲染方程中求P点的间接光照的积分域是P点的半球空间,对整个立体角进行采样;现在是通过对已知的光源的贡献求和得到点P的间接光照。
蒙特卡洛方法需要在x上采样在x上积分才能成立,需要把渲染方程对\(\mathrm{d}\omega\)的积分转化为对\(\mathrm{d}A\)的积分。

可以将\(\mathrm{d}A\)投影到单位球表面上:

\[\mathrm{d} \omega=\frac{\mathrm{d}A \cos \theta^{\prime}}{\left\|x^{\prime}-x\right\|^{2}} \]

那么渲染方程可以写成对\(\mathrm{d}A\)积分的形式:

\[\begin{aligned} L_{o}\left(x, \omega_{o}\right) &=\int_{\Omega^{+}} L_{i}\left(x, \omega_{i}\right) f_{r}\left(x, \omega_{i}, \omega_{o}\right)V\left(p, \omega_{i}\right) \cos \theta \mathrm{d} \omega_{i} \\ &=\int_{A} L_{i}\left(x, \omega_{i}\right) f_{r}\left(x, \omega_{i}, \omega_{o}\right) V\left(p, \omega_{i}\right)\frac{\cos \theta \cos \theta^{\prime}}{\left\|x^{\prime}-x\right\|^{2}} \mathrm{d} A \end{aligned} \]

把立体角的积分变成了对Light区域面积的积分,如果当区域足够小的时候dA甚至不用积分,直接相乘后相加即可。
因为假设物体是Diffuse的,所以:

\[f_r = \frac{\rho}{\pi} \]

\[L_i = f_r\frac{\Phi}{\mathrm{d} A} \]

其中\(\Phi\)代表直接光的flux,将\(L_i\)带入渲染方程之后,可以抵消\(\mathrm{d} A\),最后可以得到一个次级光源对着色点的贡献公式:

\[E_{p}(x, n)=\Phi_{p} \frac{\max \left\{0,\left\langle n^{\prime} \mid x-x^{\prime}\right\rangle\right\} \max \left\{0,\left\langle n \mid x^{\prime}-x\right\rangle\right\}}{\left\|x-x^{\prime}\right\|^{4}} \]

分母上多出来的\(\left\|x-x^{\prime}\right\|^{2}\)用于给上面两个\(x^{\prime}-x\)归一化。
剩下的和RSM一样,将有次光源贡献求和即可。

3.5 SSDO存在的问题

毕竟只有屏幕可见几何的信息,遮挡上一定会存在误判:

上图中的点A,按照SSDO的理念应该属于直接光照贡献部分,但在实现时会被判定为间接光照贡献。
屏幕空间拿不到的信息无法补全,当下图中的方块朝向与摄像机射线几乎垂直或被遮挡时:

SSDO只适合小范围的间接光补全,当距离超过追踪范围时,无法补全。下图是Path Tracing的结果,如果用SSDO,绿色墙面超出采样范围,Cube上不会有绿色反光:

4. Screen Space Reflection

屏幕空间反射,或屏幕空间光线追踪(Screen Space Raytracing)

4.1 基本实现方法

4.1.1 镜面反射 Specular

对于任何一个像素:

  • 知道Shading point的观察方向后,可以得出其反射方向
  • 从Shading point点沿着反射方向延长找到与屏幕的壳的交点
  • 将交点的颜色作为反射的颜色记录到Shading point

4.1.2 光滑面反射 Glossy

Specular反射只需要反射一个方向的话,那么对于一定Roughness的材质来说我们要根据其BRDF的Lobe来考虑:如果Lobe比较细,则需要很少的光线;如果Lobe比较越大,像Diffuse那种的话我们需要射出很多根光线。

4.2 理论支持

对于任何一个Shading point,看到的radiance就是对半球进行积分,如果是Specular的物体,那么相当于光线打到物体的哪里,就用它所发出的radiance就可以:

\[\begin{aligned} L_{o}\left(x, \omega_{o}\right) &=\int_{\Omega^{+}} L_{i}\left(x, \omega_{i}\right) f_{r}\left(x, \omega_{i}, \omega_{o}\right)V\left(p, \omega_{i}\right) \cos \theta \mathrm{d} \omega_{i} \\ &=\int_{\Omega^{+}} L_{o}\left(q, q-p\right) f_{r}\left(x, \omega_{i}, \omega_{o}\right)V\left(p, \omega_{i}\right) \cos \theta \mathrm{d} \omega_{i}\end{aligned} \]

\(q\)代表次光源的位置
所以,我们需要根据反射向量与场景壳求交得到\(q\),然后通过采样Color Buffer得到\(L_{o}\left(q, p-q\right)\)

4.3 反射光线与场景壳求交

4.3.1 Linear Raymarch

上图中,黄色点是Shading point,橙色点是反射方向的采样点,绿色是反射射线与场景壳的交点。

  • 沿着反射方向以一个固定的步长逐步前进,并将每次停止时的深度与壳的深度进行比较:如果浅于壳,则继续前进;比壳深、则停止求交。也就是我们用深度来进行可见性判断
  • 质量取决于步长的大小,步长小越精准,同时计算量也越大,因此步长太大太小都不行,在没有SDF的情况下,步长只能是一个定值

所以如果没有场景的SDF,需要一种加速策略。

4.3.2 Hierachical Ray Trace

这种方法基于为Depth Buffer生成存储下层最小值的Mip-Map,和Hi-Z一样。

大体步骤如下:
1根据Normal Buffer计算出Shading point的反射方向;
2使用最小步长前进,检查是否与壳相交,深度采样对应Level 0的Mip-Map;
3如果没有相交,增大步长,检查是否相交,采Level 1;以此类推,直到相交或者采样点超出屏幕范围;
4相交后根据Mip-Map向下级回退,很容易得到交点像素坐标。

特别说明:

  • 因为Level(n+1)对应Level(n)四个像素的最小值,只要Level(n+1)不与射线相交,Level(n)四个像素都不会。
  • 这里的步长是反射向量投影到Mip-Map深度图上的距离。如果在Level0,那么步长是向量投影到Level0相邻两个像素的长度;如果在Level1,则是对应Level1上相邻两个像素的长度。所以步长是根据当前所在的Mip-Map Level动态决定的。
  • 如果Shading point并不是在\(2^k\)上的像素,查询并不准确

4.4 存在问题

摄像机看不到的内容和在视锥体之外的信息无法得到。

Shading Point为Diffuse物体时效率低。

4.5 SSR的效果

4.5.1 Sharp and blurry reflection

Glossy物体反射的模糊现象:

4.5.2 Contact hardening

对于物体来说,近处的物体反射清晰,远处反射模糊,当反射物是Glossy时反射的lobe是一个锥形,当距离越远锥形的截面越越大,也就会发生模糊现象:

4.5.3 Specular elongation

反射在垂直方向被拉长的现象,在雨天常见的现象,当我们认为地面是各向同性的,也就是法线分布是一个圆,反射出去的lobe就是一个椭圆:

4.5.4 Per-piex roughness and normal

对于不同的法线与粗糙度不同的现象:

引用

GAMES 202
图片来自于GAMES 202 PPT
https://zhuanlan.zhihu.com/p/381782999
https://zhuanlan.zhihu.com/p/383370745


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM