数学原来这么有用-笔记《3D数学基础:图形与游戏开发》

来源:互联网 发布:java 抽象类的方法 编辑:程序博客网 时间:2024/04/28 11:15

一,坐标系

一维的坐标系是一条直线,二维是一个平面,3维是一个立方体,坐标系用来确定物体的位置。3D坐标系分为左手坐标系和右手坐标系。判断方法:

伸出右手,让拇指和食指成“L”形,大拇指指向x正方向,食指指向y正方向,其余手指指向前方,如果其余手指跟z正方向重合,那么这个坐标系是右手坐标系,如果跟z负方向重合,那么这个坐标系是左手坐标系。

常见的坐标系:世界坐标系,物体坐标系

 

二,向量

1.数学定义

向量就是一个数字列表

2.维度

向量包含的数字的个数

3.表示方法

可以用行向量[1,2,2]也可以用列向量表示(竖着写)

4.几何定义

一个箭头

5.向量与点

点描述位置,向量描述位移

 

三,向量运算

研究向量的数学分支叫线性代数。

1.零向量

每一维都是零的向量,零向量没有方向

2.负向量

x+(-x)=0,(有零才可以定义负)

几何意义,大小相等,方向相反

3.向量的模

向量的长度叫模

4.标量与向量的乘法

[x,y,z]*i=[i*x,i*y,i*z]

几何意义:将向量长度变为原来的n倍

5.标准化向量

v=v/|v|

几何意义,长度变为1的向量

6.向量的加法和减法

每个相对的维度值,进行加减法

几何意义:高中书中有,不多说

7.向量的点乘

向量的点乘也叫内积,[a,b,c].[x,y,z]=ax+by+cz 结果是一个标量

几何意义:a.b=|a||b|cosz(z是2个向量的夹角)

8.向量叉乘

[a,b,c]X[x,y,z]=[bz-cy,cx-az,ay-bx]

几何意义:

叉乘得到的是一个垂直于2向量的向量,并且:

|aXb|=|a||b|sinz

 

三,矩阵

向量是标量的数组,矩阵是向量的数组

行数和列数相等的矩阵叫方阵。

对角矩阵是非对角线元素为0的方阵,对角线元素都为1的矩阵叫单位矩阵

1.转置

将矩阵的行变为列,列变为行,新的矩阵是原来矩阵的转置

2.标量与矩阵的乘法

将标量与矩阵的每个元素相乘

3.矩阵的乘法

乘法的结果是一个新的矩阵,矩阵的每个元素计算:c[i,j]=a[i,k]*b[k,j].mXn的矩阵只能跟nXm的矩阵相乘

4.几何解释

方阵能表示线性变换,线性变换包括:旋转,缩放,投影,镜像,仿射,线性变换的特点是保持直线和平行线,其它的几何性质如长度,角度,面积和体积就可能会变化

如果把矩阵的行解释为坐标系的基向量,那么乘以该矩阵就相当于执行了一次坐标转换,若有aM=b,我们就可以说M将a转换到b

矩阵的每一行都能解释为转换后的基向量

有了上面的2条结论,给出一个期望的变换,能够构造一个矩阵代表此变换,我们所要做的一切就是计算基向量的变换,然后将变换后的基向量填入矩阵。

 

四,线性变换

1.旋转

对于2D,和3D的旋转矩阵在网上应该很容易找到,这里要详细说的是3D中绕任意轴的旋转矩阵的推导思想

要得到v绕轴n旋转z的向量,我们要将v分解为垂直于n和平行于n的2个向量。平行于n的向量旋转后不变,垂直于n的向量,在其所在的垂直于n的平面里进行2D旋转,很容易得到旋转后的向量,最后做个向量加法。就得到所求向量。

 

2.缩放

可以通过让比例因子k按比例变大或者缩小物体,沿任意轴的缩放矩阵的推导类似于旋转矩阵的推导

 

3.投影

所有点都被拉平至垂直的轴(2D)或者平面(3D)上,这种类型的投影称作正交投影,或者平行投影,因为从原来的点到投影点的直线相互平行。

 

4.镜像

是缩放因子为-1,能够很容易实现镜像变换

 

5.切变

切变是一种坐标系“扭曲”变换,非均匀地拉伸它。切变的时候角度会发生变化,但是面积和体积却保持不变,基本思想是将某一坐标的乘积加到另一个上。例如:2D中,将y乘以某个因子然后加到x上,得到x‘=x+sy

 

组合各种线性变换

因为矩阵的乘法满足结合律,所以连续的变换,最终可以合成一个变换矩阵。

 

变换的分类:

 

线性变换

一个变换被称为线性的,必须满足下面2条性质:

1,F(a+b)=F(a)+F(b)

2,F(ka)=kF(a)

 

前面讨论的变换都是矩阵乘法,所以都是线性变换。

 

仿射变换

仿射变换是只线性变换后接着平移。

仿射变换是线性变换的超集,任何具有v'=vM+b的变换都是仿射变换

 

可逆变换,等角变换看名字都明白,呵呵

 

正交变换

 

正交变换的矩阵是正交矩阵,正交变换的基本思想是轴保持相互垂直,而且不进行缩放变换。平移,旋转和镜像是仅有的正交变换。

 

五,矩阵的更多知识

1.矩阵的行列式

行列式是一个标量,它的定义很复杂,可以从网上找到公式

几何意义

行列式等于以基向量为两边的平行四边形的面积或者平行六面体的有符号体积,正交矩阵的行列式为+-1

 

2.矩阵的逆

如果a与b矩阵相乘为单位矩阵,那么a,b互为逆。

 

3.正交矩阵

正交矩阵的逆=它的转置

正交矩阵的性质:

矩阵的每一行都是单位向量

矩阵的所有行相互垂直

 

平移虽然是正交变换,但是无法用3X3矩阵进行表示,4X4的齐次矩阵可以表示平移变换,齐次矩阵只是数学上一种方便的记法,一种技巧。

 

一般仿射变换

经过4X4矩阵的武装后,现在我们可以构造包含平移在内的一般仿射变换矩阵

例如:

绕不通过原点的轴旋转

沿不穿过原点的平面缩放

沿不穿过原点的平面镜像

向不穿过原点的平面正交投影

他们的基本思想是将变换的“中心点”平移到原点,进行线性变换,然后再将“中心点”平移回原来的位置。

开始使用平移矩阵T将点P移到原点,接着用线性变换矩阵R进行线性变换,最终的仿射变换矩阵M等于矩阵的积,即:TRT-1。

 

透视投影

透视投影的投影线不再平行,而是相交于一点,这点被称作投影中心。透视投影可以用4X4矩阵进行变换。

 

六,3D中的方位与位移

方位是通过相对于已知方位的旋转来描述的的。旋转的量称作角位移,数学上描述方位等价于描述角位移。

 

方位可以用几种方式来描述:

 

1.矩阵,旋转是正交矩阵。

优点:

可以立即进行向量的旋转

矩阵的形式被图形api所使用

多个角位移连接

矩阵的逆

 

缺点:

占用的内存太多

难于使用,因为无法很直观地看出表示的意义

病态矩阵

 

2.欧拉角

欧拉角的基本思想是将角位移分解为绕三个相互垂直轴的三个旋转组成的序列。欧拉角仅使用三个数来表达方位,并且这三个数都是角度。

优点:

容易使用

最简洁的表达方式

任意三个数都是合法的

 

缺点:

给定方位的表达方式不唯一

2个角度之间求插值非常困难

 

使用限制欧拉角可以部分解决别名问题,但是对于方向锁需要额外的限制条件。限制欧拉角和将角度差限制在一定范围内提供了一种简单的解决角度插值的方法,但是对于方向锁却很难解决。

 

3.四元数

一个四元数包含一个标量分量和一个3D向量分量[w,(x,y,z)]

四元数扩展了复数系统,它使用3个虚部i,j,k,他们的关系如下:

(不好输,还算去看wiki)

复数能够旋转2d中的向量,四元数能够旋转3d中的向量,而且很多标准的复数性质都能应用到四元数上。

欧拉证明了一个旋转序列等价于单个旋转,3d中的任意角位移都能表示为绕单一轴的单一旋转,也就是说可以用轴-角来进行描述,这里的轴是一般意思上的轴,而不是坐标系的轴。

四元数就是这样一种表示方式,但是n和角度并不是(x,y,z)和w他们的关系如下:

[cos(z/2) (sin(z/2)nx,sin(z/2)ny,sin(z/2)nz)]

 

四元数跟复数具有很多相似的定义,比如共轭,逆,负,叉乘,模

四元数乘积的模等于模的乘积,这个性质非常重要,因为它保证了2个单位四元数相乘的结果还是单位四元数。

四元数乘积的逆等于各个四元数的逆以相反的顺序相乘

(ab)-1=b-1a-1

四元数的运算还包括点乘,对数,指数,标量乘,幂

四元数最重要的一种运算slerp,它是球面线性插值的缩写,它可以再两个四元数间平滑插值。slerp运算避免了我们遇到的所有问题。

 

四元数的优点:

平滑插值

快速连接和角位移求逆

能和矩阵形式快速转换

 

缺点:

比欧拉角的空间稍微大一点

四元数可能不合法

难于使用

 

各种表达形式之间可以相互进行转换,详见160页

 

 

七,几何图元

直线,射线,线段,球,圆,平面的数学表示,相信大家在高中已经很熟悉了。

 

矩形边界框

AABB(axially aligned bounding box),它的边都平行于轴。

计算AABB

先将最小值和最大值设为“正负无穷大”或任何比实际中用到的数都大或小得多的数。接着,遍历全部点,并扩展边界框直到它包含所有点为止

AABB和边界球通常用于确定物体的边界

 

八,几何检测

直线的最近点,平面上的最近点,圆或者球上的最近点,高中的知识

 

AABB上的最近点

代码更容易看懂:

if(x<minX)x=minX;

if(x>maxX)x=maxX;

 

if(y<minY)y=minY;

if(y>maxY)y=maxY;

 

if(z<minZ)z=minZ;

if(z>maxZ)z=maxZ;

 

 

 

相交性检测

这些测试的目的是检测2个几何图元是否相交,在某些情况下还要求出相交部分。这些基本测试构成了碰撞检测系统的基础。

静态测试:检测2个静止的图元是否相交

动态测试:2个运动的图元,检测他们是否相交,以及相交的时间点。

 

直线相交,直线和平面:解方程

 

AABB和平面的相交性检测

平面可以由平面的法向量和平面上的一点来进行确定:p。n=d

一种简单的静态测试方法是,计算矩形边界框顶点和n的点积,通过比较点积与d,来检测边界框的顶点是否完全在平面的一边。如果所有点积都大于d,那么整个边界框就在平面的正面。


射线和球,圆的相交性检测

检测可以再包含射线(直线)和球心的平面中进行检测,从而将3d问题转化为2d问题。

 

球和AABB的检测

找到距球心最近的AABB点,根据点跟球心的距离就可以判断是否相交

 

射线和三角形的相交性检测

第一步计算射线跟三角形所在平面的交点

第二步计算交点的重心坐标,如果全为正,则在三角形内

 

九,三角网格

三角网格是由三角形组成的多边形网格

表示方法:

1.三角形列表

2.索引三角网格

2个列表:顶点表和三角形表

每个顶点包含一个3D位置,也可能有如纹理映射坐标,表面法向量,光照值等附加数据

每个三角形由顶点列表的三个索引组成

 

大多数图形卡并不直接支持索引三角网,渲染三角形,一般是将三个顶点同时提交。这样共享顶点会多次提交,优化的方案有:

顶点缓存

三角带:三角带是一个三角形列表,其中每个三角形都与前一个三角形共享一边。最佳情况下,三角带可用n+2个顶点存储n个面。n很大时,每个三角形平均发送一个顶点。

三角扇:三角扇使用n+2个顶点存储n个面

 

额外信息

 

纹理映射坐标:

记录2d纹理坐标,以便将纹理贴到多边形表面上

 

表面法向量:

1.计算光照

2.进行背面剔除

3.模拟粒子在表面“弹跳”效果

4.通过只考虑正面而加速碰撞检测

 

光照值

 

十,图形数学

图形管道中数据流:

1,建立场景

2,可见性检测

3,设置物体级的渲染状态

4,几何体的生成与提交

5,变换与光照

6,背面剔除与裁剪

7,投影到屏幕空间

8,光栅化

9,像素着色

 

光源:

1.点光源

2.平行光

3.聚光灯

4.环境光

 

 

光照方程:

Clit=Cspec+Cdiff+Camb 用于计算单个像素的色彩

 

Cspec:镜面反射分量,取决于物体表面的材质,观察者的位置,光源的位置

Cdiff:散射分量,取决于光源与物体的相对位置,因为散射是一个随机过程,光源与物体的相对位置影响物体单位面积上的光线数量

Camb:环境分量,用于模拟光多次反射后进入眼睛,取决于材质和全局环境光

 

物体的外观主要取决于以下四点因素:

1.物体表面的性质,即材质属性

2.表面的方位与朝向,常用单位法向量表示

3.照射来的各个光源

4.观察者的位置

 

光照方程分别考虑了上述因子的不同组合

 

雾化:用于模拟空气中粒子的浓度

 

flat着色与gourand着色

如果渲染速度不重要,我们可以逐像素地计算光照和雾化(这种称作Phong着色模型)然而这样的计算量过于巨大,所以我们必须选择:逐多边形或者顶点计算,这2项技术分别称作flat着色和gourand着色。

 

使用flat着色,整个三角形只计算一次光照值。通常计算光照的“位置”为三角形中心,表面法向量为三角形法向量。

gourand着色,又称作顶点着色。在顶点级计算光照和雾,然后这些值被线性插值于整个多边形面。

 

缓存

一个是帧缓存,一般是双缓存,一个缓存当前显示的图像,一个离线缓存正在渲染的图像

一个是z-缓存,存入缓存的深度信息,用来剔除被遮挡的像素

 

几何体的生成与提交

LOD选择与渐进式生成

根据距离的远近,决定三角形提交的数量,2种方式,一种是离散的LOD,一种是连续的LOD

 

向API投送几何体

核心是顶点,三角形,多边形只是顶点的提交形式而已。

顶点的数据分为3类:

1.位置

2.光照和雾化

3.纹理映射坐标

 

背面剔除与裁剪

利用三角形的法向量与摄像机的法向量可以判断背面三角形,但是当今图形硬件上,通常利用屏幕中三角形顶点的顺序进行背面剔除

 

十一,可见性检测

 

可见面检测(visible surface determination VSD)可以再不同层次上进行,比如像素,三角形,物体等。像素的vsd使用深度缓存,三角形级vsd由背面剔除和裁剪完成。

 

这里主要讨论物体级别的可见性检测,目的在于流入下一阶段的物体尽可能的少

 

包围体检测

使用长方体或者球体对物体进行包围,如果包围体不可见,那么物体也不可见

 

1基于视锥的检测

基于视锥探测包围盒是相当容易的,基本思想是用包围盒的八个顶点对6个裁剪面进行测试。如果所有顶点都在一个或多个裁剪面的“外部”,则包围盒是不可见的,可以抛弃。

 

2遮断检测

一种技术是“渲染”这个包围盒,在z-buffer探测。我们光栅化包围盒的面,但并不实际渲染它,而只是探测是否有像素可见。这种技术称作z-探测。

 

空间分割技术

包围体技术是一种中级算法,空间分割技术是一种高级的算法

 

1.网格系统

使用网格均匀地分割空间,然后渲染可见网格,缺点是不够灵活,划分总是均匀的

2.四叉树和八叉树

有选择地进行细分,达到自适应的划分空间的效果

3.bsp树

每个节点都有2个子节点,子节点由分割平面隔开。在四叉树和八叉树中,分割平面是轴对齐的,在bsp中这不是必须的,可以使用任意方向的平面。当然也可以使用轴对齐的平面。bsp要比相应的八叉树存储更多的数据,比如划分平面。

 

遮断剔除

使用标准的树遍历,我们只能剔除那些视锥意外的节点,无法做出任何基于遮断的剔除

 

pvs(potentially  visible set)

预先计算节点内从任一点可见的节点和物体列表

 

portal

通过将场景分为portal(门廊)和房间,对视点所在的房间,通过portal进行遍历,从而找出可见集。

 

终于写完了,累死了。。。

 

 

 

 

 

原创粉丝点击