Games101学习笔记(持续更新中)
Games101
一、Lecture 01 计算机图形学概述
(一)什么是图形学
Computer Graphics,使用计算机来合成和处理视觉信息的技术 / 领域。
(二)为什么学图形学
1、图形学主要应用
- 电子游戏(游戏画面、渲染等)
- 电影(特效、面部捕捉、渲染等)
- 设计(CG/概念图)
- 可视化(操纵视觉信息的方法)
- 虚拟现实VR 与 增强现实 AR
- 数字插画
- 模拟仿真
- 图形用户接口 GUI
- 字体设计 Typography
2、图形学的难点
- 实现虚拟世界逼真的交互
- 对真实世界物理规律的深刻理解
- 新的计算方法、显示方法、新技术
3、技术挑战
- 透视、投影、曲线、曲面相关数学原理
- 光照与着色的物理机制
- 三维形状的表示与运算
- 动画与仿真
- 三维图形软件编程与硬件
4、为什么要学
Computer Graphics is AWESOME!
(三)主要课程
- 光栅化
- 曲线和曲面
- 光线追踪
- 动画 / 模拟 / 仿真
(四)这门课不说什么
- OpenGL / DirectX / Vulcan(图形学 API)
- Shader(着色器)
- Maya / 3DS / Blender(3D建模)
- Unity / Unreal(游戏开发引擎)
- Computer Vision / Deep Learning(计算机视觉/深度学习)
- 两者都不属于计算机图形学范畴
- 计算机视觉:一切需要猜测的内容,比如识别,分析理解东西
- 深度学习:比如人脸生成,是在图像层面上的操作
计算机图形学与计算机视觉
- 图形学不是计算机视觉。
- 计算机视觉:猜测、预测、分析处理
- 计算机视觉是理解这个世界,计算机图形学是创造这个世界

当今各个学科结合越来越紧密,边界越来越模糊。
二、Lecture 02 向量与线性代数
(一)图形学依赖的知识
- 基础数学 —— 线性代数、微积分、统计学
- 基础物理 —— 光学、力学
- 其他 —— 信号处理、数值分析
- 以及一些美感
(二)向量
-
向量:具有大小和方向的量,没有绝对的起点。记作 \vec{a} 或 粗体 \boldsymbol{a}
-
向量的模长:向量的模长(长度),记作 ∥a∥
-
向量归一化:长度为1的向量,计算方式为 \hat{\boldsymbol{a}} = \dfrac{\boldsymbol{a}}{|\boldsymbol{a}|}
-
向量加法:使用三角形法则或者平行四边形法则
-
笛卡尔坐标系:让向量起点为坐标原点,这样可以使用基向量 X、Y 线性组合表示一个向量。X 和 Y 通常为正交单位向量(互相垂直的单位向量)。
- 向量表示:\mathbf{A} = \begin{pmatrix} x \\ y \end{pmatrix}、\mathbf{A}^T = (x,\ y)。
- 向量的模长: \|\mathbf{A}\| = \sqrt{x^2 + y^2}
-
向量点乘(Dot):
- 说明: \vec{a} \cdot \vec{b} 可以看作是 \vec{a} 与 \vec{b} 在 \vec{a} 上的投影 的长度的乘积。
- 几何定义:\vec{a} \cdot \vec{b} = \|\vec{a}\| \|\vec{b}\| \cos\theta
- 点积求夹角余弦:\cos\theta = \frac{\vec{a} \cdot \vec{b}}{\|\vec{a}\| \|\vec{b}\|}
- 单位向量求夹角余弦:\cos\theta = \hat{a} \cdot \hat{b}
- 性质:
- 交换律: \vec{a} \cdot \vec{b} = \vec{b} \cdot \vec{a}
- 分配律: \vec{a} \cdot (\vec{b} + \vec{c}) = \vec{a} \cdot \vec{b} + \vec{a} \cdot \vec{c}
- 数乘结合律: (k\vec{a}) \cdot \vec{b} = \vec{a} \cdot (k\vec{b}) = k(\vec{a} \cdot \vec{b})
- 笛卡尔坐标系下的点乘:\vec{a} \cdot \vec{b} = \begin{pmatrix} x_a \\ y_a \end{pmatrix} \cdot \begin{pmatrix} x_b \\ y_b \end{pmatrix} = x_a x_b + y_a y_b
- 应用:
- 计算两个向量之间的夹角
- 计算一个向量在另一个向量上的投影
- 衡量两个方向的接近程度(越接近\|\vec{a}\| \|\vec{b}\|,两向量越同向)
- 判断方向是向前还是向后
-
向量叉乘(Cross):
-
说明:叉乘结果与两个原向量正交(垂直),方向由右手螺旋定则确定:以 \vec{a} \times \vec{b} 为例,右手四指从a指向b并握紧,最终拇指朝向就是叉乘结果向量的方向。
-
模长公式:\|\vec{a} \times \vec{b}\| = \|\vec{a}\| \|\vec{b}\| \sin\phi
-
性质:
-
坐标轴单位向量的叉乘:\vec{x} \times \vec{y} = +\vec{z}(排列组合共6种)
-
反交换律:\vec{a} \times \vec{b} = -\vec{b} \times \vec{a}
-
自身叉乘为零向量:\vec{a} \times \vec{a} = \vec{0}
-
分配律:\vec{a} \times (\vec{b} + \vec{c}) = \vec{a} \times \vec{b} + \vec{a} \times \vec{c}
-
数乘结合律:\vec{a} \times (k\vec{b}) = k(\vec{a} \times \vec{b})
-
笛卡尔坐标系下的叉乘:
- 分量形式: \vec{a} \times \vec{b} = \begin{pmatrix} y_a z_b - y_b z_a \\ z_a x_b - x_a z_b \\ x_a y_b - y_a x_b \end{pmatrix}
- 矩阵形式:\vec{a} \times \vec{b} = A^* \vec{b} = \begin{pmatrix} 0 & -z_a & y_a \\ z_a & 0 & -x_a \\ -y_a & x_a & 0 \end{pmatrix} \begin{pmatrix} x_b \\ y_b \\ z_b \end{pmatrix}
-
应用:
- 判断两个向量左右关系。
- 判断一个点位于凸多边形的“内外”关系。
-
-
标准正交基 / 坐标系:坐标系对表示点、位置、空间坐标至关重要,核心的问题就是不同坐标系 / 基之间的变换。
-
标准正交坐标系:满足以下条件的 3 个向量构成标准正交基
- 单位向量: \|\vec{u}\| = \|\vec{v}\| = \|\vec{w}\| = 1
- 正交: \vec{u} \cdot \vec{v} = \vec{v} \cdot \vec{w} = \vec{u} \cdot \vec{w} = 0
- 第三个向量由前两个叉乘得到: \vec{w} = \vec{u} \times \vec{v} \quad
-
向量分解(投影分解):
- 任意向量都可以用标准正交基线性表示,本质是在三个基向量上的投影之和
- \vec{p} = (\vec{p} \cdot \vec{u})\vec{u} + (\vec{p} \cdot \vec{v})\vec{v} + (\vec{p} \cdot \vec{w})\vec{w}
-
(三)矩阵
- 矩阵:可以理解为一个由数字组成的二维数组,在图形学中被广泛用于变换,比如平移、旋转、错切、缩放等。
- 矩阵加法与标量乘法:比较简单,对应元素分别操作。
- 矩阵乘法:(M \times N) \cdot (N \times P) = (M \times P)
- 性质:
- 不满足交换律:大部分情况下 AB \neq BA
- 结合律:(AB)C = A(BC)
- 分配律:A(B+C) = AB + AC 、 (A+B)C = AC + BC
- 矩阵的转置:
- 交换矩阵行与列: \begin{pmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \end{pmatrix}^T = \begin{pmatrix} 1 & 3 & 5 \\ 2 & 4 & 6 \end{pmatrix}
- 性质:(AB)^T = B^T A^T
- 单位矩阵:I_{3\times3} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix}
- 逆矩阵:AA^{-1} = A^{-1}A = I
- 矩阵乘积的逆: (AB)^{-1} = B^{-1}A^{-1}
- 向量乘法转换为矩阵乘法:
- 将向量视为 m 行 1 列的列矩阵
- 点乘:\vec{a} \cdot \vec{b} = \vec{a}^T \vec{b} = \begin{pmatrix} x_a & y_a & z_a \end{pmatrix} \begin{pmatrix} x_b \\ y_b \\ z_b \end{pmatrix} = \begin{pmatrix} x_a x_b + y_a y_b + z_a z_b \end{pmatrix}
- 叉乘:\vec{a} \times \vec{b} = A^* \vec{b} = \begin{pmatrix} 0 & -z_a & y_a \\ z_a & 0 & -x_a \\ -y_a & x_a & 0 \end{pmatrix} \begin{pmatrix} x_b \\ y_b \\ z_b \end{pmatrix}
附录:课程作业环境搭建
1、准备
我使用的是VS2022+OpenCV+Eigen。需要准备如下三样东西:
- VS2022:官网下载即可
- Eigen:可以在github中下载,我下载的是这个:janm31415/eigen-3.4.0: Mirror of eigen 3.4.0
- OpenCV:下载对应平台的即可,比如Windows:Just a moment…
2、配置Eigen
- 右键解决方案,点击属性

- 选择C/C++ → 常规 → 附加包含目录,选中Eigen所在目录即可。

- 验证,在main中输入如下代码,如果没有报错并且正确打印两个矩阵的信息则说明配置正确。
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main() {
cout << "<========================>" << endl;
Matrix<float, 3, 3>matrixA;
matrixA.setZero();
cout << matrixA << endl;
Matrix<float, 3, 3>matrixA1;
matrixA1.setZero();
cout << '\n' << matrixA1 << endl;
cout << "<========================>" << endl;
return 0;
}
3、配置OpenCV
-
下载好后,先配置环境变量,将
opencv\build\x64\vc16\bin这个路径添加到环境变量的Path中 -
右键解决方案,点击属性,选择VC++目录,配置包含目录和库目录
- 包含目录:
opencv\build\include - 库目录:
opencv\build\x64\vc16\lib
- 包含目录:

- 配置附加依赖项,在刚才的lib目录下找到这个库文件,复制名字

- 然后在 链接器 → 输入 → 附加依赖项 中将刚才复制的名字粘贴进去

- 之后运行如下程序进行测试,如果能正常打开图片代表成功
#include <opencv2/opencv.hpp>
using namespace cv;
int main() {
Mat img = imread("你的图片路径");
imshow("test", img);
waitKey(0);
return 0;
}