课程的下一个部分是光线追踪,为了说明为什么要用光线追踪,本节内容,将针对光栅化过程中遇到的一些困难,比如涉及到全局光线传输,包括阴影都是光栅化不太好做的事情,讲述光栅化中如何生成阴影等内容。
之前在光栅化部分我们说着色是一种局部的现象,只考虑着色点自己、光源和摄像机,计算着色时完全没考虑其他物体,甚至这个物体的其他部分对这个着色点的影响。事实上这是不对的,因为如果有其他物体挡在shading point和光源之间,就会挡住光线,光线就到达不了shading point,自然算出来的结果就应该是黑的,这就是为什么会有阴影,这是之前的着色解决不了阴影,现在我们来解决这个问题。
Shadows
下图是2018年第一批支持光线追踪的游戏之一,古墓丽影暗影
这幅图中生成的的阴影是RTX:off,不是基于光线追踪生成的,而是光栅化中经典方式生成的阴影(阴影可以明显的将人的位置渲染出来,如果没有阴影会感觉人物飘在空中)
Shadow Mapping是一种图像空间的算法
Shadow Mapping是一种图像空间的算法。
- 使用Shadow Mapping计算阴影时,不需要知道场景的几何信息;
- 使用Shadow Mapping,会产生走样现象。
Key idea:
- 如果一点不在阴影内,说明你可以从摄像机看到这个点,并且光源也可以看到这个点。(如果点在阴影里,你看得到该点,而光看不到该点)
经典的Shadow Mapping只能处理点光源或方向光源,这种光源的阴影通常会有明显的边界(硬阴影:这些点要么在阴影里,被这个点光源看到;要么不在阴影里)。
点光源下如何生成阴影
我们必须考虑这些点能不能被光源或摄像机看到。其分为两步操作:
- 在光源处虚拟的放一个摄像机,并对准整个场景,做一遍光栅化,就可以得到光源会看到的点,并且生成了一幅深度图(记录了不同位置看到的点对应的深度)
- 从眼睛或摄像机出发再次看向场景,如下图,看到的2个黑点,可以将其投影回光源的虚拟摄像机的成像平面上(即:如果从光源看这个点,它应该在之前记录的那张深度图的哪个像素上)
- 然后再比较:
对于左边那个黑点:之前记录了从光源处虚拟摄像机的点到这个点的深度(橙色的线),然后从摄像机看这个点,也可以计算这个点到light的深度,可以看到这两个深度是一致的,这就说明这个点既可以被光源所看到,又可以被相机看到。
对于右边那个黑点(如下图):从摄像机看的这个点投影回光源所在的虚拟摄像机所成像的图像上,发现之前记录的深度是最上面那个点的深度这和它实际的深度是不一样的。说明这个点是光源在这个方向所看不到的点,那也就是说这个点在阴影中。
总结:共会进行2次不同的投影,第1次认为光源处有一个往场景看的虚拟摄像机,记录了不同位置能看到的深度,第2次,从实际摄像机出发,再去渲染场景,渲染出的不同的点都重新投影回光源,就知道在之前深度图的哪个像素去寻找这个点,再比较之前记录的深度和当前看到的这个点是否一致。
An Instance
左上角有一个点光源投影出阴影在地板上,那如何通过shadow mapping的方式生成shadow map,并用它来产生阴影
-
从光源看向场景,如下图;实际上记录的是深度,如下下图
-
当实际从真正的摄像机看场景时,可以看到下面这幅图的几何形状,这些几何形状从不同的位置打到不同的像素,每一个像素都连一条光线到光源上去(或者说每个像素对应的实际位置都投影回光源处所生成的shadow map上),就可以知道在shadow map上的哪一个像素可以找到这个方向,就可以对比在shadow map上记录的深度和实际这个点和光源的距离它们之间的关系。
-
问题: 可是判断浮点相等很困难,特别是考虑到各种各样的数值精度问题,解决方法:不去判断是否相等,而是判断大小,并引入bias(偏差),但并不能本质上解决问题
Shadow map本身有分辨率,这个分辨率要多大? 如果shadow map的分辨率很低,然后渲染整个场景的分辨率又很高,那就变成这个阴影记录的信息是走样的(有锯齿),但阴影图太大的话开销就会大。
Problems with shadow maps
shadow mapping的缺点有:
- 只能做硬阴影(point lights only)
- 质量取决于阴影图分辨率(基于图像算法的通病)
- 涉及浮点数数值精度的问题
但并不妨碍shadow mapping技术成为现在几乎所有的3D游戏,以及早期电影里的主流技术:
硬阴影与软阴影
- 硬阴影:如下图,右边有一个点光源,阴影的边缘非常锐利,因为对于点光源来说,物体上任何一个点,要么可见,要么不可见
- 软阴影:阴影会从有阴影慢慢过渡无阴影,不再是非0即1。越靠近物体根部越硬,离物体根部越远越虚
软阴影其实是一种自然现象,是物理上所称的半影(Penumbra)
物理上,影子分为2种,本影(Umbra)(在一个地方完全看不到光源),半影(Penumbra)(一个地方可以部分看到光源)
上面日食图,可以看得比较明显,本影区域月亮完全挡住了太阳,半影区域,由于太阳是有一定大小的,所以这个区域可以看到一部分的太阳
阴影程度取决于你可以看到多少(大)的光源,同时说明点光源是无法产生软阴影的,因为软阴影的产生是因为光源有一定的大小
「如果这篇文章对你有用,请随意打赏」
如果这篇文章对你有用,请随意打赏
使用微信扫描二维码完成支付

comments powered by Disqus