Unity 自阴影的锯齿产生原因分析
- By losuffi
- 周三 20 十一月 2019
Unity的默认阴影实现方式是传统的ShadowMap,这种利用光照空间渲染光照深度贴图的做法,容易产生阴影锯齿,而且即使调整阴影贴图的分辨率,也得不到有效的解决。
1.ShdowMask阴影方式工作流程介绍
观察FrameDebug,有一个单独光照深度贴图写入的Pass,大概可得出如下流程:
graph TD
s[光照深度贴图生产Pass]-->0
0(剔除超出阴影范围的Object)-->A
A(DrawCall)-->B(写入光照空间深度贴图)
d[阴影渲染Pass]-->C(遮挡剔除)
C-->D(Drawcall)
D-->E(转换该屏幕空间坐标到光照空间拿到光照深度贴图取值UV)
E-->F(拿到该UV在光照深度图下的深度以及该点在光照空间下的Z值)
F-->H(返回两者的Compare值)
H-->G(将返回值保存在屏幕阴影贴图中)
大体过程如此,至于后续的CSM本质上是阴影贴图渲染多次DownSample操作。与后续内容没太大影响
2. 会产生阴影锯齿的原因
在某种情况下,在光照空间下的物体边缘的一个像素点,在相机空间下是一列像素点。比如光垂直射下,而我们水平观察。 这样由于锯齿,就会导致该像素点的列,读取到的阴影可能是明暗相间的。
如果在光照空间下, 关注 物体的 明暗边缘,由于三角片的原因 导致那一列的 光照空间UV 是同一个值,那么 由于锯齿,就会造成 相机空间下,阴影的锯齿~