笔记
先讲两个概念
软阴影、硬阴影
硬阴影:
● 应用于点光源
● 对于每一个像素,只需要检查该像素和光源之间是否有遮挡物存在即可,因此这种和像素一对一的可见性函数结果可以如同表面颜色一样,被存储在一个阴影贴图中,这种阴影的分布在表面上是一种非黑即白的效果。
软阴影:
● 应用于真实光源(面积或体积)
● 光源对于接受点,可能是部分可见的,因此这种部分可见性必须能够以某种方式被计算,这就要求每个观察点向光源发射多条光线来进行计算
● 目前主要有两大类方法来计算软阴影:
- 基于图像的方法:通过借助标准的阴影贴图技术,然后使用一些2D的过滤器来对边缘进行模糊处理(如PCF)
- 基于几何体的方法:如基于光线追踪的软阴影实现、基于距离场的软阴影实现。这些方法不使用阴影贴图,避免了阴影贴图的走样问题,但是有较高的计算成本。
实时阴影方案
主要分为两个方案:
- 基于几何:平面投影阴影、ShadowMap、CSM(级联阴影)、PCSS、基于光线追踪的软阴影、基于距离场的软阴影
- 基于滤波/图像:PCF、CSM(卷积阴影)、VSM、ESM
基于几何的阴影方案
平面投影阴影
阴影映射(Shadow Map)
原理
- 从光源位置渲染深度图片
- 从摄像机位置去渲染整个场景,将每一个像素点转换到光源坐标系下
- 与之前的深度图对比,当该片元的深度值大于深度图的深度时,也即产生了遮挡
阴影映射优化——自阴影
自阴影原理
由于Shadow Map的分辨率有限,离散的采样点以及数值上的偏差可能造成不正确的自阴影,也被称为Z-fighting或者阴影粉刺(Surface Acne)
解决方法:当比较深度时,需要设置容错阈值
● 深度偏移:增加深度偏移会使该像素向光源靠近
● 法线偏移:沿表面法线方向向外偏移
偏移单位是阴影映射的纹素
但是当深度偏移设置过大时,会导致漏光现象。即阴影与投影者之间发生脱节,也叫做Peter Panning问题
偏移原理
对于视锥的右侧蓝色点,加了偏移后可以认为不被红色点相应像素点遮挡,但是对于红点左侧,阴影就可能产生脱节,产生Peter Panning问题。
Unity中的偏移优化
- Shadow Caster阶段基于顶点的Normal Bias
- 在Shadow Caster阶段,让遮挡物进行反向偏移
● 性能高了
● 精准度低了
阴影映射优化——透视走样
透视走样,全称perspective aliasing
原理:在左图中,A、B点在shadow map中都占用1个像素,从摄像机位置观察A、B,会有更多的需