阴影

阴影的数学推导

这是实时渲染中常用的约等式

image

这个约等式如果满足以下两个条件中的至少一个,则成立

  1. small support: 积分域比较小
  2. smooth integrand: \(g(x)\)比较平缓,没有大的波动起伏

在实时渲染中,我们会给the rendering equation加上一个\(V\)项,代表可见程度

image

通过用上述的约等式,改写成

image

其中提出来的部分就代表我们要求解的阴影,其余的就是常规的shading

根据我们上述提出的,这种形式的the rendering equation需要至少满足其中一个条件

  1. small support:点光源、平行光
  2. smooth integrand: diffuse材质会让BRDF均匀;单个面光源会让radiance比较均匀

硬阴影

算法

这是最原始的,在光栅化中生成阴影的算法,步骤为

  1. 将相机放在光源处,根据场景在每个pixel中记录一个最小深度,得到一张深度图,叫做shadow map

image

  1. 将相机放回观察处,对场景渲染,在每一个pixel记录的场景位置,和光源做一个连线,计算深度h,再找到深度图中该连线对应像素的深度h',如果 h 不等于 h',则产生阴影

image

存在问题

Self-Shadow Aliasing

image

因为我们在shadow map中,每一个pixel都记录了一个深度,但场景中的点的数量是远远大于pixel的数量的,shadow map只是离散地采样了场景
我们往往用每个pixel中心的点来采样,代表这一块区域的深度,但一块区域内的深度往往是会有变化的
光源和地面法线夹角越大,区域内深度变化就越大,导致有可能在同一块区域,shadow map记录的深度和第二次渲染找到的深度有一定差距,而错误地得到了阴影

image

我们通过给深度加上一个bias,来解决这个问题,也就是只要深度差不超过bias,就不会生成阴影
slope scale bias是一个动态的bias,光源和地面法线夹角越大,bias就越大,更符合实际情况

Detached Shadow

在加上bias之后,在一些位置阴影会发生缺失

image

这是因为影子和遮挡物的距离比较近,这个距离有可能会bias抹去了,导致不生成阴影

PCSS

PCF

Percentage Closer Filtering是用来抗锯齿的算法,但同时也是生成软阴影的方法

image

核心在于,在第二次渲染时,原本是对每个fragment,查询shadow map中对应pixel的深度进行比较
现在是对每个fragment,查询shadow map中对应pixel所处的一片范围里每个pixel的深度,将fragment与该范围里每个pixel的深度一一比较,每个结果记录在一个矩阵中对应的位置
然后对该矩阵做一个卷积得到一个阴影值,代表该fragment的可见程度

image

算法

生活中,阴影的软硬程度是随着影子与遮挡物距离而变化的,距离越近影子越硬朗

image

PCSS的思路就是在距离比较小的地方,用比较小的卷积核做PCF,得到比较硬的阴影,否则用比较大的卷积核,让影子变软

这是我们建立的抽象模型,将距离与半影长度建立了联系

image
image

PCSS的算法步骤如下

image

其中blocker depth我们需要的是一个范围的平均blocker depth
这个范围我们通常通过如下方法来找到
将shading point和光源做连线得到一个锥体,锥体与shadow map相交的部分就是要求的范围

image

PCSS的数学形式,\(w\)代表加权的权值, \(\chi^+\)使得深度比较值变为0或者1

image
image

VSSM

算法

在PCSS中,第二次渲染时,我们用shadow map中的一块区域来和shading point比较,然后做卷积
在VSSM中转化为,找到该shading point的深度\(t\),和shadow map该区域中深度分布\(P\),求\(P(x>t)\)

我们将切比雪夫不等式看作一个约等式,来求\(P(x>t)\)

image

使用切比雪夫不等式时,其中\(\mu\)在记录shadow map时就记录下来

\(\sigma\)我们通过这个方程来计算

image

所以shadow map中还要记录深度的平方\(x^2\),用来计算方差

VSSM也能将找平均blocker depth的步骤加速

image

我们把阴影接收部分看作一个平面,这样我们将\(z_{unocc}\)看作一个常数,也就是shading point的深度\(t\)
这样就可以计算出\(z_{occ}\)

SAT

Summed Area Table是用于范围求和的算法
我们可以用于快速查询shadow map中区域的\(\mu\)

SAT中每个点记录的是从左上角到该点覆盖的矩形区域的和
可用于快速查询任意矩形的和

image

存在问题

切比雪夫不等式的约等形式只在\(t>\mu\)时比较准确,如果超出这个范围可能会出现问题,比如light leaking
概率可以用Moment Shadow Mapping等算法估量得更加准确

image

我们把\(z_{unocc}\)看作常数在一些情况也会出现问题

image

Distance Field Soft Shadow

算法

Distance Field Soft Shadow可以高效计算出软阴影

SDF(Signed Distance Field) 的意义是,记录了三维场景中每个点,到离该点最近的物体的距离

渲染一个点的阴影时,算法先是用了ray marching的思想
从shading point向光源做ray marching,每次走SDF的长度,直到SDF收敛到一定程度(与物体发生接触)

Distance Field Soft Shadow的思路在于
在每次marching抵达的点,计算遮挡物与shading point连线和光源与shading point连线的夹角
找到所有计算得到的角度中最小的夹角,这个夹角越小,代表遮挡程度越大,阴影越深
image

image

这个夹角本应该用arcsin来解,但我们用如下右侧的方程来拟合,k是人为给定的系数
把阴影控制在[0,1],如果k越大,阴影效果越容易达到饱和,影子就越硬,否则就得到较软的阴影

image

image

存在问题

SDF需要预计算,一个三维空间的SDF需要大量存储空间

这种算法也会造成瑕疵,叫做banding effect
在ray marching时,因为是离散地采样光线上的角度,会出现无法找到光线上最小角度的情况,就会出现light leaking
特别是在遮挡物是一个角(sharp corner)的时候,就容易发生这种情况

一个算法是,在ray marching每相邻两个采样点之间再加多一个采样点
如图,红点和绿点是原采样点,黄点是容易导致light leaking的地方,所以再加多一个采样点

image

如下是改进的效果
image

posted @ 2022-07-15 12:01  wcvanvan  阅读(421)  评论(0)    收藏  举报