1.4 采样和反走样
3D图像的生成本质上是一个对各种连续函数(如几何图形,BRDF分布函数,光照场等)采样,然后转化为对应的一个离散函数(以有限分辨率表示的一个二维图像)的过程。3D渲染的大部分采样发生在光栅化阶段,或者其他由光栅化导致的采样,例如第1.3节图(11)中,三角形两个顶点之间的边是连续的,但是被光栅化过程采样为离散的像素值。
在数字信号处理(digital signal processing)中,术语采样(sampling)的目的是将连续的信号表述为离散的信号,在采样的过程中,其中的一些信息会丢失;为了重建(reconstruction) 原始连续信号,则需要对离散信号使用过滤(filtering)技术来还原原始连续信号,如图1所示。
图(1):在数字信号处理的过程中,一个连续的信号(左图)被采样为离散的信号(中图),然后通过重建还原为接近原连续信号的连续信号(右图)
以下我们就首先来讨论采样和重建这两个数字信号处理的基本过程,然后介绍一些由于采样不足导致的走样的概念以及其一般解决方案。
采 样
关于采样的理论非常复杂,它涉及傅里叶变换,积分,级数等数学知识,以及像频率域等滤波相关的概念。然而理解采样相关知识是理解走样相关知识的重要理论基础,而且在图形学的其他一些地方也会涉及这些知识,例如在光线追踪技术中就会大量涉及脉冲函数。此外,理解傅里叶变换也有助于理解后面的如小波变换,球谐函数等概念。但本节不会严格地推导和讨论傅里叶相关的知识,而只是使用一些结论让读者比较容易地理解采样相关的概念及逻辑,本书后面的内容还会反复更深入地讨论傅里叶变换相关的知识,更多关于数字图像处理的理论知识,可以参考[cite b:DigitalImageProcessing]。
法国数学家傅里叶(Jean Baptiste Joseph Fourier)于1807年在他的《热分析理论》一书中指出,任何非周期(但该曲线下的面积是有限的)的连续函数可以用正弦和/或余弦乘以一个加权函数的积分来表示,这个积分方程称为傅里叶变换(Fourier transform)。用表示连续变量的连续函数的傅里叶变换,则:
(式1)
其中,表示正弦项或余弦项的频率,由于被积函数中的变量被积分,所以上式的结果为变量的函数。
对于任何周期函数则可以使用傅里叶级数,表示为不同频率的正弦和/或余弦和的形式,每个正弦项和/或余弦项乘以不同的系数。例如具有周期的周期函数的傅里叶级数为:
(式2)
其中:
(式3)
相反,给定,通过傅里叶反变换可以获得:
(式4)
利用欧拉公式,可以把式(1)表示为:
(式5)
我们看到,由于变量被积分后只剩下,所以傅里叶变换的作用域是频率域。频率变量的单位取决于的单位,例如,如果表示单位为秒的时间,则的单位为周/秒,如果表示单位为米的时间,则的单位为周/米。
从广义上讲,频率域(frequency domain)表述的是一个连续函数在它的作用域上的改变有多快,所以一个函数通常有多个频率,这些频率构成该函数 的一个频率谱(spectrum of frequencies)。傅里叶变换正是将一个连续非周期函数由其时间域(如果一个信号随时间而变化,称该作用域为时间域。)(time domain)或空间域(例如与时间无关的静止的图像,它的作用域为空间位置,称为空间域。)(spatial domain)变换到其频率域。其目的在频率域我们可以发现该函数的一些重要特征,甚至一些对函数的操作在频率域进行更方便。
从图2中可以看到这种作用域的转化,红色线条代表原始连续周期函数(注意这里是针对傅里叶级数而非傅里叶变换进行描述),蓝色线条为傅里叶级数各级的正弦或余弦函数,图2(a)包含了傅里叶级数的头6项,这个傅里叶级数本身是有无穷多项的。图2(b)通过提取出每个正弦或余弦项的频率,而形成图2(c)的频率域函数,这个频率域将用于后面对信号采样的质量判定。值得注意的是,由式2可知,其傅里叶级数的频率域是离散的;然而由式(1)可知,非周期连续函数的频率域函数,即傅里叶变换函数是连续的,如图3所示。
图(2):傅里叶变换将函数由时间域(或空间域)变换到频率域,注意这里讨论的是周期函数的傅里叶级数(图片来自Wikipedia)
当一个函数被变换到频率域后,则我们可以检测该函数是否存在最大的频率,以至对于所有大于该频率的傅里叶变换函数的值为。如果该最大频率存在,该函数称为带限函数(bandlimited function),这意味着我们可以检测该函数的频率带宽(bandwidth),如图3是某个函数的傅里叶变换,其频率带宽为。带限函数是后面对函数进行采样以及相关理论的重要基础概念。
图(3):一个带限函数的频率域具有一个有限的范围,如果采用频率大于这个带限的宽度, 则其采样后的离散信号可以被完美复原(图片来自Wikipedia)
为了理解采样及采样定理,我们需要首先了解一下卷积的概念,卷积在计算机图形学中也是一个重要的基础数学工具,例如在后面讨论渲染方程,以及一些全局光照方案中几乎所有涉及球谐函数(spherical harmonics)的地方等都会涉及卷积,所以本节首先学习卷积及其在傅立叶变换中的应用。
卷 积
在数学上,卷积(用符号表示)定义为两个函数和,在其中一个函数被翻转之后(以下假设被翻转),两个函数乘积的积分,即:
(式6)
注意这里是一个积分假变量,它说明在积分滑过整个定义域的同时,翻转函数将作用于的每一个位置。
我们可以给卷积做一个很直观的视觉解释,在图4中,蓝色曲线表示函数,红色曲线表示函数,以下过程可以用来描述卷积的计算:
图4:卷积的视觉解释,对于两个函数和的卷积(第一行),我们首先将执行翻转(第二行),然后将从定义域的左边(第三行)开始向右滑动(第四,五行),并在每个位置处计算式(6)中的积分(图片来自Wikipedia)
- 对函数执行翻转: ,如图4第一行到第二行的图形变化。
- 设置一个时间偏移,使从轴的起点位置开始“滑行”,如图4第三行所示。
- 将从滑动到,即是将从沿轴滑动到经过整个时间域,如图4第四和五行所示,只要两个函数存在相交,则计算它们乘积的积分,换句话说,在每个时间,对执行一个权重系数为的积分,注意式(6)的积分变量为,它表示被执行翻转的函数的作用域,所以整个积分是一个关于的函数,我们需要求解每个处的积分。
这个过程形成的关于的波形(在图中没有画出),即是和的卷积。由此可以看出,卷积计算是对整个定义域的每一点,在定义域内的积分计算。因此卷积的计算量非常大,我们看到后面的一些计算中,的定义域一般都非常小。此外,卷积是一个线性计算,它输出一个和定义域一样大小的结果,例如,如果代表的是一张图像,则卷积计算的结果输 出另一张一样大小的图像。另外,卷积公式本身只是关于每个点的计算公式,所以卷积实现必须要遍历整个定义域。
对于卷积和傅里叶变换,可证明(读者可参考[cite b:DigitalImageProcessing]等相关书籍),空间域中两个函数的卷积的傅里叶变换等于两个函数的傅里叶变换在频率域的乘积;反过来,如果有两个变换的乘积,则可以通过计算傅里叶反变换得到空间域的卷积,这即是卷积定理(convolution theorem)。换句话说,和是傅里叶变换对,这一结果是卷积定理的一半,可以写为:
(式7)
双箭头用于指示右边的表达式是通过对左边的表达式执行傅里叶变换得到的,而左边的表达式是通过求右边表达式的傅里叶反变换得到的。
遵循类似的推导可得到卷积定理的另一半:
(式8)
它说明频率域的卷积类似于空间域的乘积,两者分别与傅里叶正,反变换相联系。卷积定理是傅里叶分析的重要基础,也是计算机图形学中很多算法的重要基础工具。
采样定理
有了傅里叶变换和卷积定理两个基础工具,我们就可以推导出采样定理,由于信号处理涉及对连续信号进行采样,以生成离散信号,然后通过离散的采样结果对函数进行重建的过程,采样定理 告诉我们,在什么条件下可以完美地重建原始连续信号。除此之外,采样定理还能帮助我们理解走样的概念,以及对离散信息进行平滑等知识。
首先我们需要了解冲激函数(dirac function)的概念,它是推导采样定理的重要基础。连续变量在处的单位冲激表示为,其定义为:
(式9)
同时它还被限制为满足:
(式10)
很容易看出,假设函数在处是连续的,那么冲激函数具有如下的采样特性:
(式11)
更一般地,对于任意位置处的冲激函数,采样特性变为:
(式12)
可以看出,冲激函数的采样特性可以简单地得到冲激位置处的函数值,那么如果我们定义一个具有均匀间隔的冲激串函数,将这个冲激串作用于一个连续函数,那么其结果就得到对原始信号的均匀采样。
一个具有均匀间隔的冲激串函数可以定义为:
(式13)
上述冲激串表述的函数如图5(b)所示。将上述冲激串函数作用于一个连续函数,则得到以下采样后的函数为:
图(5):冲激函数具有采样的能力,它可以简单地得到冲激位置处的函数值,所以函数$f(f)$的均匀采样可以定位为使用一个冲激串函数(b)与之相乘,这得到采样过后的函数(c),最终每个冲激位置处的采样值由加权后的冲激强度给出(d)
(式14)
上述和式的每一个分量都是由在该冲激位置处的值加权后的冲激,如图5(c)所示。每个采样的值由加权后的冲激“强度”给出,我们可以通过积分得到它,即任意采样值为:
(式15)
图5(d)显式了上述的采样结果,它由原始函数的等间隔采样而成。
为什么要用这么复杂的方式来表述函数采样呢?这是因为借助冲激函数的傅里叶变换以及卷积定理,我们可以得出采样定理,并进而指导我们对函数进行采样。
令表示连续函数的傅里叶变换,为采样后的函数的傅里叶变换,由卷积定理可得:
(式16)
其中,符号表示傅里叶变换,为冲激串函数的傅里叶变换:
(式17)
可以看出,冲激串函数的傅里叶变换仍然为一个冲激串函数,这是一个非常重要的特性,由此我们可以得到采样后的函数的傅里叶变换为: