概述
在不考虑光线反射的前提下,当一个光源发射的一条光线遇到一个不透明物体A时,这条光线就不能够再继续照亮其他物体了,相当于光线被更靠近光源的物体挡住了一些;
也就是说阴影的产生就是因为光线无法到达;
Shadow Mapping
基本原理
将摄像机的位置放在和光源重合的位置上,那么场景中关于这个光源的阴影区域就是摄像机看不到的位置;
Shadow Mapping在Unity中的本质就是生成一张深度图(阴影映射纹理),一般存于显存中,这张深度图记录了从光源出发,能看到的场景中距离它最近表面的位置;
Unity中如何应用Shadow Mapping
阴影映射纹理的生成是由光源完成的;
在每帧渲染的早期阶段,Unity会对每个能够投射阴影的光源创建一个对应的摄像机视角,这个视角用于捕获从光源位置看到的场景。平行光设置为正交摄像机,点光源可能会设置多个视角,捕获多个方向的立方体阴影贴图;
Unity会渲染场景中的深度信息,这些深度信息表示从光源到场景中每个物体的距离,不考虑颜色信息,最终存储在显存中;
实时阴影映射纹理需要每帧更新,但对于静态光源和静态场景,可以使用预烘焙的阴影贴图,减少实时计算的开销;
有了映射纹理后,只需要在Pass中将顶点位置变换到光源空间下,得到顶点在光源空间下的三位位置信息,然后使用X和Y分量对阴影纹理进行采样,得到阴影纹理中该位置的深度信息。如果阴影纹理中取出的深度值小于该顶点的深度值,那么说明该顶点位于阴影中;
Screen Space Shadow Mapping
在Unity中,使用的并不只是纯粹的Shadow Mapping技术,还会使用Screen Space Shadow Mapping(屏幕空间阴影投射技术)。它是基于Shadow Mapping技术的一种拓展和改进技术;
SSSM技术在Shadow Mapping技术的基础上,需要多生成一张深度图——屏幕空间深度图。这张屏幕空间深度图中记录了摄像机视角看到的每个像素的深度值(即每个像素点到相机的距离);
我们需要把屏幕空间中的像素位置变换到光源空间下,然后在光源空间下比较每个像素的深度值和阴影映射纹理中的值,如果当前像素的深度值大于光源深度图中的值,说明该像素在阴影中;