学之前你必须知道

视锥

这是透视相机的概念,用来衡量视距的大小。一般用2种属性来描述一个视锥:

  1. near面的宽高比
  2. 垂直视角 Vertical Field of View

有了上面2个确定值,然后再自己定义一个near的值(近平面与相机的距离),就能确定成像了,视锥完成。

屏幕上的概念

分辨率,也就是1080p、2k等,就是像素的多少。

屏幕 Raster,德语中的屏幕的意思,而屏幕是一个光栅成像设备。

光栅化 Rasterize,把东西画在屏幕上的过程。

像素 Pixel,全名picture element,是最小单位的小正方形,它的颜色由Red、Green、Blue三个色(0~255)来混和成。

屏幕发展过程

过去方式

  1. 示波器
  2. 阴极射线管 Cathode Ray Tube:和示波器原理相同,用很多电子打在屏幕上。通过扫描一样的方式,一条一条画横线,组成图像。

隔行扫描 Raster Scan:上面的画横线,优化的话还会在一帧只画1、3、5…奇数行,下一帧再只画偶数行。这样省去了一半的工作量,也能一定程度欺骗到肉眼。

现代方式

  1. 液晶显示器 LCD(Liquid Crystal Display):通过液晶扭曲光的方向,让其可以通过对应的光栅。
  2. 控制发光二极管的显示器 LED(Light Emitting diode array)
  3. 电墨水:通过电子控制只有黑、白像素的电墨水,实现电纸书的页面刷新。

帧缓存技术 Frame Buffer(Memory for a Raster Display):将显卡中的一块内存区域中,存储的内容反映到屏幕上。

光栅化一个Cube

视口变换 Viewport

光栅化之前要做的事。将一个 [-1,1] x [-1,1] 的2维平面,转换成[width,0] x [0,height]的笛卡尔坐标系内来表示。这叫做视口变换,看下:

最后算出,变换矩阵如下:

光栅化

我们将原图形分解成很多个三角面,投影到屏幕的像素点上。

首先,怎么判断一个像素点与三角形的位置关系?

靠前面的知识,已经可以做到任何一个点都确定性地投影到屏幕上了。

那么如果想判断一个像素点是否在一个三角面内呢?也就是问,如何确定这个像素的着色?

可以通过判断这个像素点的中心点与三角形的位置关系来确定,为了方便,就定义一个判断函数Inside()。而这个函数就是进行3次叉积。

然后,哪些像素点需要判断呢?

如果需要把整个屏幕的点都进行一次Inside()判断,实在是没有必要,那么哪些需要、哪些不需要,这就涉及到包围盒了。

简单介绍一个AABB包围盒,它就是取三角面3个顶点的Min(x), Min(y), Max(x), Max(y),作为他的盒子。

最后,成像完有锯齿 (Jaggies) 怎么解决?

又叫做反走样(Aliasing )、抗锯齿。

在解决之前先理解为什么会有这类问题?取哪些像素点来表示这个三角面,叫做采样(Sample)。而采样会有3种瑕疵(Artifacts)

  1. 锯齿 Jaggies
  2. 摩尔纹 Moire
  3. 运动速度过快 Wagon wheel effect

产生原因是信号变化的速度太快,而采样速度跟不上了。

那么怎么抗锯齿?

可以对三角面做预处理,比如滤波、模糊,之后再进行采样。

抗锯齿 Anti-Aliasing

前面了解了为什么会产生锯齿,以及大致的抗锯齿技术(滤波、模糊)。这里细说。

频域 Frequency Domain:描述信号在频率方面特性时用到的一种坐标系。想象一下cos2Π的图。

滤波 Filtering:把某个时段内,特殊的频率给过滤掉。

傅里叶变换:变幻的具体内容不要深究,只要知道,可以通过傅里叶变换把一张图变换为频域图,这样就能知道哪些地方的信号量多、少。中心定义为低频、周围定义为高频。最后,得到的频域图,是可逆的!

// TODO 下面的都只简单理解,更为深入要去学习 数字图像处理

先傅里叶变换,再过滤一张图 FFP

中心定义为低频、周围定义为高频。当颜色变化差异巨大的时候(比如人物边缘),会产生高频信息。

为什么会有十字线?没有学过信号学不能看懂这张频谱图,只能理解为傅里叶变换前会把这一张图复制很多份拼起来,来取样。拼起来之后每张图的4个边的边界之间的信息差异巨大,就有巨大的高频信息,而这十字线的高亮就是边界的映射。

高通率波

High-pass,就是只有高频能通过,低频直接忽略的滤波方式。可以看到,逆变换回来的图几乎只保留了边界信息(人物描边),这是因为边界处的信号量差异很大,这就是高频的信息

低通滤波

滤掉高频,也就是滤掉边界信息,那么就会像下面这样。

高低滤波

卷积定理

只简单概述结论:

在空间域中,对一张图进行卷积滤波 = 对一张图进行傅里叶变换、再对其乘以卷积核的傅里叶变换、最后逆傅里叶变换回去

采样 Sample

稀疏采样会产生更多混叠,导致走样;密集采样更少混叠,所以映射结果更好一些。

怎么较少走样,也就是如何反走样?

本质上,就是想办法增大傅里叶副本之间的距离来减少混叠。

1.增加采样率(更高分辨率的屏幕)

2.抗锯齿,通过对图像模糊预处理(使用傅里叶来低通滤波)再采样

常规采样流程

先用低通滤波器模糊原图,然后再采样。

抗锯齿:模糊操作

取像素颜色时,根据三角面的在该像素块中覆盖的面积,来设置灰度。

这个理论很简单,但是实现比较困难,于是采用一种类似的方法,对一个像素块再进行划分、进行更多的采样,也就是**多重采样抗锯齿 MSAA (MultiSampling Anti-Aliasing) **来实现。

下图就是一个MSAA的例子:把一个像素格分成了2x2,来确定0%、25%、50%、75%、100%。

工业界会优化,想要2x2的效果不会这么单纯的分割成4个正方形,而是一些其他不规则图形,甚至可能多个像素块复用一个点,这么做都是为了减少需要检测的点数量。

其他抗锯齿方法

FXAA(Fast Approximate AA):快速近似抗锯齿,是一种后处理,会对有锯齿的地方进行修正。

TAA(Temporal AA):利用时间而不是空间采样,对于静止的连续帧,上一帧有效的采样点才继续采样。

DLSS(DeepLearning SuperSimple):当低分辨率拉伸成高分辨率时,会有很多锯齿,此时用深度学习来猜测描绘。