【CG Fundamentals】07_阴影
作者:互联网
1概述Shadow Map
1.1传统的阴影映射技术 Traditional Shadow Map
① 使用第一个pass将模型变换到光源空间,存储距离光源最近的深度值,生成阴影映射纹理shadow map。注意,不同类型的光源在生成shadow map时是有细微差别的:聚光灯生成阴影映射纹理的过程和摄像机生成深度纹理的过程很相似,在将模型变换到光源空间后,将椎体内的模型变换到NDC坐标下并记录深度值,得到的深度值是非线性的;点光源生成阴影映射纹理时会使用cubemap(具体细节还不是很清楚,后续补充);平行光生成阴影映射纹理的过程和摄像机生成深度纹理的过程也比较相似,但方向光会使用正交投影矩阵而非透视投影矩阵,得到的NDC坐标下的深度值是线性的。
② 使用第二个pass将模型变换到光源空间(具体来讲应该是NDC坐标),使用xy分量对阴影映射纹理进行采样,并比较采样所得的深度值和光源空间下的深度值,从而判断片元是否在阴影中。
1.2屏幕空间的阴影映射技术 Screen-Space Shadow Map
① 使用第一个pass将模型变换到摄像机空间,存储距离摄像机最近的深度值,生成深度纹理;使用第一个pass将模型变换到光源空间,存储距离光源最近的深度值,生成阴影映射纹理shadow map。
② 使用第二个pass做阴影收集计算。对屏幕空间中的每一个像素,根据其深度纹理中的深度信息,还原其在世界空间下的坐标,转换到光源空间后使用xy分量对阴影映射纹理进行采样。比较采样所得的深度值和光源空间下的深度值,从而判断片元是否在阴影中。
2缺点与改进
2.1脏
原因:在比较采样所得深度值与光源空间下的深度值时,由于数值精度不够,导致判断错误,使得画面出现不连续的阴影值,看起来“脏脏”的。
Fig.1. 脏脏的画面
解决:使用bias,如光源空间下深度值大于采样所得深度值加bias时,才判断点在阴影中。
2.2自遮挡
原因:当光线与模型表面接近平行时,距离很近的像素会映射到同一个阴影映射纹理的纹素上,从而产生自遮挡现象,也被叫做阴影失真现象shadow acne。
Fig.2. shadow acne现象(左图)和peter panning现象(右图)
解决
² Variable Bias
使用bias,如光源空间下的深度值大于采样所得深度值加bias时,才判断点在阴影中。且bias是可以随光线与表面夹角而改变的,当光线垂直于表面时bias可以较小,当光线平行于表面时bias可以较大。
但不合理的bias可能会引发新的问题,如过大的bias会导致阴影在物体交界处消失,产生阴影悬浮现象peter panning。
² Second-depth shadow mapping
在记录深度纹理和阴影映射纹理时,不仅记录最小深度值,还要记录次小深度值,然后取两个深度值的中间值作为深度比较对象,这样可以很好地防止peter panning现象的发生。
Fig.3. second-depth shadow mapping
但此方法也有另外的缺点:
① 模型必须是双面的,否则无法计算midpoint;
② 记录次小的深度值会增加开销。
2.3透视走样
原因:透视走样指的是近处阴影出现锯齿但远处阴影没有锯齿的现象。透视走样有两个产生条件,①摄像机使用透视模式,②光源使用平行光。当光源为平行光时,阴影映射纹理会渲染整个场景(光源的orthographic box非常大),此时对同样分辨率的阴影映射纹理而言,相比其他光源,平行光的阴影映射纹理会用很少的纹素记录同样的模型深度信息,导致摄像机视锥体内靠近近裁剪平面的多个片元会映射到阴影映射纹理的同一纹素上,摄像机视锥体内靠近远裁剪平面的多个片元反倒不容易映射到阴影映射纹理的同一纹素上(在屏幕空间同等距离的片元对还原到世界空间后,靠近远裁剪平面的片元对的距离会更大),导致近处出现锯齿而远处无锯齿的透视走样现象。
解决:Cascaded Shadow Mapping.
将摄像机的视锥体分成n个部分,对每一部分的视锥体进行从摄像机空间到光源空间的坐标变换,对光源空间下的每个视锥体生成最小包围盒,对n个包围盒内的模型生成单独的阴影映射纹理,在判断片元是否被遮挡时,根据片元到摄像机的距离选择合适的阴影映射纹理。这样,靠近摄像机视锥体近裁剪平面的模型会有更精细的阴影贴图(因为场景尺寸变小了,而阴影贴图的分辨率没变)。
Fig.4. 将摄像机视锥体分成三部分并生成三张shadow map的案例(箭头是光源方向)
3软阴影Percentage Closer Soft Shadows
3.1 Percentage Closer Filtering
在不使用PCF的Shadow Mapping中,我们通过比较光源空间下的深度值与采样所得的阴影映射纹理上的深度值来判断片元是否在阴影中,判断结果非0即1,因此只能产生硬阴影。而当使用PCF时,我们将阴影映射纹理上的采样点从一个纹素拓展到一个box内的纹素,这样就能得到片元在一块区域内的遮挡情况(如7x7的box得到7x7的阴影值),取均值后得到可见性值,这个值是一个浮点数。这个技术最初是用于抗锯齿的。
3.2 Percentage Closer Soft Shadows
当PCF的filter box的尺寸较大时,显然可以得到软阴影。而为了使阴影符合“距离遮挡物近处更硬、距离遮挡物远处更软”的自然规律,我们可以对不同的片元采用不同尺寸的filter box,而filter box的尺寸和片元到遮挡物的距离及遮挡物到光源的距离相关(如Fig.5)。
Fig.5. 面光源大小、遮挡物高度与半影大小间的关系(左)和对应公式(右)
因此PCSS的算法如下:
① 计算片元对应的一块区域内的遮挡物(只有遮挡片元的纹素才计入)的平均深度值,区域大小可以是恒定的;
② 利用Fig.5中的公式计算片元对应的filter box的尺寸;
③ 使用PCF计算片元的可见性。
标签:07,映射,Fundamentals,光源,CG,阴影,片元,深度,纹理 来源: https://www.cnblogs.com/rbcl-ljh/p/14603298.html