如果光源发出的光由于受其他物体(遮光体)阻挡而不能到达某个物体(接受体)时,就会产生阴影。我们将考虑仅有点光源投影的简单光照模式。使用点光源时,来自光源的所有光线到达接收体上的一个点,或者所有光线都被遮光体阻挡。这种模式下将创建出硬阴影,是实际不存在的一种阴影;因为这些阴影会在接收体的光照区域和阴影的区域间产生明显的(即硬的)边缘。在空间中占据一定体积的光源会产生软阴影,即接收体只受到光源的部分光照(图 2)。
图 2:仅从一个点采样的光源形成一个硬阴影。从整个光源采样的光线产生比硬阴影小的半影和本影。Lance Williams 在 1978 年引入了阴影贴图。
3阴影贴图的基本思想是光源仅照亮可从光源看到的物体。要计算光照,必须先确定场景中可从光源看到的点。阴影贴图可将场景中最接近光线的点的距离存储起来。计算某个点的光照时,将根据阴影贴图中的对应值测试该点到光线的距离。I如果该点到光线的距离值等于阴影贴图中存储的值,则该点就被照亮。如果该点较远,则必定存在更靠近光线的物体,因此该点处在阴影中。
要创建阴影贴图,我们将从光线的视角来渲染场景,并在每个像素上存储深度值。正常情况下,贴图以纹理的形式存储。标准的场景渲染提供了一种在场景中对物体排序的快速方法,使我们可以忽略场景几何形状的呈现方式。我们在渲染场景时,必须将每个点转换为光线的透视空间,并计算点到光线的距离。然后,将此距离与贴图中存储的值进行比较。如果该点到光线的距离大于贴图值,则在光线和该点之间必定存在一个遮光体,因此该点处在阴影中。
阴影贴图因其简单的特性而特别有用。我们不需要对场景中的几何形状施加任何限制;如果我们能渲染场景中的物体,就能生成阴影贴图。阴影贴图的数量以及相关的存储要求与场景的复杂性无关,与光线的数量成线性关系。因为我们使用了高度优化的硬件,所以生成阴影的速度很快。此外,由于阴影与观看者在场景中的位置无关,因此,光线或场景中的物体移动时,我们只需要重新计算阴影贴图。
阴影贴图有精度的限制。由于各个进程多次转换场景中的点,因此会累积浮点错误。这可有会导致程序画出不正确的阴影区域。低分辨率模式也会产生问题,因为该模式似乎会对自身投影。此外,每次像素分析的固有失真比较明显。主要的失真问题来自用于生成阴影贴图的样本。阴影贴图是在光源的透视空间中创建的,但用于确定来自相反角度的光照:视图的透视空间。如果这些因素匹配得不好,则视图空间中的许多像素将与阴影贴图中的相同采样点对应。
阴影贴图技术概括: