Games101
文章目录
- Games101
- 一、Review of Linear Algebra 线性代数
- 向量
- 向量点乘:==判断同向反向、接近程度==
- 点乘基本属性
- 点乘坐标系运算
- 向量投影
- 向量叉乘:==判定左右、判定内外==
- 叉乘基本属性(右手坐标系):不满足交换律
- 叉乘坐标系运算
- 矩阵
- 矩阵乘积
- 矩阵乘积属性:不满足交换律
- 矩阵的逆
- 二、Transformation 变换
- 1. 模型变换 Modeling Transformation
- 缩放矩阵
- 镜像矩阵
- 切变矩阵
- 旋转矩阵
- 齐次坐标变换
- 平移变换
- 仿射变换
- 引入齐次坐标后的二维线性变换
- 三维变换矩阵
- 三维旋转矩阵
- 2. 视图变换 Viewing Transformation
- 初始相机定义
- 相机标准位置
- 相机旋转矩阵
- 3. 投影变换 Projection Transformation
- 正交投影 Orthographic Projection
- 透视投影 Perspective Projection
- 三、Rasterization 光栅化
- 采样
- 光栅化
- AABB包围盒
- 走样
- 反走样
- 低通滤波
- MSAA
- 其它抗锯齿方法
- 四、 Shading 着色
- 布林冯模型 Blinn-Phong反射模型
- 漫反射 Diffuse Reflection
- 高光 Specular Term
- 环境光 Ambient Term
- 着色频率
- 图形渲染管线(Real-time Rendering)
- 纹理映射
- 重心坐标
- 纹理的应用
- 环境贴图
- 凹凸贴图、法线贴图
- 位移贴图
- 五、Geometry 几何
- 几何表示方法
- 隐式几何 Implicit Representations of Geometry
- 显式几何 Explicit Representations of Geometry
- 曲线和曲面
- 曲线
- 贝塞尔曲线
- 逐段(Piecewise)贝塞尔曲线
- 其他
- 曲面
- 网格处理
- 网格细分
- 1. loop subdivision
- 2. catmull-clark subdivision
- 网格简化
- 网格正规化
一、Review of Linear Algebra 线性代数
向量
单位向量:长度为一的向量
操作:向量求和–平行四边形法则,三角形法则
向量点乘:判断同向反向、接近程度
点乘基本属性
点乘坐标系运算
向量投影
向量叉乘:判定左右、判定内外
叉乘基本属性(右手坐标系):不满足交换律
叉乘坐标系运算
叉乘结果是正的说明后项向量在前项向量的左侧,叉乘结果是正的说明后项向量在前项向量的右侧;
由此可以得到点在图形内还是在图形外
右手三维直角坐标系
矩阵
矩阵乘积
乘积的i行j列元素 = i行向量点乘j行向量
矩阵乘积属性:不满足交换律
矩阵的逆
向量的点乘和叉乘写成矩阵相乘的形式:
A*:伴随矩阵
二、Transformation 变换
1. 模型变换 Modeling Transformation
缩放矩阵
镜像矩阵
切变矩阵
旋转矩阵
θ为逆时针旋转的角度
线性变换:一个向量 = 一个矩阵 * 另一个向量
齐次坐标变换
引入齐次坐标的理由是平移变换
引入齐次变换后:
平移变换
向量具有平移不变性
点+点 = 这两个点的中点
仿射变换
( = 先应用前述 线性变换,再应用平移变换)
引入齐次坐标后的二维线性变换
逆变换矩阵的效果就是将原来的变换还原:M ➡ M-1
向量会从右向左逐个运用变换矩阵
三维空间引入齐次变换:
三维变换矩阵
(先线性变换,再平移)
正交矩阵:矩阵的逆等于它的转置(例如旋转矩阵)
三维旋转矩阵
罗德里格斯旋转公式:绕任意过原点的轴旋转任意角度
绕任意轴:把旋转中心点平移到原点再进行操作,最后把所有东西再移回去
四元数的引入:旋转与旋转之间的插值
2. 视图变换 Viewing Transformation
视图变换:改变相机位置、方向
初始相机定义
相机标准位置
相机旋转矩阵
模型要和相机一起变换
3. 投影变换 Projection Transformation
3D到2D
正交投影 Orthographic Projection
映射到标准立方体:先把中心点平移到原点,再缩放
透视投影 Perspective Projection
映射到立方体的变换矩阵:
三、Rasterization 光栅化
定义视锥的长宽比(Aspect ratio)和可视角度(fovY)
光栅化 = 绘制到屏幕上
像素:一个像素是一个有着均匀颜色的小方块,是RGB的混合
像素的坐标:
视口变换矩阵:
三角形得到广泛应用的原因:三角形是最基础的多边形;任何多边形都能拆成三角形;三角形内部一定是平面的;三角形内外定义是清晰的
采样
给一个三角形,判断像素中心在不在三角形内:
光栅化
AABB包围盒
走样
走样:锯齿、摩尔纹、车轮效应
走样原因:信号变化太快,采样太慢
反走样
低通滤波
在采样之前先做模糊
傅里叶级数展开
采样频率如果太慢,就会产生走样
傅里叶变换
可以把某个函数/图像从时域Spatial Domain变到频域Frequency Domain(频谱)
低频多,高频少:
滤波:把某个特定的频段去掉。
下图为高通滤波,只有高频信号可以通过。
下图为低通滤波,只有低频信号可以通过。
带通滤波
滤波 = 平均 = 卷积
卷积示例:
时域上的卷积相当于频域上的乘积,时域上的乘积相当于频域上的卷积
每个像素取周围3*3的盒子(box filter)做点乘操作:模糊
如果盒子在时域上变大,那么对应在频域上会变小
时域上:采样 = 原始信号 * 冲击函数
在频域上:采样就是在重复原始信号的频谱
产生走样的原因:
采样的间隔会影响频谱的复制粘贴间隔,采样的不够快就会导致复制粘贴原频谱的间隔小 (混叠)
改善走样造成的问题的方法:增加采样频率(但是需要高分辨率);反走样:
先拿掉高频信号(模糊),再采样
对于一个三角形:对每个覆盖到的像素求平均
MSAA
多重采样抗锯齿,用更多采样点进行反走样
把一个像素分为多个采样点,近似一个合理的覆盖率
通过MSAA可以得到抗锯齿效果,但是增大了计算量,不过很多样本得到了复用,计算量不会增加那么大
其它抗锯齿方法
SSAA:先把低分辨率变为高分辨率处理(增加采样点),再变回低分辨率
TAA 时间性抗锯齿:目前最主流的抗锯齿技术,复用上一帧每个像素的值继续产生作用,能够很好地缓解物体运动造成的闪烁。抗锯齿效果极佳,但是会造成严重的画面模糊。
FXAA 快速近似抗锯齿:图像的后期处理,检测图像的边缘并对其进行模糊处理。抗锯齿效果较差,但是性能消耗极低。
SMAA边缘抗锯齿技术:类似于FXAA,是一种基于图像的抗锯齿技术,它通过检测和平滑图像中的边缘来减少锯齿效应。
TXAA:TAA+MSAA
FSR2:超分辨率 Super resolution:是 AMD开发的从低分辨率到高分辨率的优化方法,它会根据之前帧的信息以及当前帧的低分辨率图像生成高分辨率图像。这种技术可以在保持较高帧率的情况下,显著提升图像的细节和清晰度。
DLSS :是 NVIDIA 开发的一种图像重建技术,利用深度学习和 AI 算法来提升游戏的图像分辨率。
四、 Shading 着色
Z-Buffer 深度缓存
对每个像素/采样点记录最浅深度(离我们最近的距离)为浮点型
时间复杂度为O(n),和顺序无关
顺序:MVP变换,Viewport,Rasterization,Shading
着色:对不同物体应用不同材质的过程
布林冯模型 Blinn-Phong反射模型
最基础的着色模型
高光、漫反射、环境光
shading point
n:法线向量
v:观测方向
l:光照方向
表面属性:颜色、亮度(shininess)
shading不考虑其它物体的存在,也不考虑阴影,只考虑每个点自己,有局部性(local)
漫反射 Diffuse Reflection
任一shading point周围单位面积接收到的能量和光照方向与法线方向之间的夹角的余弦成正比
cosΘ = l · n (l和n都为单位向量)
球壳离光源距离为1时,定义光强为I;则球壳离光源距离为r时,定义光强为I/r2(球壳面积*光强守恒)
漫反射公式
到达的能量➡接收的能量
点有颜色的原因:它吸收了一部分能量,反射出去的是没吸收的能量
漫反射与v完全没关系,从各个地方看到的都是一样的
高光 Specular Term
高光反射是在观察方向接近镜面反射的方向,即法线向量接近半程向量方向
高光反射公式
用指数是降低容忍度,布林冯一般用100~200
环境光 Ambient Term
环境光反射公式
总结:布林冯反射模型公式:对每个点应用该公式
着色频率
Flat Shading:对每个三角形求法线,计算出着色结果就是一个三角形的着色结果
Gouraud Shading:对每个顶点着色,三个顶点为一个三角形,每个三角形内部的颜色通过插值的方法计算
求顶点法线:顶点相邻面的法线加权求平均
Phong Shading:对每个像素着色
每条法线都是单位向量
图形渲染管线(Real-time Rendering)
shader:每个像素都会执行一次的程序
vertex shader:顶点着色器
fragment/pixel shader:片段/像素着色器
GPU的并行度很高
纹理映射
uv
重心坐标
重心坐标是为了插值
对于三角形内的点坐标:
通过面积比得到重心:
做插值处理:
但是重心坐标在投影下会变化,所以三维空间中的属性建议在三维空间中做插值,再对应到二维结果上去
纹理映射实现伪代码:
texel:纹理元素
纹理分辨率太低的解决方法:
Nearest:把小数部分四舍五入成为整数
Bilinear:双线性插值,找到相邻的4个整数点,进行两段lerp插值
Bicubic:与Bilinear类似,是找到相邻的16个整数点,进行三段lerp插值
纹理分辨率太高(纹理太大)会产生走样问题:
原因:远处一个像素覆盖多个纹素
解决方法:避免采样
使用范围查询,快速得出平均值
MipMap:快、不准、正方形的范围查询
存储量是原来的4/3
一张图片中有很多图片,每一张图片的分辨率是递减的,渲染器在调用它们时会根据距离自动切换
像素对应的纹理区域近似:
通过这个区域计算出它在第几层会变成一个像素大小
三线性插值:两次查询,一次插值
MipMap问题:Overblur
解决方法:
引入各向异性过滤Anisotropic Filtering
- Ripmaps and summed area tables 预先计算在x、y两个方向的压缩图,允许查到矩形区域
-
引入EWA过滤,将不规则图形拆成很多椭圆,多次查询
纹理的应用
环境贴图
将环境光记录在球体上再展开会扭曲
解决办法 Cube Map:存在立方体上变成六张纹理图,但是需要额外的计算
凹凸贴图、法线贴图
用纹理图定义一个点的相对高度、法线信息,没有改变几何信息
有关法线信息的二维计算:
有关法线信息的三维计算:
位移贴图
相比于凹凸贴图,位移贴图是真的移动了顶点的位置
DirectX提供了动态曲面细分,根据需要细分模型
纹理还可以:定义三维程序噪声、存一些计算好的信息(AO信息)、体积渲染
五、Geometry 几何
几何表示方法
隐式几何 Implicit Representations of Geometry
满足一定特定关系的点都在一个平面上 f(x,y,z) = 0
判定一个点是否在平面上还是平面内或外很容易(函数大于等于小于0),但找出所有在平面上的点很难
表示方法:
-
代数平面(隐式):用函数式定义几何
-
CSG (Constructive Solid Geometry) (隐式) : 用数学运算定义几何
-
距离函数(隐式):描述一个点到这个表面的最近距离,可正可负。可以进行blend操作(SDF : signed distance function)
-
水平集(隐式):类似于距离函数,区别是把距离写在格子上。等于0的地方就是物体表面。
-
分型(隐式):自相似
优点:表述很容易;查询点在里外较简单;容易做光线和表面求交点;对简单集合能给出确切描述;容易描述拓扑结构
缺点:很难描述复杂几何
显式几何 Explicit Representations of Geometry
通过参数映射的方法定义一个平面:(u,v) <—>(x,y,z)
点在平面里面还是外面很难看出
表示方法:
- 点云(显式):密集的点表示几何,变成不同的面
- 多边形面(显式):应用非常广泛,用三角形四边形等描述复杂的物体
常用文件格式:
曲线和曲面
曲线
贝塞尔曲线
用一系列的控制点定义曲线
找到时间t上的点连成曲线:
代数表示方法(线性插值):(这里的2不是平方,是次数)
规定:
- t=0时一定在起点,t=1时一定在终点;
- 如果想对贝塞尔曲线做仿射变换,则只需要对控制点做仿射变换,但是对投影不是这样
- 画出来的贝塞尔曲线一定得在所有控制点形成的凸包(最小凸多边形)内
逐段(Piecewise)贝塞尔曲线
每次用较少的控制点定义一段贝塞尔曲线,然后把这些贝塞尔曲线连起来
曲线连续:
-
前一条终点 = 后一条起点
-
保证连起来的曲线是光滑的:前一条最后一段和后一条第一段导数相同,即:
其他
样条:满足一定连续性,是一个可控的曲线
B-样条:奇函数样条,是对贝塞尔曲线的扩展,具有局部性(有一定影响范围)
曲面
原理:在两个方向上分别应用贝塞尔曲线
因此需要一个二维的控制的东西:
网格处理
几何处理:网格细分、网格简化、网格正规化
网格细分
upsampling
1. loop subdivision
只适用于全三角形网格
两步操作:三角形数量增多、调整三角形位置(区分新、旧顶点)
更新新的顶点的位置:
更新旧的顶点的位置:
2. catmull-clark subdivision
对于网格的一般情况,不只是三角形
定义:四边形面、非四边形面、奇异点(度不为4的点)
做法:为每条边和每个面加上中点,连接所有的中点
网格简化
downsampling
二次误差度量:新的点是到原来各个面的距离平方和最小的点
按照二次误差度量由小到大做贪缩:优先队列/堆