目录
2. 可见性/遮挡(Visibility/occlusion)
1. 反走样(Antialiasing)
光栅化之后的图片有走样(aliasing)的现象,也叫锯齿(jaggies)。
顾名思义,反走样技术就是尽可能消除这种走样现象的一种技术。
1.1 采样理论
1.1.1 采样是什么
要学会反走样技术,先得知道采样是什么。
采样就是把连续的东西给它离散化了,比如下面的几个例子:
(1)在光栅化的时候,将连续的三角形采样为许多个像素。
(2)在相机拍照过程中,将现实世界连续的图像采样为传感器上面的小平面块。
(3)视频拍摄过程中,是按照一定的时间间隔记录下图片,是对时间的采样。
可以说,采样在计算机图形学中无处不在:光栅化、照片、视频。
1.1.2 采样瑕疵
采样瑕疵也无处不在。
Sampling Artifacts(Errors/Mistakes/Inaccuracies) in Computer Graphics:锯齿、摩尔纹、人眼在时间上的采样跟不上目标旋转的速度。
在走样和瑕疵的背后,本质上是:信号变化速度过快,但采样速度太慢了。
1.1.3反走样的思路
反走样的一个想法:采样前进行模糊(预滤波)(Antialiasing Idea: Blurring (Pre-Filtering) Before Sampling)
原本的三角形,采样之后的值是纯白或者纯红的。我们先对原图进行一次滤波,或者叫模糊,然后再进行采样,边缘部分采样之后的颜色就是介于红色和白色之间的中间色。
采用这个反走样方法之后的效果:
->
先采样后模糊 不能达到反走样的效果,必须要先模糊,后采样。
问题1:为什么欠采样会导致走样?
问题2:为什么先进行预滤波再进行采样可以做到反走样?
为了解决这两个问题,我们需要挖掘基本的原理。
1.1.4 反走样的思路背后的原理
(1)频率域
余弦函数中的 f 就叫做频率
所有的函数都可以用傅里叶函数展开成余弦函数相加的形式
傅里叶变换可以实现时域到频域的转换
下图中黑色的点是采样点。
在采样频率不变的情况下,绿线的频率越高,采样得到的信息越不准确,会损失很多信息。
欠采样会造成走样。具体来说,用一个给定的采样频率对频率相差较大的两个信号(蓝色函数和黑色函数)进行采样,得到的采样结果却没有区别。
对于蓝色函数来说。这种现象叫做走样。
(2)滤波:去除某些特定的频段
傅里叶变换可以将图片从图像空间变换到频域空间内。
下面我们先举例,说明不同频率与不同图像特点的关系。
像上面这张图,左侧的图像经过傅里叶变换之后,转化到频域,然后可视化,就是右侧的频谱样子。
(水平和竖直方向的亮线是因为变换的时候,默认是把一张图片重复排列起来,那么上一张图片的右边界和下一张图片的左边界衔接处会产生剧烈的信号变化,从而,频率相当高,所以显示出来就是很亮的。)
上图将低频的部分从频域中消除,也就是高通滤波,经过如此操作后,原本图片上的信息只剩下了图形的边界,也就是说,边界处信息变化大,对应了频域中的高频部分。
将高频的部分从频域中消除,也就是低通滤波,经过如此操作后,原本图像只剩下了模糊的色块,硬朗的描边线条不见了。
将非常高频和非常低频的信号消除,经过如此操作后,原本图像剩下了一些不是特别明显的分界线。
(4)滤波 = 卷积 = 平均
简化的一维卷积过程:信号与滤波器点乘,得到结果。实际上就是将信号上的某个点与其周围进行了平均。
时域卷积 = 频域乘积
时域乘积 = 频域卷积
如上所示,图像卷积的模糊操作,可以直接对原图的频域乘以3*3滤波器矩阵的频域,然后将结果转化为时域,就可以完成对原图的模糊操作了。
实际上,模糊就是在频域上对图片进行低通滤波。去除了高频的信号,这也是反走样技术的关键所在,即去除高频信号。
让我们关注滤波器盒子本身。
一个格子在频域上也对应一个格子。
下图中左边是时域格子的大小,右边是时域格子转化到频域的图样。
如果这个时域的格子变大了,那么它在频域上对应的格子会更小,这会去除更多的高频分量,从而让卷积后的结果更模糊。
(4)频域角度下的采样:重复频域上的内容
下图中,左侧是时域,右侧是频域。
时域上 连续函数与冲击函数相乘(采样)= 频域上 频谱卷积
走样现象在频域中变得可以解释了:频谱混叠,即高频部分的信号出现差错。这就是频率意义上的走样。
那么在采样前,进行适当的模糊(去除高频信号),自然可以在一定程度上解决频谱混叠的问题,从而实现反走样。
1.2 反走样
1.2.1 反走样技术思路
了解了走样的原理之后,如何解决走样问题?
方案1:增加采样率:烧钱
方案2:反走样:先模糊(高频信号拿掉),再采样。
下面分别展示了常规采样和反走样技术的过程:
如何进行滤波操作,将三角形变成模糊的三角形?
取一个像素的小格子作为低通滤波器。
通过取一个像素区域内的颜色平均值来抗锯齿。
1.2.1 反走样具体实现
那么在实际中如何进行上面的操作?
如何计算出一个图形在某个像素中的占比?
人们研究出了一种反走样的近似方法:MSAA
用更多的采样点来进行反走样。
将 一个像素 划分为 很多小的像素
通过采样一个像素内的多个位置并取其值的平均值,来近似1像素盒滤波器的效果。
注意:MSAA并没有提高分辨率。
1.2.3 MSAA的代价是什么?
·计算量增大
工业上会使用不规则的划分来达到模糊,并不是4*4或者2*2这种规则的。
1.2.4 工业界里程碑的抗锯齿方法
FXAA(Fast Approximate AA):直接采样,将结果中的锯齿替换成没有锯齿的图案。
TAA(Temporal AA):没听懂(),好像是在不同时间上进行操作,国外为了把这个单词与“暂时”区分,将其念作tem’poral。
1.2.5 一个和反走样相近的技术:超分辨率
(Super resolution/super sampling)
·就是从低分辨率扩到高分辨率
·本质上要解决的也是样本不足的问题。
·常用的方法:DLSS:就是一种深度学习的方法,把缺失的信息猜出来。
2. 可见性/遮挡(Visibility/occlusion)
·问题引入:在一张图中有多个物体时,如何处理它们之间的前后遮挡关系,使近处的物体能够遮挡住远处的物体呢?
·一种解决方案:画家算法
受到画家作画的步骤启发,这种算法从后到前光栅化画面中的内容,覆盖帧缓冲区。
比如下面这张图,就先画雪山,再画草地,再画树木。
但画家算法需要对深度进行排序(对n个三角形排序,时间复杂度O(nlogn)),并且存在解决不了的顺序问题:以下三角形相互交叠,不能确定出绘制顺序。
2.1 深度缓冲(Z-buffering)
2.1.1 深度缓冲的相关概念
为了解决上述问题,图形学中引入了一个概念:深度缓冲。
思想:
1. 对每一个像素,记录最小的深度值。
2. 需要为深度值提供一个额外的存储缓冲。
·帧缓冲区存储颜色值
·深度缓冲区(z-buffer)存储深度
如图,我们之前总是假设相机看向原点,并且是朝向-z方向的。
为了简化概念,我们将深度值定义为:物体离摄像机的距离,并且均取正值。
如此一来,离摄像机越近,值越小;离摄像机越远,值越大。
2.1.2 深度缓冲示例
深度值越小,越近,越黑;深度值越大,越远,越白。
2.1.3 深度缓冲算法
(1)算法流程
假设深度初始值为无穷大
遍历每一个三角形,遍历三角形中的每一个像素,如果当前像素的深度小于深度缓存中的记录,那么就将深度缓存中的记录更新为这个更小的深度值,并且把当前像素绘制在屏幕上。否则,不做任何操作。
(2)性质
假设三角形之间不存在重叠部分深度相同的情况,那么就算改变三角形绘制的顺序,比如先画蓝色三角形,再画红色三角形,那么得到的结果也是一样的。换句话说,深度缓冲算法的结果与绘制顺序无关,这样就节省了排序的工作量。
Z-buffering无法处理透明物体。
(3)重要性
深度缓冲是最重要的可见性算法,它在所有GPU的硬件中实现。