阴影(Shadow Mapping)

着色是一种局部现象,只考虑着色点自己、光源、摄像机,如果我要算出它的着色,完全不考虑其它物体,甚至自己的其它部分对这个着色点的影响。而事实上如果有其它物体挡在 shading point 的光源之间,那就会挡住光线,光线就到达不了 shading point,这就是为什么会有阴影,我们之前说着色解决不了阴影,我们现在就来解决这个问题。

Shadow Mapping 本质上是一种图像空间的做法,所谓图像空间就是说,我在生成阴影的这一步,我是不需要知道场景的几何信息的。Shadow Mapping 也会导致走样现象。

关键思想在于,如果这个点不在阴影里,你从摄像机可以看到这个点,光源也可以看到这个点。

经典的 Shadow Mapping 只能处理点光源,这种阴影通常有很明显的阴影的边界,要么在阴影里要么不在阴影里,这种阴影我们叫硬阴影。

有两步操作。第一,先从光源看向整个场景,也就是说在光源处有一个虚拟的摄像机在这里,我先做一个光栅化。

我们得到的这个图我们不要做着色,我们把这些点对应的位置的深度记下来。相当于我只需要它的深度图。

第二步,我们用真正的摄像机位置再次看向这个场景

找到对应的点投影回光源,在光源中的深度图上应当出现在哪个位置上。

在深度图上对于这个点记录有一个深度,我同样可以计算从摄像机看这个点,这个点到光源的深度,这两个深度肯定是一致的,那说明这个点一定是可以被光源所看到的。

 

而下面的这个点深度不一样,就看不到了。

从实例来看:

从光源看向场景。

记录深度缓存。

投影回光源生成的 Shadow Map 上。会有浮点数精度问题,并且一个像素覆盖的范围会有一定误差,所以呈现这样,即使不判相等,通过设置范围、加 bias 偏差等方法都不能本质上解决问题。

这个 Shadow Map 本身是有分辨率的,那这个分辨率要多大?如果我用的 Shadow Map 分辨率很低,而我渲染的场景分辨率又非常高,那么说我记录的阴影的信息是走样的,那就会投影出一个有锯齿的阴影,那就会很难看。而用分辨率很高的 Shadow Map 效果当然非常好,但是开销就会非常大。

现在当然会有更大的开销,要渲染整个场景两遍,原先只做 shading 只要渲染一遍。

即使这样,也不耽误成为现在几乎所有 3D 游戏、3D 电影的主流技术。

Shadow Map 的缺陷:

硬阴影 VS 软阴影

软阴影其实在物理上就是所谓的半影(Penumbra)。

对于点光源确实不可能出现软阴影,如果有软阴影,那么就说明光源有一定的大小。

 

posted @ 2022-01-03 10:11  HanselHuang  阅读(741)  评论(0编辑  收藏  举报