Lecture 06 Rasterization 2 (Antialiasing and Z-Buffering)
Antialiasing 反走样
采样理论
-
发生在不同位置 (如照相)
-
发生在不同时间 (如动画)
Sampling Artifacts(指图形学中的错误、看上去不对的地方、瑕疵)
- 锯齿
- 摩尔纹
- Wagon wheel effect 行进的车轮看起来似乎是向后转的现象(由于人眼采样频率不够)
- [Many more]
本质都是信号的变化太快了,以至于采样速度跟不上
对走样的理解:采样速度跟不上信号的变化速度,导致采样还原出来的信号不能模拟原信号
反走样的方法
-
在采样之前先做一个模糊(或者叫滤波)
近似抗锯齿,效果一般,但损耗最小
能不能先采样再模糊?
(左图为先采样再模糊,右图为先模糊再采样)
不行,先采样再模糊叫做Blurred Aliasing,这样做其实还是走样的,只是走样之后再模糊了
还会走样是因为先采样没有去除信号混叠
信号分析
傅里叶级数展开
任何一个周期函数,都可以写成一系列正弦和余弦的线性组合以及一个常数项
加的项越多,近似结果越精确
傅里叶变换
给定一个函数,都可以经过一个复杂的操作变成另外一个函数
(时域函数经过傅里叶变换到频域函数)
\[f(x)\ F(w)=\int_{-\infin}^{\infin}f(x)e^{-2xiwx}dx\ F(w)\\ 时域\rarr傅里叶变换\rarr频域\\ 时域\larr逆傅里叶变换\larr频域\\ f(x)=\int_{-\infin}^{\infin}F(w)e^{2\pi iwx}dw\\ e^{ix}=\cos x+i\sin x \]傅里叶变换就是将函数变成不同频率的段
Filtering 滤波
通过滤波来操作图像是经典的操作,现在更多的操作是通过机器学习来进行的
滤波是抹除特定频率的信号
傅里叶变换将一个函数将时域变换到频域
这里将一副图像从时域变换到频域,在频域图中,中心代表低频,周围代表高频,图像的亮度表示信息的多少,如上图中大多数信息集中在低频上
频域图中水平和竖直的两条线?
在分析一个信号的时候,会认为这是一个周期性重复的信号,对不周期性重复的信号,比如上图,我们认为,到了右边界时,又会重复左边界的内容,可以理解成有无限多个这张图拼在一起(类似d3d中的wrap寻址模式),而图像的左边界和右边界并不一样,所以在这条边界上会产生极其高的高频,导致剧烈的信号变换
High-pass filter 高通滤波
将低频信号抹除,再进行逆傅里叶变换,可以看到提取出了图像的边界
Low-pass filter 低通滤波(Blur)
将高频信号抹除,可以看到去除掉了图像边界
但是产生了水波纹(这是不完美的低通滤波导致的)
同时高通滤波和低通滤波
去除了边界(高频信息)和大面积相同色块(低频信息)
滤波=卷积(=平均)
图形学上的简化定义
卷积操作(取原始信号周围信号,做一个加权平均,得到一个新的信号)
Convolution Theorem 卷积定理
时域上若想对两个信号进行卷积,对应到频域上等于两个信号的乘积
-
选项1
直接在时域上卷积
-
选项2
-
傅里叶变换到频域
-
将卷积滤波器(数学上叫卷积核)变换到频域上,二者相乘,得到频域上的结果
-
将结果逆傅里叶变换到时域
-
-
选项1
在图像上,每个像素取周围9个像素求平均,最终模糊图像
-
选项2
图像变化到频域,卷积核变换到频域,二者相乘结果变换回时域
(相当于对原图像进行了一个低通滤波)
(这里卷积核和结果出现了Artifact)
Box Filter
一个低通滤波器
乘于一个\(\frac{1}{9}\),防止图像发生亮度变化(归一化因子)
如果用一个更大的滤波器,频域图反而更小了,因为只留下了更低的频率
采样
用\(c\)函数乘于\(a\) 函数等到一系列离散的点,\(c\)为冲激函数,只在箭头上有值,其他位置没有值
时域上的乘积=频域上的卷积
采样就是在重复一个原始信号的频谱
走样
采样速度不够快,意味着采样点直接的距离很大,导致频谱上重复的信号距离越小(时域和频域上有很多相反的关系),也就导致了信号发生了混叠,也就是走样
降低走样错误
-
选项1
增加采样率
-
反走样
先做模糊(低通滤波),再做采样砍掉高频信号,再做采样,就不会发生混叠了
对于每一个三角形,用一个一定大小的低通滤波器对其进行卷积,使其模糊
- 对每个像素,进行卷积
- 采样每个像素中心
- 根据每个像素中被三角形覆盖面积,决定其灰度值(可以简单理解为颜色的深浅)
实际中的反走样
MSAA
原理
对于任何一个像素,将其划分成小的像素,每个小的像素有个中心,判断每个小像素是否在三角形内,然后将结果平均起来,得到一个近似结果
采样点越多,近似结果越精确
MSAA是做了反走样的第一步,解决了信号的模糊操作
MSAA只是为了近似合理的覆盖率,并不是通过提示采样率来解决的
损耗
增大了计算量,如果一个像素用\(4\times4\)的划分,就增大了16倍的计算量
在工业界,人们用的并不是规则的\(4\times4\)个点,而是用更加有效的图案来分布采样点,有些采样点还会被临近的图案所复用
FXAA(Fast Approximate AA)
原理
图像后期处理,先得到有锯齿的图,通过一些图像匹配的方法找到边界,再将锯齿边界换成没有锯齿的边界。
FXAA与采样无关,是一种在图像方面上做抗锯齿的方法
TAA(Temporal AA)
Temporal 时间的
原理
对于一个静止的场景,相邻两帧显示的东西一样,可以用一个像素内不同的点来感知是否在三角形内,因此在时间范围内得到的静态的图会各不相同,有时候出现边界,有时候没出现边界
TAA的思想就是复用上一帧感知到的结果,上一帧每个像素的值,在这一帧才会继续发挥作用,被应用进来,相当于把MSAA对应的样本分布在了时间上,在当前帧没有引入任何额外操作
动态场景在实时光追中再说
超分辨率/超采样
与抗锯齿无关,但本质相同
- DLSS(Deep Learning Super Sampling)
Visibility/occlusion 可见性/遮挡
每次光栅化只画出了一个三角形,在一个场景中,有许多深度不一的三角形,如何正确画出它们呢?答案是使用深度缓冲区(Z-buffering/Depth buffering)
Z-buffering 深度缓冲区
Painter‘s Algorithm 画家算法
先将最远的物体画在屏幕上,再将近的物体画在屏幕上,覆盖更远的物体,就可以得到准确的结果
从远到近先后做光栅化
比如要画立方体,先画后面。左面,下面,右面,上面,再画前面
但是先画右面,下面,上面,左面会发现错误(左面多了条竖线)
但是根据深度对\(n\)个三角形排序需要\(O(nlogn)\)的时间,且会有无法解决的问题
三个三角形互相遮挡,可以看出实际做法中不能用画家算法,所以在图形学中引出深度缓冲区的概念
深度缓冲区
- 存储每个像素上最近的深度值
- 需要一个额外的缓冲区来存储深度值
- 帧缓冲区存储颜色值
- 深度缓冲区(z-buffer)存储深度
帧缓冲区和深度缓冲区是同步生成的
深度越近,值就小,深度越远,值越大,反映在颜色上就是近黑远白
Z-Buffer Algorithm
以屏幕上某一点像素举例
渲染某个三角形时,将三角形上该像素位置的深度值写入,后续渲染另一个三角形时,该像素位置上的深度值大于当前三角形该点像素,则将帧缓冲区和深度缓冲区对应像素更新
在深度值相同时是否更新,用户自己设置
在光栅化期间
for (each triangle T)
for (each sample(x, y, z) in T)
if (z < zbuffer[x,y])
framebuffer[x,y] = rgb;
zbuffer[x,y] = z;
else
; //否则无视
复杂度
- 对于\(n\)个三角形,时间复杂度为\(O(n)\)
- 我们只记录了每个像素深度最小值,没有排序,所以只需要遍历
深度缓存算法与三角形光栅化顺序没有关系
考虑到如MSAA,深度缓冲区可能不是对每个像素进行记录,而是对每个采样点进行记录
标签:采样,Antialiasing,频域,像素,信号,深度,缓冲区,Lecture,Buffering From: https://www.cnblogs.com/Tellulu/p/18092216