GAMES101-光栅化与抗锯齿

157 阅读4分钟

MVP

1)Model transformation(placing objects) = 找好一个场景,让人物摆好姿势

2)View transformation(placing camera) = 放置好照相机

利用camera和物体的相对运动关系,始终让camera从任一位置变换到原点看向-z方向且向上为y,其余物体也跟着camera做相同的变换,从而保证model transformation应用到每一个model上,并且view transformation也应用到了每一个model上。

3)Projection transformation = 按下快门,将三维物体表现在二维平面上

在view transformation之后我们知道场景中的所有物体都是由一个标准位置的camera看过去的,接着将所看到的东西从3D投影成2D的一张照片。又分为正交投影(忽略深度信息)和透视投影(拥有近打远小的效果)。

经过mvp变换矩阵之后的所有东西都会在一个[-1,1]的立方体里,那么下一步该干什么呢?

答案就是将其画在屏幕上,也就是今天的光栅化(Rasterization )。

两条红线所夹的角度 : 垂直可视角度

横向也可以分别连接两条长度为height的中点 : 平行可视角度

角度大,像广角; 角度小,像正交投影

image.png

定义屏幕(视口变换):

  • 将屏幕定义为一个二维的数组,数组中的每一个元素是一个像素(an array of pixelx)。
  • 我们用256个等级0-255来表示灰度(如等级0表示是黑的,等级255表示是白的),一个像素内的颜色可以用rgb(red,green,blue)三个值来定义,用红绿蓝的各种组合来表示每一种红色蓝色绿色的密度,例如红色是(255,0,0),白色是(255,255,255)

image.png

将投影的结果(一个(-1 ~ 1 , -1 ~ 1 , -1 ~ 1)的立方体)转换为屏幕(0 ~ width , 0 ~ height) :

操作为: 左乘以下方矩阵[视口变换], 得到上面的图(array of pixels)

image.png

屏幕显示的图片是存放在显存里的一部分内存

image.png

LCD (Liquid Crystal Display): 液晶显示器

左右两边的板是光栅(偏光器) , 中间的是液晶 , 液晶改变光的方向

第一张图经过改变光能出去; 第二张图不能

image.png

LED(Light emitting diode)发光二极管

image.png

普遍得到应用的是三角形的光栅化 三角形具备以下优点:

1.最基础的多边形

2.任何一个多边形都可以拆成三角形

3.三角形一定是各个点在同一平面的

判断像素中心点是否在三角形里

在三角形内部的点会显示,而在三角形外的点则不会显示

1判断点在内部还是外部此时需要用到向量的叉积。

image.png

使用三个叉积来判断点Q是否在三角形中,即判断

  • 向量 P0P1 叉乘 P0Q,利用右手定则我们可以发现得到一个朝向屏幕外的向量,即Z值为+的结果,告诉我们Q在P0P1的左侧
  • 向量 P1P2 叉乘 P1Q,利用右手定则我们可以发现得到一个朝向屏幕外的向量,即Z值为+的结果,告诉我们Q在P1P2的左侧
  • 向量 P2P0 叉乘 P2Q,利用右手定则我们可以发现得到一个朝向屏幕内的向量,即Z值为-的结果,告诉我们Q在P2P0的右侧

这三个叉乘结果符号是否一致,如果一致(均为正或者均为负)则代表点Q在三角形内部,若有一个不一致则代表点Q在三角形外部,从而我们可以判断一点是否在三角形内部,再结合着采样的函数我们可以判断任意一点是否在三角形内部。

2对屏幕全部像素点都遍历一遍 , 若在则记录 1 ,不在记录 0

因为是像素中心点,所以需要+0.5 image.png 伪代码如下:

for (int x = 0; x < xmax; ++x)
    for (int y = 0; y < ymax; ++y)
        image[x][y] = inside(tri,  x + 0.5,  y + 0.5);
        // x,y不必为整数,是实数。

若像素中心点落在三角形边上, 可做处理,也可不做处理. 插件一般都有严格的判定.

image.png

另一种方法 : 像素中心点的最左和最右作为轴向包围盒(多个)

image.png

适用于以下图形:

image.png

 A Simple Approach: Sampling(采样)

经过MVP变换和视口变换之后我们可以得到顶点在屏幕空间的左边,现在我们需要将变换后的图形变成真正的像素,以三角型为例:

采样:采样就是把一个函数给离散化的过程,可以理解为给你一个连续的函数,在不同地方问此处的函数值是多少,这就是采样.

例如f(x) = sinx,让你求x=1,x=3,x=5或者x=-1时候的对应的f(x)的值是多少

抗锯齿

反走样 目标

image.png

显示

image.png

Sampling Artifacts(采样瑕疵)的部分例子:

1.锯齿问题(放大后看到的锯齿)

image.png

2.摩尔纹(将某些特定的像素删除后,再合并成照片,然后放大成原来的大小)

image.png

例如车轮顺时针旋转, 但是人眼却采样到逆时针旋转, 人眼的采样速度跟不上车轮旋转速度

image.png

总结:

信号变化太快,采样速度太慢

反走样: 采样前先做一个模糊或者说是滤波

左边为先采样后滤波,右边为先滤波后采样

image.png

频率:

image.png

时域与频域的直观表现 :

image.png

傅里叶变换 : 傅里叶变换,表示能将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合

(简要概括: 将一个函数通过多次与不同的函数加减得到一个函数 , 换句话说 : 任何一个函数傅里叶展开, 都可以分解成多个不同的三角函数)

image.png

傅里叶变换和逆傅里叶变换

image.png

如下图 , 在相同的采样频率下 , 看到频率越高 , 采样后还原的函数越不像原函数 (呼应轮胎转动的采样瑕疵 , 跟不上轮胎(原函数)的频率)

image.png

定义走样:

下图中,蓝色线表示的函数,经过采样得到黑色线表示的函数,如果此时黑色线表示的是另一个需要采样的函数,那么这两个需要采样的函数,所(通过采样点)还原出的函数无法分辨.这就叫走样(aliases)!

image.png

滤波(去掉一些特定的频率)

时域(Time domain)是描述数学函数或物理信号对时间的关系

频域(frequency domain)是描述信号在频率方面特性时用到的一种坐标系

如果我们把一个信号各个频段的成分也画出来,横坐标是频段的大小,纵坐标是对应频段成分的幅度,这样一个坐标系,我们把它叫做『频域』。把信号从时域映射到频域的过程,就是大家耳熟能详的傅里叶变换

左图为时域(这里只有位置),右图为频域(中心为最低频的区域,周围为高频区域)

右图的基本为低频,在自然图片中大多频域都是这样,低频偏多.

image.png

高通滤波 (把低频的信息抹掉,只剩下高频的信息), 对应图像内容的边界 因为边界的变化很大 , 信号产生的是高频信息 , 所以高频对应的就是边界

image.png

低通滤波(把高频的信号抹掉,只留下低频的信号) 边界变得模糊了.

image.png

最低频的(代表相同色块)和比较高频(代表边界)的信息都被抹掉

image.png

image.png

滤波=卷积(=平均) 卷积的过程(简化定义 : 对三个数进行加权平均), 对原始信号,用某种滤波器对其进行卷积操作

第一步:

image.png

第二步:

image.png

最后得出:一个新的信号 (result)

时域的卷积=频域的乘积

上面为时域,下面为频域

image.png

低通滤波器(卷积和) , 若周围9个像素乘以1相加得到最中间的被滤波后的像素 , 得出的像素更加明亮 , 我们要得到的是模糊后的 , 所以要周围每个即自身像素乘以1/9来进行相加 , 这个操作称为归一化

image.png

一个正方形(Box)时域 / 频域

image.png

当这个正方形变大时 , 对应的频域所抹掉的高频越多 (留下的低频越多) , 使与之卷积的图片更模糊.

image.png

左边为时域的采样 : (a) 卷积(c)=(e)

右边为频域的采样 : (b) 乘积(d)=(f)

(c)/(d)为冲激序列

经过傅里叶变换可得右边

经过逆傅里叶变换可得左边

简单理解:频域的采样就是重复频域内容(频谱)

image.png

频域上的走样现象:

image.png

反走样

先模糊(把高频的信号抹掉) , 再用稀疏的采样频率进行采样 , 得到每个频谱的覆盖面积小了 , 然后用原本的间隔距离去采样 , 就发现不会走样.

image.png

上半部分为原始像素

下半部分为上半部分像素内部的值卷积

卷积操作就是 : 以第一个像素为例,黑色部分占像素1/8 , 白色部分占像素7/8, 按比例平均到整个像素, 得到整个像素的颜色.

image.png

反走样的近似 MSAA ( MultiSampling Anti-Aliasing的英文缩写),指多重采样抗锯齿

MSAA并没有提高分辨率, 它增加的点只是为了判断覆盖面占像素的多少, 达到模糊的效果, 然后再进行采样操作, 才能完成反走样操作.

将一个像素划分成若干个像素 (2*2) , 相当于添加次像素点 :

增加采样点

image.png

根据覆盖点的多少得出像素 , 进而求出近似的三角形

image.png

抗锯齿会带来性能上的消耗 , 原本1个像素变成4个像素 , 所以导致要处理的像素变成了四倍.

现代抗锯齿方法 : (1)FXAA (Fast Approximate Anti-Aliasing),“快速近似抗锯齿” 通过找到锯齿部分 , 用没有锯齿的像素(图片)进行更换 , 属于后期处理.

(2)TAA (Temporal Anti-Aliasing) "时间抗锯齿" 综合历史帧的数据来实现抗锯齿 , 复用上一帧的像素.

(3)Super resolution "超分辨率" 若要将512512大小的图片拉成10241024的图片 , 则需要机器的深度学习方法DLSS (Deep learning Super Sampling), 通过足够多的案例 , 猜出变大后图片缺失像素是什么 , 从而达到变大而失真的效果.

image.png ————————————————

课程说明: # GAMES101

Games101-lecture05 Rasterization 01(Triangles)

Games101-课程6笔记