Real-time Shadows

Shadow mapping

光和相机都能看到的点 = 不在阴影里的点

  1. 从光源看,记录深度

  2. 从摄像机看,计算点到light的深度并和从light看这个点的深度对比,相等则无阴影,不相等则有遮挡

自遮挡

  • shadow map 上每个采样点都代表一块范围的深度值,第二趟和第一趟比较深度时不一致,产生阴影。

解决:

  • 添加一个偏移值 bias,在一定误差内认为相等。

问题:

解决:

锯齿

硬阴影

解决锯齿问题

Percentage Closer Filtering(PCF)

有锯齿的阴影每个点非 0 即 1,要么是阴影要么不是。

PCF 对每个 shading point,在 shadow map 上找其周边(例如3*3)的点,最后取平均值,这样某个地方的值就是 0-1 之间。

实现软阴影

Percentage Closer Soft Shadow(PCSS)

PCF 中取一个较大的 Filter,就可以实现软阴影。但 Filter 的尺寸应该是自适应的。有点地方硬阴影,有些地方软阴影。

Filter 的 size 取决于 Light 的大小和距离。

PCSS的具体步骤如下:

  • 首先依据着色点选择一块范围,对 Shadow Map 做一次局部深度测试,找到范围内的 blocker 并计算其平均深度(计算平均深度的目的是减小遮挡物自身的几何影响,避免漏光)
  • 得到 d_blocker 后代入公式计算滤波范围, d_blocker 越小, d_receiver - d_blocker 越大,卷积核越大,得到的阴影就越软
  • 重新进行深度测试,继续完成PCF的过程

PCSS 可以通过减少采样来得到结果,例如 64*64 中采样三个点,但是会产生噪声。然而目前对于噪声的处理比较成熟,因此通常使用 PCSS。

VSSM

Variance Soft Shadow Mapping

PCSS 的 step1 和 step3 需要看一个区域的所有像素点,耗费时间。

VSSM 通过几种方法加速 step1 和step3

  • 求平均

    • MipMap
    • Summed Area Tables(SAT)
  • 求方差

    • $Var(x) = E(x^2) - E^2(x)$

只需要额外一张 shadow map 存储 $E(x^2)$,也可以放在两个 RGB 通道中。

知道方差和均值可以用高斯正态分布来计算有多少比例的像素点比 shading point 近。

可以通过数值解或者查表来解,但还是比较慢,采用近似。

  • N1:遮挡物格子数
  • N2:非遮挡物格子数
  • Z:深度

N1/N 可以用 Chebychev 不等式估计,非遮挡物平均深度假设都在同一平面全部相等。

SAT

Summed Area Tables

MSM

Moment Shadow Mapping

VSSM 中当一些环境简单的情况下,遮挡物的分布不会近似高斯分布。

VSSM 用 $Var(x) = E(x^2) - E^2(x)$ 两阶,但用更高的阶可以更接近。

SDF

Distance Field of Shadow

对每个点记录离物体最近的距离

Ray Marching

一般用于 Ray Tracing,光线可以行进 SDF(p) 的距离。

也可以用于生成软阴影,一个面光源和一个点生成一个锥形,通过最小的 SDF 来计算遮挡的比例,从而得到点的遮挡度。

遮挡比例需要用 arcsin 来计算,可以简化,k值可以控制阴影软硬程度。

三维中的距离场的可视化:

优缺点:

快,高质量,但是需要提前计算,需要存储,且不适用于形变物体。