GAMES101-闫令琪 https://www.bilibili.com/video/BV1X7411F744/

https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html

02 Review of Linear Algebra 线性代数

向量

单位向量:

  • 大小为1的向量
  • 向量的单位向量(归1化):向量/长度
  • 用于表示方向

向量加法:

  • 几何上:平行四边形定律和三角形定律
  • 代数:只需添加坐标

点乘:

  • a向量长度*b向量长度*夹角余弦COS
  • 两个都是单位向量,结果就是夹角余弦,反余弦就可以知道夹角大小
  • 点乘也满足交换律、结合律、分配律
  • 在直角坐标系中就是对于元素相乘后相加
  • 点乘在图形学中可以用来寻找物体直接的夹角;也可以计算一个向量在另一个向量上的投影;两个方向有多接近;方向

叉乘:

  • 叉积与两个初始向量正交
  • 方向由右手定则确定
  • 可以确定第三条轴
  • 叉乘没有交换律,需要加负号
  • 有助于构建坐标系(稍后);叉乘反转法线的功能

判定左右、内外:

  • a叉乘b,根据右手定则得负,所以a在b的右侧
  • Ap在AB的左侧、Bp在BC的左侧、Cp在CA的左侧,所以p点在三角形ABC内(都在三角形左边/右边)

投影 正交基准/坐标系:

  • 对于表示点、位置、地点很重要
  • 通常,许多坐标系全局、局部、世界、模型、模型的一部分(头部、手,…)
  • 关键问题是这些系统之间的转换/基地

矩阵

矩阵乘法:

  • 第一个矩阵列数等于第二个矩阵的行数才能乘
  • (i,j)为A的第i行和B的第j列的点积,例:61为2行3列,(5*9)+(2*8)
  • 没有交换律,但是有结合律和分配率

转置:

  • 行和列互换
  • 如果乘两个矩阵后转置,等于后一个矩阵转置乘以前一个矩阵转置

单位矩阵:

  • 只有对角线有非零元素
  • 单位矩阵乘以a还得a
  • 两个矩阵相乘得单位矩阵,就说这两个矩阵是互逆的

向量的点乘和叉乘都可以写成矩阵的形式:


03 Transformation 变换

线性变换

都可以写成这样一种形式:线性变换=矩阵

缩放:等比缩放分别*s,可以写成矩阵;不成比例缩放,就有了两个s

翻转:沿x轴翻转,x取反,y不变

切变:∵y=1时 偏移 a,当y=0.5时 偏移 0.5a ∴任何的x水平方向移动都是a*y,y不变

旋转:将变换后的坐标写成矩阵使用ABCD代替,根据三角函数求得其中一个变换后的坐标为cosθ和sinθ,将其代入矩阵求得A=sinθ、B=cosθ,再求得另一个点的坐标,可得旋转后的变换矩阵

齐次坐标

平移:因为平移不符合线性变换的一个矩阵乘另一个矩阵,但是又不想把平移当成一个新的变换,所以将二位的点/向量增加一个维度,二维点写成(x,y,1)、二维向量写成(x,y,0);(向量表示的是方向性,向量具有平移不变性)。(先应用线性变换然后平移)

齐次坐标通过增加一个数的方式,就可以把平移写成矩阵乘以向量的形式

x,y是有意义的,w是我们加上的东西,如果我们任务任何的x,y,w作为一个二维的点,可以表示为x/w , y/w , w/w(w ≠ 0否则就成向量了),w=1,

  • 向量 + 向量 = 向量
  • 点 - 点 = 向量
  • 点 + 向量 = 点
  • 点 + 点 = 两个点的中点

所以的仿射变换都可以写成齐次坐标的形式(二维变换下的仿射坐标写成的齐次坐标,最后一行都是0,0,1、平移写着最后一列的前两个,左边2*2是原来的abcd)

逆变换:对应乘以变换的逆矩阵

变换组合

  • 复杂变换可以通过一系列简单变换得到
  • 变换的顺序很重要(矩阵乘的顺序)

从右到左逐个应用矩阵

组合:预先乘以n个矩阵,得到一个表示组合变换的单个矩阵;一个3*3的矩阵,经过很多次变换后还是一个3*3的矩阵;

  • 通过矩阵相乘进行组合
  • 对性能非常重要!

分解:以任意一个点进行旋转,先把点移动至原点,而后进行旋转,再把原点移回去

旋转矩阵的逆等于旋转矩阵的转置:想求一个向反方向旋转的角度,先写出来个正向的旋转,然后把矩阵给转置

如果一个矩阵的逆等于这个矩阵,就把它叫做正交矩阵


04 Transformation Cont.

三维变换

同样三维引入齐次坐标,点加一个1、向量加一个0;先应用线性变换然后平移

三维的缩放和平移

在三维空间,绕着某一个轴旋转,哪一个轴不变

绕x轴旋转:y到z;绕z轴旋转:x到y;绕y轴旋转就会变成:z到x,所以绕y轴旋转是相反的

复杂的旋转都可以把它分解成绕XYZ轴的旋转,

视图变换

MVP:model transformation 模型变换;view transformation 视图变换; projection transformation 投影变换

相机:放在哪;往哪看;向上方向

相对位置不变,画面就不会变,所以总是把相机放在原点、看向-Z、Y朝上、并将对象和相机一起动

先做一个平移把e移动到0;再把g旋转到-Z上;把t旋转到Y

将这个过程写成矩阵,因为原始旋转不好求,所以先求逆变换,然后转置

投影

正交投影(将相机放得无限远) & 透视投影

正交投影

简单的正交:相机位于原点,删除z轴,将生成的矩形平移并缩放为[-1,1]²

通常做法是:

  • 定义一个空间中的立方体,X轴上定义左右[l,r]、Y轴上定义上下[b,t],Z轴上定义远近[f,n](我们沿着-Z方向去看,所以小的放前面near>far)
  • 将其移动到原点
  • 然后缩放到标准立方体[-1,1]³

然后将其写成矩阵:

  • 长宽相加除以2;
  • 然后再缩放将其变成2(-1到1的范围是2)

透视投影

透视投影让平行线看起来不再平行

先把截锥体压成长方体,再做一次长方体:

  1. 近平面不变
  2. 远屏幕z值不变,只在平面内向内收缩
  3. 中心的不发生变化

xy:

  • 从侧面看,根据相似三角形,两个点y的比值就是n与z的比值,同样从上面看可以得出x的比值
  • 这样任何一个点我们都可以写成这样,但是Z不知道,可以都乘Z:Z还是不知道,XYZ就可以映射到这样一个向量( (x,y,z,1),(kx,ky,kz,k!=0),(xz,yz,z²,z!=0)都是在表示三维中的同一个点,所以可以同时乘k也可以同时乘z )
  • 根据矩阵乘向量可推出矩阵中的很多元素

近平面z:

任何一个点在近的平面上是不变的、远处的平面经过变换后也不会发生变换

  • 把z换成n,对于已经近的平面上的点永远会映射回它自己,可以把它们都乘以n,
  • 可得矩阵第三行乘以这个矩阵等于n²,
  • 因为n²跟xy都没有关系,所以前两个数必然是0

远平面z:

原平面中心点不变,我们希望最后一个数是f,所以都乘以f

我们将近远平面都展开,得到两个式子,就可以解出AB

我们将挤成长方形做完,然后做正交投影就可以得出透视投影

透视投影视锥需要两个概念:定义垂直可视角度以及长宽比

垂直可视角度除以2,可得一个直角三角形,只要知道距离相机的距离n,就可以求得高度


05 Rasterization 1 (Triangles) 光栅化-三角形的离散化

像素屏幕

对于屏幕来说:

  • 是一个二维的像素阵列
  • 阵列大小:分辨率
  • 一种典型的光栅显示器(光栅:德语屏幕;光栅化:在屏幕上绘图

像素:

  • 目前:像素是一个颜色均匀的小方块
  • 颜色是(红、绿、蓝)的混合体
  • 像素使用整数坐标来描述(x,y)

先忽略z,将xy拉到[0,width]*[0,height]的高度;先缩放,再平移,写成一个视口变换矩阵

为什么是三角形?

  • 最基础的多边形
  • 可以分解其他多边形
  • 一定是平面的
  • 内部轮廓分明
  • 定义良好的插值方法 三角形上的顶点(重心插值)

采样

我们可以通过采样对函数进行离散化;使用像素中心进行采样

如果每个像素中心都在三角形内,则进行采样;

  • 定义一个函数,输入点的坐标判断是否在三角形内部,取像素中心xy各+0.5
  • 结果放在一个二维数组里,1为显示
  • 使用两个for循环将所有点的坐标传入
  1. 因为很多像素是不需要计算的,所以可以使用边界框,使用三角形x的最小最大值和y最小最大值,这个方形区域内的像素做判断
  2. 也可以找到三角形对于每一行的最左和最右做判断

06 Rasterization 2 (Antialiasing and Z-Buffering) 光栅化-深度测试与抗锯齿

傅里叶变换

采样产生的瑕疵 Artifacts:

  • 锯齿
  • 摩尔纹
  • 车轮效应

信号的变化速度太快,导致采样的速度跟不上变化的速度

在采样之前做一个模糊 Pre-Filtering,然后再采样

  • Antialiasing:先模糊再采样
  • Blurred Aliasing:先采样再模糊
  • 可以通过余弦定义频率f、周期;
  • 傅里叶级数展开:任何一个周期函数,都可以把它写成一系类正弦和余弦函数的线性组合和一个常数项
  • 傅里叶变换:给定任何一个函数,都可以让它经过一个相当复杂的操作,变成另外一个函数;还可以通过逆变换变回原来的函数

通过对多条不同频率的函数,使用相同的方法进行间隔采样 ∴ 对于函数来说,采样的评率应该匹配函数的频率

走样:用同样的采样方法采样两种完全不同的频率,但结果相同

滤波Filtering:去掉某些频率

中心是低频信息,周围是高频信息

频谱:傅里叶变换能让我们看到任何在各个不同的频率长什么样,频谱(十字线是周期边界条件)

  • 高通滤波器:只让高频信息通过,留下的主要是边缘
  • 低通滤波器:只让低频信息通过,边缘都被模糊掉了
  • 去掉部分高频和低频信息

卷积

滤波 = 平均 = 卷积

卷积:将可以滑动的滤波的格子,跟信号对应的格子做点乘,结果写到格子上;取原始格子的三个数做加权平均

对两个信号进行卷积,对应到两个信号各自的频域上,是对两个信号频率的乘积

时域上的乘积意味着频域上的卷积,在频域中,反之亦然

选项1:

  • 在时域中通过卷积进行滤波(1/9是做归1化保证亮度不变)

选项2:

  • 频域变换(傅里叶变换)
  • 乘以卷积核的傅里叶变换
  • 转换回时域(傅里叶逆变换)

盒子=低通滤波器;盒子在时域上变大,在频域上缩小了;更大的滤波器=更低的频率,更模糊

采样

采样=重复 频率内容

采样就是重复原始信号的频谱

走样:采样的间隔会导致频谱以不同的间隔移动,频谱在搬移的情况下发生了混叠

反走样

  • 选项1:提高采样率 基本上增加了傅里叶域中副本之间的距离,更高分辨率的显示器、传感器、帧缓冲区…但是:成本高昂,可能需要非常高的分辨率
  • 选项2:抗锯齿 采样前消除高频,进行模糊

先做1像素的box-blur方框模糊卷积f(x,y),然后在每个像素的中心进行采样

在光栅化一个三角形时,对被三角形覆盖的像素,求像素内的平均值,f(x,y) = inside(triangle,x,y),。


通过多重采样消除混叠(MSAA):

将一个像素划分出很多小的点(并没有提高分辨率,相当于采样时提高了计算精度),对每一个小像素进行判断,然后平均起来

其他抗锯齿方法:

  • FXAA (Fast Approximate AA):先得出有锯齿的图,找到边界替换成没有锯齿的边界,后期处理和采样无关,非常快
  • TAA (Temporal AA) :复用上一帧的信息

超分辨率/超采样:

  • 从低分辨率到高分辨率
  • 基本上仍然存在“样本不足”的问题
  • DLSS(深度学习超级采样)

THE END