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

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

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


  1. 先从光源看向整个场景

      

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

  1. 再从相机看向整个场景

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

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

 

 如果相机所记录的点的深度投影到光源,与光源所记录的深度不一致,则说明该点被遮挡,即眼睛看不到


一个复杂场景的阴影实例:

 有阴影和无阴影的比较

 从光源看向物体

 记录深度缓存

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

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


 硬阴影的一些问题

当渲染左边的一幅图片时会观察到地面上出现了很多的纹路,这些不是摩尔纹,而是由于数值精度而造成的。

从右边图中进行分析:从光源出发看向场景,每个屏幕像素最终会记录一个深度并覆盖场景中的一片区域,而且深度为一个常数并垂直于观察的方向,所以最终一个像素所覆盖的场景投影到场景中为那些红色斜线部分。

但是从眼睛出发看向场景中的一点,与光源照向该点有一个微小的误差,光源记录的该点的深度为橙色斜线部分,比实际深度要浅,那么就会发生自遮挡的现象。当光源垂直于地面照向场景这种情况就会得到缓解

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐