03 - 屏幕空间的实时全局光照算法
本文将介绍一些屏幕上的实时全局光照算法,例如 屏幕空间环境光遮蔽SSAO
,屏幕空间方向性遮挡SSDO
和屏幕空间反射SSR
。
屏幕空间算法
如果全局光照算法在生成间接光照效果时,只根据从相机视角能得到的信息,对只有直接光照的渲染结果进行后处理(post processing)以加上间接光照效果,即只用到了屏幕空间(screen space)信息,则这该算法属于屏幕空间算法。
SSAO
简介
SSAO(Screen Space Ambient Occlusion) 是一种在屏幕空间中对全局光照的近似。
如下图,SSAO可以让场景看起来更真实,因为它让物体富有立体感。而且SSAO的实现也比较容易,因此是必要的。
SSAO的核心思想如下:
- 不知道间接光照的具体内容(屏幕空间),于是假设它是个常数。
- 认为各着色点所有方向上的可见性不同,因为着色点间存在“遮挡”关系。
- 认为物体材质都是漫反射(diffuse)材质。
这样就可以通过估计着色点的可见性,直接地计算出间接光照效果。
理论推导
需要解RTR渲染方程,使用积分近似将其拆分成可见性V项+其他项:
其中:
- 可见性V项:即
,从着色点看向周围所有方向可见性的加权平均,范围0~1。 - 间接光和BRDF项:两个常数的乘积
,即间接光强与漫反射BRDF。
有关积分近似拆分:
可以理解为将
f(x)
,g(x)
拆开,顺便求了f(x)
的均值。上面这种拆分是准确的,因为f(x)
和g(x)
都是常数。为什么拆出来3个cos项?是因为要进行换元,引入“投影立体角”这一概念,即球面立体角在它单位圆上的投影,有
。于是变成了在“半球”上的积分,且 。
间接光和漫反射BRDF项均为常数,于是可以将它们从积分中提出来:
也就是
计算Ka
从上面的理论可以得出,要计算SSAO只需计算
如图,SSAO算法在以着色点为中心,一定半径的球里进行采样,得到被遮挡(红)和不被遮挡(绿)的点的数量。在屏幕空间如何判断着色点和采样点的遮挡关系,可以利用屏幕空间的深度值来判断,若采样点深度比屏幕空间中该点深度大,说明该采样点被遮挡了。
当超过一半的采样点均被遮挡时,认为该着色点是不可见的,应用SSAO。
计算出的
在估计可见性时没有考虑法线方向,导致出现“假遮挡”现象,如上图中间红虚线右边的点,应该是绿色的,但被SSAO计算成了红色。不过影响不大,可以忽略。
算出来的
没有被余弦加权平均,在物理上不准确,但看起来还算正确。
避免“假遮挡”
要想避免假遮挡现象,就得进行更多采样,但实时渲染的性能要求不允许我们这样做,可以用下列技巧来缓解/避免“假遮挡”现象:
可以用较少采样得到有噪声的结果,然后降噪,获得“更多”的采样点。
现代图形渲染管线通常是 延迟渲染(Deferred Rendering)的,可以通过其中的 G-Buffer 获取当前着色点的法向量,有了法向量就能将采样点的范围缩减至一个半球,让结果更准确。
这也是 HBAO 的思想:
HBAO的结果是准确的,因此可以避免假遮挡现象。
SSDO
简介
是SSAO的升级版,比SSAO考虑的更全面准确。SSAO假设间接光来自远处,而SSDO则认为间接光来自附近,因为场景中的间接光照信息还是知道一部分的。
由于是屏幕空间算法,SSAO无法像RSM那样获取间接光照信息,于是SSDO认为 屏幕里能被直接光照射到的物体就是间接光源。
SSDO的核心思想和路径追踪很像:
在着色点P上向任意方向射出若干光线,如果
- 光线没有打到物体,说明射向P的光线是直接光;
- 光线打到了物体,说明射向P的光线是间接光。
和SSAO对比
如图,SSAO和SSDO最主要的不同点就是 间接光的来源不同:
- SSAO认为着色点一定能够接收到部分间接光(红圈),另一部分则因为遮挡没有间接光(橙圈)。
- SSDO认为着色点射出光线后,打不到物体的是直接光(红圈),打到物体的则为间接光(橙圈)。
因此,SSAO认为 间接光来自远处,SSDO认为 间接光来自近处,理论上它俩应该结合起来做才科学。
理论推导
还是解渲染方程,将其分为可见和不可见两部分:
重点考虑不可见(间接光贡献)的情况,而这种情况是可以被算出来的。
具体做法
SSDO的做法类似于HBAO,在着色点为球心,一定距离的半球上进行采样,然后将采样点和摄像机视角深度值比较,如果采样点深度比摄像机视角深度大,说明采样点和摄像机连线与物体的交点所在面片是一个次级光源(如左图A,B,D);反之则不是次级光源(如左图C)。
最后利用渲染方程将所有次级光源对着色点的贡献求和即可。
但SSDO也存在误差,如右图A点,本来是直接光源,却被SSDO误认为是次级光源。
优缺点
优点:
- 效果很好,接近离线渲染
- 轻量化
缺点:
- 只能表示小范围的全局光照,这说明它仍会丢失一些来自于远处次级光源的信息。
- 屏幕空间算法的缺点,有来自屏幕外的误差和信息缺失。
SSR
简介
SSR也是一种屏幕空间实现全局光照的方法,它在屏幕空间上进行模拟光线追踪,不需要场景图元信息。
SSR的核心问题如下:
- 求交问题:解决任意光线和场景求交的问题。
- 着色问题:计算光线与场景相交的像素点们对着色点的贡献。
具体做法
基本SSR算法
为了充分利用屏幕空间提供的信息,该算法是基于 镜面反射 的。
对于每个着色片段:
- 计算反射光方向
- 让光线和场景求交,获得交点
- 让交点颜色作为反射的颜色
可以做镜面反射,也能调整地面粗糙度,配合法线造成模糊/凹凸效果。
接下来说说如何具体进行求交和着色操作。
解决求交问题
起初人们使用 Linear Raymarch 算法进行光线和场景求交。反射光线在着色点往反射方向以一定的距离步进,直到它的深度比场景物体深度大停止步进,视为光线和场景物体相交。
在这个算法中,步长为定值,太大太小均不好。于是能 让步长动态调整 的算法 Hierarchical Ray Trace 便出现了。
就像世界空间光线和场景求交可用层级结构加速(如BVH树、KD树)一样,屏幕空间中光线和场景求交可用 深度Mipmap 来加速。该深度Mipmap和平常的Mipmap不一样,平常的Mipmap使用下层4个像素均值作为上层像素,而 深度Mipmap使用下层4个深度最小值作为上层深度。
这样就让场景深度值有了类似于树状的层次结构关系,方便光线动态步进:
解决着色问题
对SSR的着色要达到如下要求(在正确考虑物体BRDF前提下):
- 根据反射面材质做出不同反应(如镜面地板,粗糙地板等);
- 离物体越近,反射得越清晰;
- 类似雨天路面效果,反射物体会上下拉长一点(如果有场景是雨天)。
可沿用路径追踪算法,不过要假设:
- 反射物材质是漫反射材质,这样就不必考虑方向导致贡献的不同;
- 只有次级光源。
因此可用 BRDF重要性采样 来获取着色点反射光线的方向分布。然后为了复用采样结果,可以在采样前预过滤一次,然后用加权BRDF加速运算。这里的“加权”就是利用该像素旁边一圈像素的结果,用它们深度值以不同贡献求均值。
优缺点
优点:
- 对镜面/光滑材质地板性能高
- 效果好
缺点:
除了对漫反射材质地面性能和效果不好外,还是屏幕空间带来的信息不足的问题:
屏幕内物体信息丢失,如下图没有手心的信息:
屏幕外物体信息丢失,如下图没有帘布的上端:
对于第二种情况,我们可以随反射距离衰减着色结果来解决:
参考资料
- GAMES202: 高质量实时渲染 (ucsb.edu)
- 《GAMES202:高质量实时渲染》3 实时全局光照:RSM、LPV、VXGI、SSAO、SSDO、SSR - 知乎 (zhihu.com)