俗话说的好,技(gong)多(zuo)不(zhao)压(bu)身(dao),作为一个N年游戏玩家,不得学学游戏蕴含的基本原理?
[本文笔记来自Games101课程学习过程]
官方网站:GAMES: Graphics And Mixed Environment Symposium
纯个人学习记录,促进自身理解,如有不足和错误,还请斧正。
1.线性代数入门
首先需要一定的数学知识,这些基本包括在工科生必修课程中,所以本节简要介绍。实在不记得就翻翻书,温故而知新。
1.1向量的点乘、叉乘
1.1.1 右手系、左手系判断
使用右手定则,大拇指.jpg
1.1.2 向量点乘前后判断,叉乘左右、内外的判断
1.2矩阵的运算
大家都会
2.坐标变换【齐次坐标】
对于计算机图形来说,最终还是要呈现在我们的屏幕上,从现实生活中我们知道,从不同的角度观察事物会有不同的画面呈现,而在计算机中也是如此。对于空间的一个个点之间的关系,其实很容易用数学去描述。图形的变换使用矩阵的运算则变得简单。
2.1 3D/2D Transformations
对于三维空间的坐标点或者向量往往采用四维表示,其中第四位采用1表示点,采用0表示向量。
对点/向量进行变换时,使用矩阵进行运算。
注意:可以将旋转平移等操作分解为不同矩阵,先左乘旋转矩阵,再左乘平移矩阵【这一步具象化为对于实际图形的变换为:先平移再旋转,具体理解为先平移到原点再旋转,与先绕原点旋转再以同样的方式平移的区别】:
旋转的一些性质:[注意正交矩阵]向相反的方向旋转就是采用矩阵的转置,同时此转置与逆相同。
矩阵的逆适用于所有的逆变换过程。
2.2 MVP transformation
2.2.1三维下的旋转的分解,绕xyz轴旋转
详细见2.2.4 MVP(1)
2.2.2正交投影 orthographic projection
正交投影就是将图形按照平行光线方向投射至相机。
2.2.3透视投影 perspective projection
在日常中,是存在着透视关系的,例如我们观看铁路,由近往远看两条铁路会逐渐收窄。
这也是透视视图的由来,从远平面投影至近平面有一个变换的过程。
从远平面投影至近平面使用矩阵,变换完成后再进行一次正交投影。
以上注意:都是变换矩阵左乘向量或者点。
2.2.4 M V P
(1)Model Transformation:【绕轴旋转等】
为什么叫model transformation?因为需要对图形本身进行旋转变换。
其变换矩阵如下所示:
(2)View Transformation:【视角变换】
一般来说,将相机视角先移动到原点,再将y轴朝上,看向-z方向,其变换矩阵如下:
由于对于gte直接变换至原坐标系比较困难,所以采用逆变换,相对较简单反推变换矩阵Rview。
(3)Projection Transformation:【投影变换】
正交投影,思路还是同一般坐标一样,先将图形平移至原点,再进行scale。
Mortho为上图。
透视投影,形状类似一个平头截体。n为近平面,f为远平面z轴坐标。
为上图。
(4)Viewport Transformation【个人理解是标注视角(屏幕)大小的另一种方式】
Canonical Cube to Screen:
将MVP操作后的图形移动变换至[0, width]x[0, height]大小的屏幕。为像素表示做准备。
3.光栅化Rasterization
光栅化,顾名思义就是让图形到光栅显示器上显示给人类观看。
3.1 Triangles
计算机图形常用三角形网格表示。
3.1.1 raster display
-
示波器
-
CRT显示器
-
LCD
-
LED
-
Electronic Ink
3.1.2 为什么要使用三角形作为基础形状
-
作为基础的多边形,可以构成其他的多边形。
-
三点构成一个平面。
-
内部方便定义。
-
在顶点上能够有良好的方法对三角形内的参数数值进行插值处理。
3.2 Sampling
3.2.1 如何判断像素是否在三角形内
屏幕是由一个个像素点组成的,而我们知道一个三角形是一块连续的图形,当三角形只包含部分像素点时,判断像素点是否属于该三角形内,对于图形显示尤为重要。
3.2.2 采样(sampling)
(1)判断像素中心在三角形内部
注意,对于在两个三角形共同边界上的像素,通常由渲染器的定义决定,例如:下左边上的像素属于左边的三角形,上右边上的像素属于右边的三角形。
加速方法:
-
1)边界箱体:将三角形框入一个Box内,这样就能够不对所有的像素进行判断操作。
-
2)Incremental Triangle Traversal :一行一行进行像素点遍历,减少像素点判断数量?【适用于薄三角形和旋转三角形】
(2)实际的显示器的像素是离散的,是颜色均匀的正方形,易产生走样问题。
3.3 Antialiasing 抗走样(包括处理采样的错误,失误,不准确等)
3.3.1 什么是aliasing(走样)
-
边缘----锯齿空采样
-
摩尔纹----欠采样
-
车轮效应----时间采样误差
-
...
(1)欠采样为什么会造成走样?
低频信号与高频信号采样点值重合。高频信号采样点不足,导致认为采样到了低频信号,即无法区分两个信号。
(2)滤波(filtering)
上述问题的解决方案,便是滤波。
Spatial domain vs Frequency domain
对于Spatial domain的理解其实就像CV里的卷积神经网络对于图像的卷积计算【根据卷积核计算】,其可以通过傅里叶变换转化为Frequency domain中的信号。反过来就是傅里叶逆变换。
Spatial domain中采用卷积符号计算,Frequency domain中采用乘法计算过滤信号。
Filtering = Convolution = Averaging
Sampling = Repeating Frequency Contents
将采样过程与滤波的内容结合起来:采样其实是重复频率的内容。
采用卷积进行averaging像素内的值:Convolve f(x,y) by a 1-pixel box-blur ,f(x,y) = inside(triangle,x,y)即等于三角形覆盖像素点的面积。
先filter再sample 非常重要的一点!先进行滤波后,能获得更多的(过渡性)像素点采样。
3.3.2 减少aliasing的方法
(0)加像素分辨率5ex5e!
(1)在采样之前进行模糊处理(预过滤)
-
将采用卷积进行averaging像素内的值 [先filter再sample]
-
ag: ???
(2)SMAA【超采样】
超采样指的是通过采样一个像素内的多个位置,并对它们的值取平均值来获取像素的最终显示。
游戏中常见的抗锯齿4X4, 16X16等
当然,超采样所带来的代价是超分辨率带来的NxN倍的计算量。
(3)FXAA
(4)TAA
(5)DLSS
参考:
3.4 Z-buffering 深度缓冲
我们在屏幕上显示的图形都是二维的,这就不可避免地需要考虑图形的远近投射到屏幕上所带的深度属性。
首先假设z=0最近,z=无穷为最远
Store current min. z-value for each sample (pixel)
Needs an additional buffer for depth values
-
frame buffer stores color values
-
depth buffer (z-buffer) stores depth
伪代码如下:
for (each triangle T)
for (each sample (x,y,z) in T)
if (z < zbuffer[x,y]) // closest sample so far
framebuffer[x,y] = rgb; // update color
zbuffer[x,y] = z; // update depth
else
; // do nothing, this sample is occluded
Z-buffer的复杂度为O(n),对于同一个像素点上的n个三角形
其示意如下图: