GAMES101 Lecture 6 Rasterization 2 (Antialiasing and Z-Buffering)
这里回顾GAMES101 Lecture 6,光栅化(深度测试与抗锯齿)。
课程主页:
课程作业:
课程视频:
本讲的内容如下:
- 抗锯齿
- 采样理论
- 实际中的抗锯齿
- 可见性/遮挡
- Z-buffering
回顾上一讲的内容,目前的问题在于锯齿状较为明显:
本节的内容是如何缓解这个问题。
回顾
采样在计算机图形学中无处不在:
- 光栅化 = 采样2D位置
- 照片 = 采样图像传感器平面
- 视频 = 采样时间
同样,采样产生的走样问题在计算机图形学中无处不在:
锯齿:
摩尔纹(忽略图像奇数行和列):
车轮幻觉(虚假运动):
走样问题可以总结如下:
- 锯齿:空间采样
- 摩尔纹:图像欠采样
- 车轮效应:时间中采样
- 还有很多
走样问题的背后:
- 信号变化太快(高频),但采样太慢
反走样的解决思路
反走样的解决思路:
- 采样之前先进行模糊(滤波)操作
示例:
锯齿边缘,像素取值为纯红色或白色。
抗锯齿边缘,像素取值为中间值。
效果如下:
注意到上述操作的顺序不能互换,即不能先采样,然后滤波:
为什么这样做是有效的呢?
- 为什么欠采样会产生走样?
- 为什么先滤波然后采样可以做抗锯齿?
让我们深入挖掘根本原因并看看如何实现抗锯齿光栅化。
频域
傅里叶变换将信号分解到频域(正弦波,余弦波):
对于三角函数$\sin(2\pi f x), \cos (2\pi f x)$,$f$为其频率。
高频信号需要更高的采样率,从下图中可以看出,使用同样的采样率,可以基本捕捉原始信号:
小结:
- 高频信号采样不足:样本被误判为来自低频信号
- 在给定采样率下无法区分的两个频率称为“走样”
滤波
- 滤波 = 去除某些频率(频域)
- 滤波 = 卷积(时域)
卷积定理:
空间域的卷积等于频域的乘法,反之亦然。
选项1:
- 在空间域中通过卷积过滤。
选项 2:
- 变换到频域(傅里叶变换)
- 乘以卷积核的傅里叶变换
- 转换回空间域(逆傅里叶)
分析
采样等于重复特定频率:
a, c, e是在时域进行操作,采样等价于取某些特定点的值(脉冲函数),对应的信号为c,采样结果为e。
b, d, f为a, c, e在频域对应的信号,注意到c(脉冲函数)在频域对应的结果依然是(脉冲函数),最后的结果f相当于把b“复制粘贴”,即重复特定频率。
据此分可以分析为什么会走样。
如果采样率够高,那么“复制粘贴”的结果如下:
如果采样率太低,那么“复制粘贴”的结果如下:
有部分频率混合了,这样就产生了走样。(个人理解,无法区分重叠部分来自于哪个“复制块”。)
反走样(pre-filter)
选项 1:提高采样率
- 从本质上增加傅里叶域中重复项之间的距离
- 更高分辨率的显示器、传感器、帧缓冲器
- 但是:成本高且可能需要非常高的分辨率
选项 2:抗锯齿
- 在重复之前使傅里叶域的项“更窄”
- 即在采样前滤除高频
- 限制其余,然后重复
抗锯齿的效果如下:
一个常用的pre-filter为box-blur,即平均每个像素周围的值,对应的矩阵为:
最终解决方案,通过平均像素区域中的值进行抗锯齿:
- 将$(x,y)$通过box-blur
- 回想一下:卷积 = 滤波 = 平均
- 然后在每个像素的中心采样
上述操作等价于计算某区域内的三角形覆盖面积,因为一个像素区域内的平均值$f(x,y) = \mathrm{inside}(triangle,x,y)$等于该三角形覆盖的像素区,这样操作的效果如下:
但是上述操作不容易执行,因为计算三角形的面积很困难,一个解决方案是使用超分辨率。
反走样(超分辨率, MSAA, Multisample anti aliasing)
通过对一个像素内的多个位置进行采样并对它们的值进行平均来近似1-pixel box filter的效果(即把一个像素拆成多个小像素):
对于(超分辨率)光栅化一个三角形,第一步为在每个像素内采样$N\times N$个样本:
第二步,在每个像素内平均$N\times N$个采样点:
最终结果:
实际效果:
小结
没有免费的午餐!
- MSAA的开销增加了$N^2$倍
里程碑(老师的个人想法)
- FXAA(Fast Approximate AA)
- TAA(Temporal AA)
超分辨率/超采样
- 从低分辨率到高分辨率
- 本质上仍然是“样本不足”问题
- DLSS(深度学习超采样)