Search K
Appearance
Welcome
Appearance

是两趟的算法
第一趟,从点光源出发渲染出一张图(记录像素点出发最近物体点的深度信息),shadow map

第二趟,从相机位置,结合shadow map,渲染出一张图,这张图包含阴影。


自遮挡:由于shadow map是有分辨率的(它是光栅化后的深度图)因此其一个像素对应真实场景的一个面片,这些面片上的点记录的深度值都是一样的,但实际上这些值不应该一样,因此造成明暗交替的现象。光源与物体越平行,这种现象越严重。
解决自遮挡:
深度偏移bias:

但bias过大会导致漏光现象

second-depth shadow mapping (实际没有人用) 记录多个深度,除了第一个深度,还要储存次小深度
shadow mapping 给的是硬阴影,PCSS 给的是软阴影
回顾渲染方程 Lo(p,ωo)=∫Ω+Li(p,ωi)fr(p,ωi,ωo)cosθiV(p,ωi)dωi 其中V为visibility项 这个方程近似于(证明略,拿来用就行) Lo(p,ωo)≈∫Ω+dωi∫Ω+V(p,ωi)dωi⋅∫Ω+Li(p,ωi)fr(p,ωi,ωo)cosθi dωi 因此若要计算阴影,可以先做正常的shading(右边积分项),然后把可见项(左边分数项)乘上即可。
PCF(Percentage closer filtering)是做阴影抗锯齿的,但是也可以生成软阴影,filter约小越锐利(为1x1的时候一点抗锯齿都没有),filter越大阴影约模糊。
在shading point对应的shadow map上取一个框(eg.3x3)会得到一个矩阵⎣⎡111001110⎦⎤ 对其取平均0.667即为visibility,再乘以正常shading的结果得到阴影。 V(x)=∑q∈N(p)w(p,q)⋅χ+[DSM(q)−Dscene (x)]
注意:PCF并不是直接对shadow map做filtering,而是对shading point对应shadow map的点的周围一些点的深度值做filtering。若直接对shadow map做filtering结果还是有锯齿的。V(x)≠χ+{[w∗DSM](q)−Dscene (x)}
如果根据不同位置(blocker distance)的阴影取不同大小的filter(离遮挡物越远的阴影filter越大)做PCF,这便是PCSS。PCSS用了PCF的思想。

其中WPenumbra为半影范围也就是filter的大小,越大阴影越软。Blocker离Light越近WPenumbra越大,离Receiver越近WPenumbra越小 对于一个面光源来说其shadow map是按点光源生成的,点光源在中心位置。
WPenumbra =(dReceiver −dBlocker )⋅WLight /dBlocker
流程:

由于上述第一步和第三步都需要多重采样,因此速度会慢。那VSSM就是解决这两个问题。
可以用高斯分布的CFD或切比雪夫不等式
具体方法:
有了filter大小用来计算可见项大小,需要在shadow map上遍历filter大小的纹素,去算平均。但是如果我们已经知道有百分之多少的点对应的深度会被遮挡,那么就能直接得到可见项大小。
可以假设filter对应的shadow map大小的区域的深度值符合正态分布,使用一维高斯分布来估算可见项大小。
那如何确定高斯分布的均值和方差?
均值:1.mipmap 2.SAT
一维情况下,SAT表对应的算法是前缀和
二维情况下,SAT表是以左上角为起点的矩形范围的和
方差:\operatorname{Var}(X)=\mathrm{E}\left(X^2\right)-\mathrm{E}^2(X)
由此可以算出某一个shading point对应shadow map中的点的周围点(尺寸为filter大小)中有百分之多少概率的深度值大于shading point对应的深度值即为可见项的大小。
上述“百分之多少概率的深度值”可以用CDF计算近似
我们只是要得到“百分之多少概率的深度值大于”那不管它什么分布,可以直接用切比雪夫不等式估计(只需要知道期望和方差)P(x>t)≤σ2+(t−μ)2σ2
我们想要计算遮挡物的平均深度dBlocker(蓝色部分)

这个采样范围是由 Rblockersearch =WLight ⋅dReceiver ⋅c 计算得到的
NN1zunocc+NN2zocc=zAvg 我们想要得到zocc(遮挡物的平均深度),需要NN1的大小和zunocc的大小。 那么可以估算:
那么就可以计算zocc
解决VSSM的问题
使用SDF计算软阴影。
SDF上任意一点的值表示,以该点为球心,该值为半径的球不会触碰到任何物体。称这距离为安全距离
进一步,从shading point出发一条ray,可以求出“安全角度”,用安全角度估算可见项。 
可见项大小
\arcsin \frac{\operatorname{SDF}(p)}{p-o}
近似于
\min \left\{\frac{k \cdot \operatorname{SDF}(p)}{p-o}, 1.0\right\}
其中K控制阴影的软硬程度。
