谈及光照模式与阴影,不可避免的需要知道:全局光照阴影技术从何而来?为什么需要这些技术?
什么是全局光照?
全局照明(GI)是一个系统,用于模拟光从表面反射到其他表面(间接光)的方式,而不是仅限于直接从光源(直接光)照射到表面的光。 全局光照 = 直接光照 + 间接光照
真实的阴影?
在现实生活中,由于光线会被物体表面无数次吸收、反弹直至衰减(此内容我在PBR流程原理中已经详细介绍过),阴影是“柔和的”“真实的”。保证画面真实并提供实时运算是所有人理想的追求,然而现实比较骨感,实时光照阴影只模拟光源第一次从发射到物体表面产生的画面,对于光线反弹一概不管(想问光线追踪的自己去搜,别杠)。这导致了一个问题——阴影暗部死黑一片,你以为画面这样?
事实上是这样
为什么同样有高光和阴影,游戏画面就成了这样?还是上面的问题,实时光照目前的技术并不能模拟光的多次反弹,由于只提供直接光照,暗部衔接僵硬。那些“天生才有地中海发型的家伙”发明了靠「光栅化」来渲染物体的技术。好比将我们的电脑屏幕当做一个摄像机镜头,而「光栅化」技术就是将游戏中的 3D 场景和光影转化为 2D 平面上的像素点,而你所看到的反射、阴影等效果,实则是靠后期加工或是其它预烘焙技术(预渲染)模拟出来的。对于Lighting烘焙及LightMap等技术的讲解,请参照我另外一篇文章——(HDRP)全局光照技术初探(二)-光照烘焙技术
(实时光线追踪在这里不做探讨)
提供间接光照的本质是采用类似离线渲染的方式预计算出一套只记录光照信息贴图(对第二套UV采样),并在片元着色阶段进行相应的计算。
知道了光照局限性和阴影原因,我们来谈谈HDRP中提供了哪些阴影以及对应的光照模式。
阴影的种类
-
光源投射阴影
-
屏幕空间阴影
Contact Shadow(接触阴影) Miro Shadow(微阴影) Ambient Occlusion(环境光遮蔽)
光源投射阴影
- 在实时Realtime模式下的阴影 (实时)
- 在混合Mixed模式下的混合阴影 (混合)
- 在烘焙Baked模式下的烘焙阴影(完全预烘焙)
影响阴影的两种光照模式
除Realtime模式外,HDRP支持的投射混合阴影产生主要由两种光照模式影响:
- Baked Indirect模式
- ShadowMask 模式
在Baked Indirect模式下,所有的物体将会接受实时阴影信息,烘焙的光照贴图不会包含阴影信息。由于某些光照是烘焙的(因此是预先计算的),在运行时更改任何参数都会导致在组合实时光照和预计算光照时出现不一致的结果。无论是 Baked Indirect 还是 Shadowmask ,直接光照的影响就像实时光源一样,可以实时更改光源的颜色、强度甚至变换等参数。但是,烘焙值是预先计算的,在运行时无法更改。
——
在ShadowMask 模式下,不同的物体会接受不同的阴影信息
1.当shadowmask的光源被设置为Distance-Shadowmask时
动态物体 | 静态物体 |
---|---|
接受实时光照信息 | 接受实时光信息 |
通过LightProbe接受烘焙的间接光照信息 | 通过光照贴图接受间接光照信息 |
接受动态的实时阴影信息,在Distance范围内,以ShadowMap阴影的方式 | 接受动态的实时阴影信息,在Distance范围内,以ShadowMap阴影的方式 |
接受静态物体阴影信息,在Distance范围内,以ShadowMap阴影的方式 | 接受静态物体阴影信息,在Distance范围内,以ShadowMap阴影的方式 |
在Distance范围外,以LightProbe获取静态物体的烘焙阴影信息 | 在Distance范围外,以光照贴图的方式获取静态物体的烘焙阴影信息 |
2.当shadowmask的光源被设置为Shadowmask时
动态物体 | 静态物体 |
---|---|
接受实时光照信息 | 接受实时光照信息 |
通过LightProbe接受烘焙的间接光照信息 | 通过光照贴图接受间接光照信息 |
接受动态的实时阴影信息,在Distance范围内,以ShadowMap阴影的方式 | 接受动态的实时阴影信息,在Distance范围内,以ShadowMap阴影的方式 |
接受静态物体阴影信息,在Distance范围内,以ShadowMap阴影的方式 | 接受静态物体阴影信息,在Distance范围内,以ShadowMap阴影的方式 |
在Distance范围外,以LightProbe获取静态物体的烘焙阴影信息,不受Distance影响 | 以光照贴图的方式获取静态物体的烘焙阴影信息,不受Distance影响 |
——
shadowmask与Distance-Shadowmask对比
Distance-Shadowmask | Shadowmask |
---|---|
占用更高的GPU性能 | 占用更高的Memory |
阴影效果较好 | 提高Shadow Resolution可以获得好的阴影效果 |
Disatance内的所有物体阴影都是实时计算的 | 只有动态物体的阴影是实时计算的 |
什么是Shadow Mapping
Shadow Mapping是一种著名的基于图像空间的阴影实现方法,上面提到的ShadowMap是通过这种方法生成的深度纹理
Shadow Mapping我总结了一下基本原理:
- 先以光源坐标空间(光源就像摄像机,但不会去shading)得到场景深度纹理(基于正交投影)
- 再以摄像机渲染场景的方式,获取摄像机坐标空间下的深度值
- 在同一坐标空间下,将两个深度值进行比较,相同则为非阴影区域,不同则为阴影区域
当然也可以通过对比“灯光到片元的距离”与“相机到片元的距离”
Shadow Mapping技术产生的问题及“缓解”办法
- Shadow Acne自阴影
上面我有说到Shadow Mapping通过对比深度值(或距离)的方式判断阴影区域,由于ShadowMap的纹理分辨率问题,使得N个像素只能对应一个ShadowMap上的采样点(一个像素或由多个片元组成),片元计算会认为对应区域属于阴影区域,由此产生黑白相间的条纹自阴影,并且当灯光与物体表面的夹角越小,Shadow Acne自阴影区域越明显。下面我们看看解决Shadow Acne的方法:
再谈深度值对比,深度值说的是不够严谨的,图形学中称之为“深度场”,这一大片场地记录着深度信息。投影的产生是由于在投影区域与光源之间存在遮挡像素,该像素到光源的深度总是小于该像素到摄像机的深度,通过该方法判断为投影区域并由此产生Shadow Acne的问题。那么有没有什么方法缓解这种问题呢?使得像素到光源的深度总是足够小于该像素到摄像机的深度,这种足够使得我们引入了一个可变的偏移常量-Bias,Bias能够尽量减小灯光到片元距离场的值,由此Shadow Acne自阴影的产生会明显减少
皆大欢喜了吗?并没有,Bias的方法产生另外一个问题——在交界处丢失一定区域的阴影(当然丢失阴影说法不太正确,而是阴影的一种走样现象)
为了解决丢失阴影的问题,HDRP中还引入了一种基于屏幕空间的Contact Shadow接触阴影的方法。Contact Shadow为弥补Shadow Mapping的技术缺陷
- Shadow Aliasing阴影锯齿
Percentage Closer Filtering反走样技术 (PCF)
以下内容待更新2022/5/12