代码懒得写了,闲着没事儿读读PBR学习一下渲染中重要的理论基础,并且记录下来方便自己理解,顺便了解一下数学知识怎么运用~
1.傅里叶变换
1.1.Recap
这个数学课上都讲过了,分段光滑周期函数可以进行傅里叶级数展开,但是我印象最深刻的就只剩下这个东西了qwq所以从这里开始对着当时的讲义复习一下吧qwq
对于以2π为周期的周期函数f(x),有
f(x)=2a0+n=1∑∞(ancosnx+bnsinnx)an=π1∫−ππf(x)cosnxdxbn=π1∫−ππf(x)sinnxdx
实际上还可以写成复数形式,但是这里我们就不考虑了。
这里的π1不能掉了,因为标准正交函数系是2π1和πsin/cos
更一般的,做点简单的变量代换,对于以T为周期的周期函数f(x),有
f(x)=2a0+n=1∑∞(ancosT2nπx+bnsinT2nπx)
a0=π1∫−ππf(x)dx(看成n=0的cos项)
an=T2∫−2T2Tf(x)cosT2nπxdx,bn=T2∫−2T2Tf(x)sinT2nπxdx
对于任何绝对可积,有限区间上分段光滑函数,都可取区间[−2T,2T],周期延拓到R做展开(这里f(x)严格来说应该取其左右极限的平均值,为了减少码字量偷个懒~)
ancosT2nπx+bnsinT2nπx=T2∫−2T2Tf(t)(cosT2nπtcosT2nπx+sinT2nπtsinT2nπx)dt=T2∫−2T2Tf(t)[cosT2nπ(x−t)]dt
于是f(x)=2a0+n=1∑T2∫−2T2Tf(t)[cosT2nπ(x−t)]dt
对于不想要严格而又臭又长的证明的同学(比如我)来说,下面是一种不严格的理解:这个求和式长得很像黎曼和,这实际上就是相当于把[0,+∞)分成长为T2π的小区间求和
令F(λ)=∫−2T2Tf(t)[cosλ(x−t)]dt
可以看出
f(x)=T1F(0)+n=1∑T2F(T2πn)
=T1F(0)+π1n=1∑T2πF(T2πn)
令T→+∞得到
f(x)=π1∫0+∞∫−∞+∞f(t)cosλ(x−t)dtdλ
里面的积分关于λ是偶函数,亦可写作
f(x)=2π1∫−∞+∞∫−∞+∞f(t)cosλ(x−t)dtdλ
这就是傅里叶积分的收敛定理
考虑到cosx=2e−ix+eix
于是将其写为
f(x)=2π1∫−∞+∞∫−∞+∞f(t)2e−i[λ(x−t)]+ei[λ(x−t)]dtdλ
=2π1∫−∞+∞∫−∞+∞f(t)2e−i[λ(x−t)]+ei[λ(x−t)]dtdλ
=2π1∫−∞+∞∫−∞+∞f(t)2e−i[λ(x−t)]dtdλ+2π1∫−∞+∞∫−∞+∞f(t)2ei[λ(x−t)]dtdλ
再次利用这个反常积分关于λ为偶函数的重要性质,发现前后两项实际上是相等的,于是得到
f(x)=2π1∫−∞+∞∫−∞+∞f(t)ei[λ(x−t)]dtdλ
=2π1∫−∞+∞eiλx∫−∞+∞f(t)e−iλtdtdλ
这就是我们熟悉的傅里叶变换式了
显然,上述过程是极不严格的,收敛性和一致性都没有证明,但是严格的证明我懒得研究了,就把这个重要的式子理解就好~
这里PBR书上有个注释,意思是说,在不同领域使用的傅里叶变换定义式不完全相同。的确如此,我的微积分讲义上给出的傅里叶变换直接用的λ的含参量积分,而PBR书上的含参量积分与此不完全相同。下面都以PBR为准。
把两个积分拆开,并且令λ=2πω进行换元,这是为了契合PBR书中的符号(当然,这也是符合物理意义的,λ是波长,ω是转速),我们有函数f的连续形式的傅里叶变换和傅里叶逆变换
F(ω)=F{f}=∫−∞+∞f(x)e−2πiωxdx
f(x)=F−1{f}=∫−∞+∞F(ω)e2πiωxdω
出于简便起见,PBR特别强调只考虑偶函数f(x),我们也只考虑偶函数,这样一来,我们又可以对F(ω)进行化简
F(ω)=F{f}=∫0+∞f(x)e−2πiωxdx+∫−∞0f(x)e−2πiωxdx
=∫0+∞f(x)(e−2πiωx+e2πiωx)dx=∫−∞+∞f(x)cos(2πωx)dx
上面我们利用偶函数的性质把两个e的幂之和合并为同一个e的幂,这里我们其实也是在利用偶函数的性质反着做回去。
有了这个式子,我们发现很好的一点:表达式中不出现虚数单位i。这意味着我们得到了一个实值函数。
此外,我们还发现这个式子很像最开始傅里叶级数中三角函数系数的式子,在那里我们用积分定义了新的点积,并且用这个点积“提取”一个周期函数中某个频率的振幅(其依据是三角函数的正交性)。
那么按照类似的理解,这里的积分式也可以看成是“提取”ω频率的振幅(当然,需要严格的证明),我们就知道了F(ω)这个实值函数的意义。也就是大家熟悉的说法,傅里叶变换将时域变换到频域。
值得一提的是,傅里叶变换算子F满足线性性,这个性质是大家都知道的。
值得二提的是大家都知道的“卷积定理”,后面会有叙述。
这一块的数学实在是太多辣,可以参考一下某篇咕咕日报23333
1.2.常见信号的傅里叶变换
PBR书中给了一个小表格,列出了一些常见的信号和它们的傅里叶变换,但是没有给出推导。
1.2.1.盒子函数
当且仅当∣x∣<21时f(x)=1,否则f(x)=0
F(ω)=F{f}=∫−∞+∞f(x)cos(2πωx)dx=∫−2121cos(2πωx)dx
=2πω1sin(2πωx)∣∣∣∣−2121=ωπsinωπ
可能是这个函数太常用了,甚至有个专门的名字sinc(ω)=ωπsinωπ。
后面还会见到更一般的形式ΠT,经过伸缩变换可给出F{ΠT}=2Tπωsin2Tπω
1.2.2.高斯函数
f(x)=e−πx2
F(ω)=F{f}=∫−∞+∞f(x)cos(2πωx)dx=∫−∞∞e−πx2cos(2πωx)dx
这个积分还是不难求的,利用含参量积分的求导就可以算。当然,我们要有一致收敛性,连续性以及原积分在某点收敛才能进行下面的运算,但是这里略去,自证不难。
F′(ω)=−∫−∞+∞2πxe−πx2sin(2πωx)dx
=∫−∞∞sin(2πωx)de−πx2
=sin(2πωx)e−πx2∣∣∣∣−∞+∞−∫−∞+∞e−πx2dsin(2πωx)
=−∫−∞+∞2πωe−πx2cos(2πωx)dx=−2πωF(ω)
不出意外,我们得到了一个想要的微分方程,而且它很好解,不过这里还是列出解的过程,把 F(ω) 除过去就有
dln∣F(ω)∣=−2πωdω=−πdω2,于是
F(ω)=Ce−πω2,代入 ω=0 的边界条件(这是经典的高斯积分,∫−∞∞e−ax2dx=aπ)就能得到 F(ω)=e−πω2
真棒啊,高斯函数傅里叶变换前后是没有变化的。
1.2.3.常值函数
考虑f(x)=1,我们发现反常积分是发散的,当 ω=0 时反常积分为正无穷大,对此,有一个专门的函数叫做狄拉克函数δ,它只在 0 处取值无穷大(虽然在实数域下是发散的,但是它在广义实数域下还是有值吧qwq),其它情况下取值均为 0 。
关于狄拉克函数还可以多说几句,这是个广义函数(广义函数的定义可以参考卓里奇但是我忘记了)。不过这也没什么关系。实际在渲染中,狄拉克函数经常用来表示一些有奇异的东西,比如完美的反射/折射的 BSDF。
不过有些教学渲染器为了使代码更加一致选择用粗糙度极小的微表面模型来近似镜面因为狄拉克函数这么不一致的东西会带来很多麻烦。
回到正题上来,于是有 F{f(x)=1}=δ(ω)
上面的说法当然是不严格的,严格的我也不会qwq
网上应该有很多资料,现在只要记住这个特殊函数就好啦。
狄拉克函数有个很重要的特性:∫f(x)δ(x)=f(0)
1.2.4.余弦(正弦)波
f(x)=cosx,用积化和差公式可以容易地算出(其实是我懒得算懒得写啦)
F(ω)=F{f}=π[δ(1−2πω)+δ(1+2πω)]
1.2.5.Shah函数
也称狄拉克梳状函数,但是PBR上的符号我不知道怎么用Latex写,所以用III模拟一下吧~
Shah 函数的定义为 IIIT(x)=Ti∑δ(x−Ti)
,这可以理解为是在 R 上以周期 T 等距离采样
其傅里叶变换结果为
F(ω)=F{f}=IIIT1(ω),真棒啊。
2.理想的采样与重建
结束了一节不算很难的数学基础,开始正式进行采样与重建理论的解释了。
前面提过,以周期T采样其实就是IIIT(x)=Ti∑δ(x−Ti),T定义了周期,或者说是采样率。那么采样的形式化定义其实应该是这样的一个函数:
IIIT(x)f(x)=Ti∑δ(x−Ti)f(iT)
看着很唬人,其实意思就是说我们在一个连续函数上等间距取了一列离散的可数点。。。由离散的点得到一个连续的函数称为重建,或者说,把这些离散的点“连起来”,显然我们有很多种方式把点连起来。
重建的形式化定义需要使用函数的卷积,类似于数列的卷积,我们可以定义函数的卷积积分为
f⊗g=∫−∞+∞f(t)g(x−t)dt
傅里叶变换很好的一个性质就是卷积定理:时域卷积,频域乘积;频域卷积,时域乘积。
F{fg}=F{f}⊗F{g}
F{f⊗g}=F{f}F{g}
我们可以选取一个重建滤波函数r(x),那么重建的过程实际上是得到如下函数:
f~=(IIIT(x)f(x))⊗r(x)=T∫−∞+∞i∑δ(t−Ti)f(iT)r(x−t)dt
=Ti∑∫−∞+∞δ(t−Ti)f(iT)r(x−t)dt
这里我们又一次不加证明地交换了无穷求和与反常积分。由于狄拉克函数的性质,后面的积分实际上等于f(iT)r(x−iT),于是
f~(x)=Ti∑f(iT)r(x−iT)
这东西就变成数列卷积了,下面来探讨其意义。闫令琪曾经在GAMES101里提过,卷积实际上是在频域上将图像复制并且平移,PBR下面就要得到这个结果。为此,PBR首先限制f的频率是有穷的,这意味着对f做傅里叶变换后得到的F(ω)只在一个有界区间上可能非0。
在上面的推导中其实隐含了一个重要的结果:一个函数与狄拉克函数进行卷积得到的函数是该函数本身,而如果我们对狄拉克函数进行平移再卷积,那么得到的函数也进行同样的平移,即
f(x)⊗δ(x−a)=∫−∞+∞δ(t−a)f(x−t)dt=f(x−a)
我们将f~变换至频域,即有
F{f~}=(F{IIIT}⊗F{f})F{r}
=(IIIT1⊗F{f})F{r}
=[IIIT1(ω)⊗F(ω)]F{r}
我们知道,Shah函数实际上就是一堆平移了的狄拉克函数之和,因此IIIT1(ω)⊗F(ω)实际可解释为所有将F在频域上平移Tk(k∈Z)的函数的和,反映在频域图像上,就好像我们为函数F创建了无穷多的“副本”一样,这就是闫神在课上提到过的含义,也是“采样”过程对于函数频域的影响。
至于这个T,我们是可以人为选取的,只要我们的T选取的足够小,T1足够大,使得F平移之后的图像不发生重叠,就可以保留F的信息。更具体的,采样频率大于等于f频率的两倍就可以,这就是奈奎斯特采样定理。
因此,若要从采样以后的函数IIIT(x)f(x)获得原本的函数f(x),实际只需保留F(ω)在原点处的那一份“副本”即可,我们可以通过乘上一个盒子函数ΠT(x)来做到,ΠT(x)仅在∣x∣<T时取值2T1,其它情况下取值均为0。
因此,我们只要取F{r}=ΠT就可以还原出f,这是容易验证的,而盒子函数的傅里叶反变换是sinc函数,理论上讲这就能完美还原出f了。
看起来实在是太好了。遗憾的是,sinc函数本身的频率是无限的,或者说,sinc压根就不是个周期函数,如果真的取r=sinc,我们还得对所有采样值进行无穷求和才能还原任意处的f。因此,实际操作中使用的滤波函数往往是频率有限的,但是效果怎么样就不好说了。
以图形学反走样时最简单的滤波方法为例,我们常常对一个像素区域内进行超采样,然后直接做平均值,这实际上就是一个二维的盒子函数,对应到频域上,实际是在用sinc乘以F,效果自然不甚理想。
3.走样
3.1.Recap:GAMES101
然而实际上我们要面临的问题不仅仅是sinc是无穷的。f本身的频率常常也是无穷的,这样一来,我们不能将F{f}的图像限定在一个有限区间上,用无穷的语言来描述:
∀ω0>0,∃ω s.t.∣ω∣>ω0,F{f}(ω)=0
这时我们不能在一个有穷的区间上考虑F的频域图了,而且将F平移几乎不可避免地会引起频域信号的混叠,这也意味着有限的采样率几乎上不可避免地会引起信息的丢失。此外,按照前面提过的说法,对于频率有限的信号,若采样率不足够,也会引起频谱的混叠与信息的丢失。这正是闫令琪在GAMES101上讲过的观点。此时如果将频谱截断,就产生了走样。
不幸的是,图形学里的信号频率常常是无穷的。实际上,任何不连续函数的频率都是无穷的。因此,除了对采样率本身的修正,我们还要考虑其它的办法来进行反走样。
3.2.反走样
3.2.1.非一致采样
给一个随机偏差ξ∈[0,1],采样函数是i=−∞∑+∞δ[x−(i+21−ξ)T]
因为随机所以图像会有噪点,但是走样就没那么明显。
3.2.2.适应性采样
在高频信号处多采样,但是实践起来较困难,很难判断一个区域内部信号频率与采样率的关系。对邻接点判断变化速度的办法在实际上没有什么走样的时候往往会差异较大。
3.2.3.预过滤
所谓预过滤,其实就是在采样之前先对函数做模糊,砍掉高频信号使得在当前采样率下不会发生走样。当然,这么做损失了信息,图像模糊了,但是相比于走样还是要好些。
我们之前提到过对采样得到的函数f~的频谱乘上盒子函数来过滤掉高频信息,这实际上也可以对f做,如果f的频率是无穷大的,在频域上乘上一个盒子函数就砍掉了f的高频信息,这相当于对f做卷积。
假设采样频率是ωs,我们只需要算f⊗sinc(2ωsx)就可以了,当然直接用sinc的卷积是不好做的,但是我们可以用其它函数来做这个事情,只要这些函数的频域表示跟最理想的sinc足够接近即可。
4.应用至图像合成
实际中我们可以把渲染得到的图像看作是一个二元函数f(x,y),其值为对应点得到的Radiance。
好消息是,光追可以算出任意点的f(x,y),坏消息是,这样基本不可能在采样之前预过滤。这样一来,我们能用的还是非一致采样或者适应性采样。
5.渲染中走样的来源
一种是几何走样。物体的边界投影至屏幕时,几乎一定会产生颜色的跃变,使得图像信号不连续。此外,极小的物体(尺度小于采样率)也会。
另一种是着色走样。一方面来自于不正确的纹理过滤或者高光,另一方面来自于阴影。
尽管检测物体表面的边界不是没有办法,但是检测阴影的边界要难得多。
6.像素到底是什么
PBR书说,关于像素有两点需要牢记的观点。首先,像素是整个图片在离散的点上进行采样后重建的结果,点是没有面积的。Alvy Ray Smith指出:把像素看成有面积的小方块是不正确的心理认知,会导致一系列的错误。
第二个观点是,像素自然而然都是整数点处的信号值,但是采样可以在浮点数坐标上进行。要想把R2上的颜色映射到N2上,最简单的方法就是取距离最近的整数点——这和像素的含义已经差不太多了,唯一的遗憾是有一个21的偏移,这个小细节如果在撸码的时候忘记了,有时候会造成微小的错误,所以在定义这个映射的时候就把21的偏移加上,就方便多了。
到此,理论基础就结束了,PBR书中接下来会详细介绍它的采样方法。。。有机会再写吧。