4.Rasterization光栅化(反走样,深度缓存)

发布时间 2023-07-01 13:13:45作者: oOLzYOo

走样Aliasing(锯齿)

采样的广泛应用

  • 采样不仅可以在图片的某个位置,也可以在时间轴上
  • 动画就是一组图在时间的采样

Artifacts(瑕疵、错误)

  • 采样会产生一些Artifacts(瑕疵、错误)
  • 例如:锯齿(图像上的采样)
  • 摩尔纹(删除图像奇数行,再放大成原大小后可得)
  • ”车轮效应“(车轮旋转速度过快,感觉车轮在倒着转)

走样的原因

  1. 信号变化过快(频率高)
  2. 采样频率太慢,跟不上

反走样

模糊Blurring(Pre-Filtering)

  • 模糊操作是在采样前的操作
  • 对原始信号做模糊处理(滤波处理),然后再采样
  • 可以模糊图像边缘,过度更加顺滑

问题:为什么不能先采样,再模糊呢(滤波)?

  • 暂时按下不表

通过频域来分析走样

  • 在频率的角度定义走样:用同样的频率采样两组截然不同的信号,得到的结果无法区分,称之为走样。

  • 对于函数\(y=Asin(\omega x+\varphi)+B\)\(y=Acos(\omega x+\varphi)+B\)的周期公式是\(T=\frac{2\pi}{|\omega|}\)
  • 对于函数\(y=Atan(\omega x+\varphi)+B\)\(y=Acot(\omega x+\varphi)+B\)的周期公式是\(T=\frac{\pi}{|\omega|}\)

傅里叶级数展开

  • 任何一个周期函数,都可以被写成一系列正弦余弦和常数的组合。

傅里叶变换

频域展现的走样

  • 在采样频率不变的前提下,假如原信号的周期很长,低于或者接近采样频率,则走样较少
  • 若原信号的周期很短,频率远高于采样频率,则走样很严重

通过频域来分析滤波

定义:频率上删除一系列的特定频率被称滤波

  • 一幅图经过傅里叶变换:从时域到频域的转变,从左图转变到右图
  • 高通滤波
  • 把频率高的信号提取出来,在图像中的表现为:留下了边界
  • 边界:左或者右边,上边和下边发生了突然的变化(信号变化大)
  • 低通滤波
  • 只留下低频的信息,获得相对模糊的图片。
  • 高频低频信息都去除了,留下了中间较为模糊的信号。

卷积Convolution

  • 又称”平均“
  • Flitering滤波=Convolution卷积

  • 滤波器Filter像一个窗口在信号Signal中从头滑动到尾。是一种加权平均。
卷积定理
  • 时域上对两个信号做卷积,相当在频域上对两个信号做乘积。
  • 求卷积:可以把时域信号先傅里叶变换获得频域信号,再做乘积,再傅里叶逆变换,得到信号的卷积
  • 时域上的乘积=频域上的卷积。
例题

  1. 时域图片

  2. 卷积后获得模糊图

  3. 也可以是:先把图片傅里叶变换,获得频域图,

  4. 把卷积操作也做一个傅里叶变换获得卷积和

  5. 两者相乘,获得频域结果图,再逆傅里叶变换获得最终结果。

卷积盒

  • 上图是一个低通滤波器
卷积盒性质

  • 上图左图是一个时域上的白色方块,右图是左图卷积后的频域图
  • 卷积盒子越大,右图片中展示效果则越模糊。
  • 上面3x3的滤波盒子效果为取 9个格子内的平均值
  • 要是64*64大小的盒子则会更失真,更模糊。
  • 反过来,要是盒子足够小不就相当于没有滤波操作。

通过频域来分析采样

  • 定义:重复抽取频域中的内容
  • 上图(c)冲击函数:只在箭头所指方向有值,做采样处理使用。
  • 时域上:原始信号(a)*(c)=(e)
  • 频域上: 对(a)和(c)做傅里叶变换获得(b)

通过频域来分析反走样

  • 上图为频谱信号图,若采样频率高,则可以获得较为清晰完整的信号图
  • 但是采样频率稀疏就会发生频谱重叠。
反走样两种思路
  1. 增加采样频率。(非正式操作,例如换分辨率更高的显示器,像素更小了,采样频率就提升了)
  2. 先做模糊(低通滤波处理),再做采样。

分析模糊处理

  • 把原来的梯形频谱低通滤波处理后,获得新的信号,
  • 再用同样稀疏的采样信号就不会发生采样重叠
  • 时域的表现如上

滤波器

  • 对像素f(x,y)做1像素格子的低通滤波处理(卷积)
  • 取每个像素的中心点进行采样

  • 像素(正方形格子)内的色值平均

更多采样点进行反走样(MSAA)

  • 不是增加分辨率,而是增加了采样点。
  • 对于每个像素,不要仅用一个中间点来判断三角形是否覆盖,而是取4个顶点来分别判断
  • 左图是不采用MSAA的做法,那么这个像素就没有被三角形所覆盖。
  • 右图用四个均匀分布的点来判断,那么有两个点就被三角形覆盖了。
  • 上图采用每像素4个点的三角形覆盖判断
  • 在具体的计算中,对于每个像素,fragment shader只需要算一次。
  • 对每个采样点赋以颜色值,最终将四个采样点的颜色平均就可以得到像素的颜色。
  • 这样一来,就可以取到较好的抗锯齿效果。
  • 计算量不会有太大变化,但是存储量则要*4(因为多了四个采样点,每个采样点也要存颜色值)。
  • 下图展示了原始图像和运用了MSAA的图像,可以看到抗锯齿的效果还是比较明显的:

其他抗锯齿方案

参考链接https://zhuanlan.zhihu.com/p/78407475

FXAA(快速近似抗锯齿Fast Apporximate AA)
  • 图像后期处理,把图像边界找到,再用其他像素替换。
TAA( Temporal AA)
  • 复用上一帧的样本,对本帧进行图像的优化处理。
SSAA和DLSS超采样反走样(SSAA)
  • 是一种支持抗锯齿的方法。它的做法也很简单:假设我们的屏幕像素为800600,那么我们只需要将渲染的texture扩大4倍(16001200),然后再把相邻像素值做一个过滤(比如平均等)得到最终的图像就可以解决这个问题了。利用该方法确实可以从根本上消除锯齿,但是这种方法大大提高了存储空间和计算量,所以一般不会使用这种技术。

  • DLSS是通过深度学习,将放大分辨率后的图片进行滤波处理。其余原理与SSAA相似。

深度缓冲(Z-buffering)

何为深度

  • 深度其实就是该象素点在3d世界中距离摄象机的距离(绘制坐标),深度缓存中存储着每个象素点(绘制在屏幕上的)的深度值!深度值(Z值)越大,则离摄像机越远。

为什么需要深度?

  • 在不使用深度测试的时候,如果我们先绘制一个距离较近的物体,再绘制距离较远的物体,则距离远的物体因为后绘制,会把距离近的物体覆盖掉,这样的效果并不是我们所希望的。而有了深度缓冲以后,绘制物体的顺序就不那么重要了,都能按照远近(Z值)正常显示,这很关键。

例子

  • 图中有很多物体,需要按先后、前后的关系放置到图中
  • 例如把最远的摆上,再把近的物体摆放在远的前面(先画山,再画草地,再画树)

  • 特殊情况:两两覆盖
  • 不能使用画家算法来渲染图,所以引入了z-buffering。

Z-Buffering

性质

  • 又名深度缓冲,深度缓存
  • 处理不了透明物体

具体实现

  • 保存每一个像素的深度(z_value)
  • 在加载时,同时缓存了
    • 帧缓存,像素的颜色信息
    • 深度缓存,每个像素的深度信息
  • 前提:相机在原点,并且是往-Z方向看到物体的,所以Z一直是负的。z越小离摄像机越近,z越大,离摄像机越远。

算法流程

  • 假设开始时,深度是无限远的
  • 对任意一个三角形,光栅化成像素后。
  • 对任意像素,若该像素深度小于在zbuffer【x,y】中的值,则把帧信息更新到framebuffer[x,y]中,深度数组zbuffer[x,y]也要更新。

效果流程图

  • R表示无限远的深度,红色格子深度为5,5<R,所以更新了颜色和深度。
  • 蓝色的三角形中像素深度小于5的,则更新framebuffer和zbuffer数组,若大于等于5,则不更新。