Real-time Shadows
Shadow Mapping
2-pass Algorithm
- The light pass generates the SM
- The camera pass uses the SM
Image-space algorithm
- 不需要场景的几何信息
- 自遮挡、走样
Pass1:Render from Light
Pass2:Render from Eye
Issues: Self occlusion
一个像素内记录一个深度,在场景中,属于一个像素的一片区域,光源深度并不相同,更远的就被认为成阴影了。
解决方式:Bias
Adding a bias to reduce self occlusion,
比较深度时,增加bias,距离“明显”更远时才记为阴影。
新的问题:Bias引发的悬浮Peter Panning
(找一个合适的Bias)或:
Second-depth shadow mapping
用最小深度和次小深度的中间深度做最终的比较。(可用性不高)
Issues: Aliasing
Math behind shadow mapping数学解释
$$
\int_{\Omega}f(x)g(x)dx \simeq\frac{\int_{\Omega}f(x)dx}{\int_{\Omega}dx}\cdot \int_{\Omega}g(x)dx
$$
当g(x)足够光滑,g(x)的support较小,二者满足一个,该近似比较准确。
在Esp的IBL-Specular中讲述了同样的==split sum approximate==,
$$
L_o(p,\omega_o) = \int_{\Omega^+}L_i(p,\omega_i)f_r(p,\omega_i,\omega_o)\cos \theta_iV(p,\omega_i)d\omega_i
\\simeq\frac{\int_{\Omega^+}V(p,\omega_i)d\omega_i}{\int_{\Omega^+}d\omega_i}\cdot\int_{\Omega^+}L_i(p,\omega_i)f_r(p,\omega_i,\omega_o)\cos \theta_id\omega_i
$$
右边代表正常的着色,左边的可见项代表阴影,分开来算再乘起来,正是shadow mapping的思想。
Small support: point / directional lighting
Smooth integrand: diffuse bsdf / constant radiance area lighting
面光源、环境光照、glossy会不太准确
Percentage closer soft shadows(PCSS)
Percentage Closer Filtering(PCF)
用于阴影边缘的反走样,并不适用于软阴影
阴影比较的结果进行滤波
不能将shadow map滤波,因为记录的是深度。
对于世界空间的点,判断比较深度不光查找shadow map对应的一个像素,而是周围的局部区域的像素,每一个深度都进行比较,将这些值作平均
(如果是在阴影边缘,那么对应深度图上有阴影部分,也有照亮部分,这样能达到滤波效果)
Filter Size:
- Small->sharper
- Large->softer
将一个较大的PCF应用于硬阴影,就类似于软阴影效果
Percentage closer soft shadows
Filter size <-> blocker distance
阴影的软硬和遮挡物距离有关,也将决定filter size的不同。
$$
w_{Penumbra} =(d_{Receiver}-d_{Blocker})\cdot w_{Light}/d_{Blocker}
$$
$w_{Penumbra}$ 即衡量了软阴影的范围
- blocker size
- light size
完整流程
Tips: W_light是指定的,Shadow mapping需要用点光源。
- Step1:Blocker search(Slow)
- 对于一个着色点,在特定区域计算平均blocker深度(类似PCF)
- 这个区域可以是常量,也可以是启发式:
- Step2: Penumbra estimation
- 使用平均blocker深度,决定filter size
- Step3:Percentage Closer Filtering(Slow)
- 可以减少sample的数量来加速,但是会有噪声
Deeper Look at PCF
$V(x) = \sum_{q\in N(p)} w(p,q)\cdot\chi^+[D_{SM}(q)-D_{scene}(x)]$
而不是filter shadow map:
$V(x)\neq\chi^+{w*D_{SM}-D_{scene}(x)}$
也不是在图像上filter
$V(x)\neq\sum_{q\in N(p)}w(p,q)V(q)$
Variance soft shadow mapping(VSSM)
解决PCSS在step1和step3慢的问题
PCSS中做平均,其实就是知道区域内阴影和照亮的比例
Accelerate PCF
将shading point对应周围的点的最近深度看作正态分布
- 计算该区域深度的均值和方差
- 均值
- MipMap
- Summed Area Tables(SAT)
- 方差
- $Var(X) = E(X^2) - E^2(X)$
- $E(X^2)$ 项需要另外一个shadow map(square-depth map) 记录(总共只需要两个通道)
- 如果假设是正态分布CDF(x)(只有数值解,没有解析解)
- 切比雪夫不等式 $P(x>t)\leq \frac{\sigma^2}{\sigma^2+(t-\mu)^2}$ (甚至不需要知道分布函数)
- 均值
Accelerate PCSS
计算遮挡物的平均深度

$$
\frac{N_1}{N}z_{unocc}+\frac{N_2}{N}z_{occ}=z_{Avg}
$$
Approximation:N1/N = P(x>t) -> Chebyshev
需要 $Z_{unocc}$ 将其假设为t(shading point的深度->导致只有阴影接收物为平面时效果比较好)
MipMap and Summed-Area Variance Shadow Maps
构建SAT范围查询
前缀和算法
2D情况:
Moment shadow mapping
VSSM:在一些特定的遮挡物场景,分布与假设差别太大,可能偏黑,也可能过亮

切比雪夫不等式只有t>z_avg时有效
解决方式:Moment(矩) Shadow Mapping
VSSM只用了前二阶矩
用前m阶矩描述,可以恢复有m/2个阶跃的CDF

4阶也正好可以用4个通道存储。
问题:主要在于利用Moment的Reconstruction需要比较大的开销,至于如何reconstruction,比较复杂,如果要深入了解,去看论文。
Distance field soft shadows距离场阴影
- Distance functions:(Optimal transform)
- 空间任何一个点到物体表面的最小距离
Usage1:Ray marching
- Ray marching(sphere tracing) to perform ray-SDF intersection
- 在任意一点,到物体最小距离之内,不会和物体相交
- 因此在任何一点P,都可以走SDF(P)的距离
Usage2:Approximate percentage of occlusion
软阴影始终定义在面光源下

During ray marching
- 任意一点的SDF,能够提供一个“safe angle”
- Safe angle越小,能够看到的东西越少
- 在每一个step,计算眼睛出发的safe angle
- $\arcsin \frac{SDF(p)}{p-o}$ 运算量较大
- $min{\frac{k\cdot SDF(p)}{p-o},1.0}$ ,k越大,earlier cutoff of penumbra,阴影越硬
- 保留最小的safe angle,用来决定阴影软硬
- 任意一点的SDF,能够提供一个“safe angle”
特点
- 快速
- 高质量
问题
- 需要预计算
- 大量的存储空间
- Artifact