Cascaded Shadow Map总结

来源:互联网 发布:国籍 知乎 编辑:程序博客网 时间:2024/05/22 05:17

Perspective Aliasing

当渲染一个大场景的时候经常会出现阴影边缘锯齿的现象,这一现象称作perspective aliasing,如图1所示。当view space的像素和shadow map的纹素不是一一对应的关系时,即多个view space的像素对应到同一shadow map的纹素时就会产生这种阴影边缘锯齿状的现象。主要是因为在近平面处像素比较集中,需要一个更高分辨率的shadow map所导致,如图2所示。
图1.阴影边缘锯齿
这里写图片描述
图2. Perspective Aliasing产生原因,在eye space中蓝绿色占据了绝大部分的比例,在shandow map中蓝绿色只占据了很少的一部分
这里写图片描述
针对这一问题,人们想出了Cascaded shadow map(CSMs)的解决方案。

Cascaded Shadow Map算法

CSMs的基本概念是根据场景的远近来划分camera frustum,靠近camera的区域划分的较密,远离camera的区域划分的比较稀疏,这就使得靠近camera的区域能够使用一个相对较大分辨率的shandow map,减少失真现象。CSM的具体流程如下:

  1. 划分camera frustum成多个subfrusta;
  2. 计算每个小的subfrusta的包围盒;
  3. 对每个subfrustum生成投影矩阵;
  4. 对每个subfrusta生产一张shadow map;
  5. 对每一个像素选择合适的shadow map生成阴影。

Partition Frustum

原论文“Hardware-Accelerated Parallel-Split Shadow Maps.”里提出了一种分割方法,即把对数划分和均匀划分做混合。对数划分是经过原论文里推导出来的理想的划分方案,均匀划分的作用是和对数划分做一个混合,避免经过对数划分的subfrustum过大或者过小。

Calculate Subfrusta Bound

针对每个subfrusta的八个点,首先把他们从camera space坐标系下变换到世界坐标下,再从世界坐标系变换到light space下,然后计算一个AABB包围盒,把包围盒的近平面设为0,远平面不变计算投影矩阵,就可以用于渲染shadow map了,但是这样会使得shadow map的利用率不高,near到object1和far到object2之间的部分都被浪费掉了,如图3所示。
图3.使用率不高的shadow map
这里写图片描述

优化的远近平面

针对上述shandow map使用率不高的问题,在计算AABB包围盒后,还需进一步考虑场景中场景的位置,优化远近平面,如下图4所示。
图4.优化过远近平面后的shadow map
这里写图片描述

Render Shadow Map

根据投影矩阵的不同,把场景距离光源的深度信息写入不同的shadow map。

Render the Scene

渲染整个场景的时候需要对每一个像素选择合适的shadow map,由以下两种选择方法:

Interval-based cascaded selection

根据每个像素的深度信息选择不同的shandow map,这一方法快速简便。

Map-based cascade selection

从第0级开始,逐层判断当前像素对应的深度纹理坐标是否在这一层级内,这种方法计算量大,shadow map的分辨率利用较高。

CSMs with PCF and VSM

使用CSMs时还可以和PCF或者VSM结合起来使用,但是当层级过渡的时候,有可能会出现阴影裂缝,有一个方案可以去解决这个问题:先判断当前像素对应的深度纹理坐标是否在shadow map的边缘,如果在边缘,最后的阴影效果就是当前层级和下一层级进行线性插值的结果。

CSMs的问题

由于camera的属性会实时改变,其对应的frustum也会实时改变,而AABB对frustum的变化较为敏感,可能会导致前后两帧中AABB剧烈变换,造成阴影抖动的情况,针对这个问题可以使用另一种划分frustum的方法,即第一级包含第零级,第二级包含第一级等。这种方法会减轻由于camera剧烈变动带来的阴影抖动情况。

原创粉丝点击