3D数学是什么?
3D数学是一门和计算几何相关的学科,计算几何研究使用数值方法解决几何问题。简而言之,通过数学的手段去理解与模拟3D几何世界,解决其中的各种问题,就是3D数学。其具体的应用可以在计算机模拟3D世界的领域,如图形学、游戏、仿真、机器人技术、VR以及动画等等,其中的数学知识可以拓展更宽阔,对于人工智能中3D领域的CV也有所涉及。
数值方法解决几何问题,原本属于数值计算的问题,现在随着计算机的发展,运算能力提升,大部分复杂的计算都有计算机来替代人手工计算。不过由于计算机的数学计算实现与人计算方法的一些差异,因此在计算机计算中一部分运算复杂度较高需要通过等价替代为开销更低的方法。这些方法在数值计算方法中提出相当多,在计算机仿真中也十分普遍,不过在本书中此类知识涉及不多,只有在实践部分C++代码中略有体现,总结中可能会适当加入。
游戏3D坐标系
坐标系由坐标轴与坐标原点组成,原点定义坐标系的位置,轴定义了坐标系的方向。
1、世界坐标系:被广泛称为全局坐标系或者宇宙坐标系;
2、物体坐标系:被称为模型坐标系,或者“身体坐标系”
3、摄像机坐标系:与观察者密切相关,摄像机坐标系与屏幕坐标系相似,区别是,摄像机坐标系在3D空间中,而屏幕坐标系在2D平面里。
4、摄像机坐标系:被认为是一种特殊的“物体坐标系”,只不过是该物体坐标系定义在摄像机的可视区域。在“摄像机坐标系”中,摄像机在原点,X轴向右,Z轴向前(朝向屏幕内,摄像机的镜头朝向),Y轴向上(是摄像机本身的上方,不是世界坐标系的上方)。“摄像机坐标系”采用的是【左手坐标系】标定法
左手坐标系与右手坐标系没有好坏之分,不同的研究领域和不同的背景下,选择不同的坐标系;传统计算机图形学采用“左手坐标系”,线性代数则倾向于使用右手坐标系
惯性坐标系
是为了简化“世界坐标系”到物体坐标系的转换,即在世界坐标系到物体坐标系的“半过渡”坐标系。惯性坐标系与物体坐标系原点重合,但是,惯性坐标系的坐标轴与“世界坐标系”的轴平行。
引入惯性坐标系的原因,从“物体坐标系”到“惯性坐标系”的转换只需要“旋转操作”,从惯性坐标系到世界坐标系的转换只需要“平移”操作。
嵌套坐标系
方便在世界坐标系中计算物体之间的关系,如物体坐标系模型视为一个质点,在世界坐标系中只需要考虑位置与方向即可,节省资源。
物体坐标系中的模型在世界坐标系中运动,可以将世界坐标系看做“父”空间,而将物体坐标系看做“子”空间。后者可以将物体打散成子块,独立的定义控制,这样可以形成嵌套的、按照层次结构组织的对象序列,这样每个动作很容易独立计算,并通过线性变换工具(矩阵,向量组合)弃疗。
游戏世界坐标变换
我们每个人都处在地球某个点上,游戏世界和我们显示一样,同样有一个以(0,0,0)为原点的游戏世界坐标。
坐标变换:指导坐标系A中的空间一点P,怎样在另一个坐标系中描述改点,即坐标变换,把“物体坐标系”与“世界坐标系”进行相互转换,不同的应用场景下。
以“物体坐标系”为参考坐标系,如果达到与操作“物体坐标系”,实现相同的效果,则“世界坐标系”的操作相对于“物体坐标系”都是相反的,即如果you 向右转,或者,you不动,世界坐标系向左转,效果一样。
游戏向量世界
向量最基本的定义就是一个方向。或者更正式的说,向量有一个方向(Direction)和大小(Magnitude,也叫做强度或长度);向量可以在任意维度(Dimension)上,但是我们通常只使用2至4维,如果一个向量有2个维度,它表示一个平面的方向(想象一下2D的图像),当它有3个维度的时候它可以表达一个3D世界的方向。
下面你会看到3个向量,每个向量在2D图像中都用一个箭头(x, y)表示,我们在2D图片中展示这些向量,因为这样子会更直观一点。你可以把这些2D向量当做z坐标为0的3D向量,由于向量表示的是方向,起始于何处并不会改变它的值。下图我们可以看到向量v¯v¯和w¯w¯是相等的,尽管他们的起始点不同:
由于向量是一个方向,所以有些时候会很难形象地将它们用位置(Position)表示出来。为了让其更为直观,我们通常设定这个方向的原点为(0, 0, 0),然后指向一个方向,对应一个点,使其变为位置向量(Position Vector)(你也可以把起点设置为其他的点,然后说:这个向量从这个点起始指向另一个点),比如说位置向量(3, 5)在图像中的起点会是(0, 0),并会指向(3, 5),我们可以使用向量在2D或3D空间中表示方向与位置。
向量运算与几何意义
向量是2D、3D数学研究的标准工具,在3D游戏中向量是基础。因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要。在本篇和大家一起回顾和学习一下Unity3D中那些常用的3D数学知识。
一、向量概念及基本定义
1、向量的数学定义
向量就是一个数字列表,对于程序员来说一个向量就是一个数组。
向量的维度就是向量包含的“数”的数目,向量可以有任意正数维,标量可以被认为是一维向量。
书写向量时,用方括号将一列数括起来,如[1,2,3] 水平书写的向量叫行向量 垂直书写的向量叫做列向量
2、向量的几何意义
几何意义上说,向量是有大小和方向的有向线段。向量的大小就是向量的长度(模)向量有非负的长度。
向量的方向描述了空间中向量的指向。
向量的形式:向量定义的两大要素——大小和方向,有时候需要引用向量的头和尾,下图所示,箭头是向量的末端,箭尾是向量的开始
向量中的数表达了向量在每个维度上的有向位移,例如2D向量列出的是沿x坐标方向和y坐标方向的位移。
3、向量与点
“点”有位置,但没有实际的大小或厚度,“向量”有大小和方向,但没有位置。所以使用“点”和“向量”的目的完全不同。”点”描述位置,“向量”描述位移。
4、点和向量的关系
任意一点都能用 从原点开始的向量来表达。
5、距离公式
距离公式用来计算两点之间的距离。从上面可以得知两点间的位移向量通过向量减法可以得知,既然得到了两点间的位移向量,那么求出位移向量的模,就能计算出两点间的位移。
6、向量点乘
两个向量相乘的结果是一个标量。此标量是等于两个向量长度相乘结果再乘上向量之间的夹角的余弦。当两个向量都为单位向量时,余弦的定义就表示为第一个向量在第二个向量上面的投影长度(或反之亦然 ,参数的顺序并不重要) 。
7、向量叉乘
叉乘只能用来计算3D向量,它需要输入两个向量返回结果是另一个向量,得到的结果垂直于输入的两个向量。"左手坐标系"可以用来表示输入和输出的向量的方向,如果第一个参数匹配手的拇指和食指匹配第二个参数,结果将是中指的方向。如果参数的顺序是相反的结果向量将指向正好相反的方向,但将有相同长度。向量叉乘的结果的大小等于输入向量的乘积,然后通过它们之间的角度的正弦值乘以该值的大小。
在Unity3D里面,两个向量的点乘所得到的是两个向量的余弦值,也就是-1 到1之间,0表示垂直,-1表示相反,1表示相同方向。 两个向量的叉乘所得到的是两个向量所组成的面的垂直向量,分两个方向。 简单的说,点乘判断角度,叉乘判断方向,形象的说当一个敌人在你身后的时候,叉乘可以判断你是往左转还是往右转更好的转向敌人,点乘得到你当前的面朝向的方向和你到敌人的方向的所成的角度大小。
游戏矩阵世界
矩阵很多同学没有接触过,所以感觉很难,很复杂,其实只要学过矩阵的同学都知道,矩阵运算并不难。今天我们给大家讲讲游戏开发中的矩阵的运算。
矩阵是什么?
矩阵是描述线性变换的一种数学工具,线性变换指的是使用一次函数从一个空间变换到另外一个空间。
例如在空间A中的一个2维向量(xa, ya)变换到空间B,使用一次线性函数变换后得(xb, yb)。
xb = A*xa + B*ya + C; yb = M*xa + N*ya + D;
上述变换中,xb 是由xa, ya 经过线性运算而得到得。如果xb = A*xa^2 + B*ya + C,这样就不是线性变换了。
矩阵是3D数学的基础,主要用来描述两个坐标系统之间的关系,通过定义一种运算,将一个坐标系统的向量转换到另一个坐标系中。
1、向量是“标量”的数组,矩阵是“向量”的数组。
2、矩阵不一定是方阵(行列相等),方阵一定是矩阵。
3、矩阵没有0行0列之说,所有都第一行,第一列,开始。
矩阵的一般表达式,如3X3的矩阵:
上述的表达式用的是方括号包围,也可以用圆括号和花括号来表示,都是等价的。
前面讲的矢量其实就是一个数组,而矩阵也是一个数组。
矢量可以看成是nX1的列矩阵 或 1Xn的行矩阵。 这样就可以让矢量像一个矩阵一样一起参与矩阵运算,这在空间变换中非常有用。
例如,矢量 v= (1, 2, 3) 可以写成列矩阵:
或行矩阵:
矩阵的几何解释
一般来说,方阵能描述任意的"线性变换“,线性变换可能拉伸坐标系,但是不会弯曲坐标系,最常见的:旋转,缩放,投影,镜像,仿射。
向量与矩阵之间的变换
1、向量在几何解释上,可以由一系列与轴平行的位移,且作为向量的各个分量
即为向量的“扩展”形式,将向量表示为基向量的线性组合
v = xp + yq + zr;
向量p,q,r 是基向量,且称为:向量v可以表示成向量p,q,r的线性变换。
2、将矩阵解释为基向量集合
把矩阵的行解释为坐标系的基向量,乘以该矩阵就相当于执行了一次坐标变换。如, aM = b,则,可以说 矩阵M将a 转换到b。
3、矩阵表达“坐标变换”
当我们再观察矩阵时,我们是在观察“变换”,观察新的坐标系。
矩阵的9个元素与不同的3D转换(旋转,平移,等)有着对应关系
4、矩阵的每一行都能解释为转换后的基向量
因为坐标系对应的三个行分量(基向量)与矩阵想成,都分别得到相应行分量对应的矩阵行向量,即基向量。
则给出一个期望的变换(旋转,平移,缩放等),可以构造一个矩阵代表此变换。所要处理的是,计算基向量的变换,然后将变换后的基向量填入矩阵。
矩阵和线性变换
多模型进行线性变换,既可以针对模型做变换,也可以针对坐标系做变换,两种方便方法性效果上是等价的,但是在某些情况下,模型可能含有大量的顶点和三角形,计算量太大,往往直接对坐标系进行线性变换更合适。
针对模型变换一个量等价于将坐标系变换一个相反的量。
1、即变换物体相当于一相反的量变换描述物体所在的坐标系。
2、当有多个变幻时,需要以相反的顺序变换相反的量。
各种模型的变换矩阵,一般指的是直接对“模型”进行变换的“变换矩阵”。
1、一般来说,投影,意味着降维操作。
2、可以将多个变换矩阵按照次序组合一个矩阵,新矩阵代表依次执行元变换的累加效果,非常适合渲染处理。
3、把从a 到 b 的F映射记做 F(a) = b。 F即为映射或者函数, 在3D数学中,则表示为矩阵表示。
4、仿射变换,即 线性变换 + 平移变换。
3D中的方位与角位移
方位主要描述物体的朝向。“向量”只有方向而没有方位,区别是,一个向量指向特定方面时,可以让向量自传。
确定一个方位,需要3个参数:空间位置,空间方向,角位移。
直线方程
2D直线:
隐式定义:ax +by = d
向量隐士定义: p·n = d, n为垂直直线方向的单位向量,d给出了原点到直线的有符号距离。
斜截式: y = mx +b , 竖 直线x = b; 水平线,m = 0(斜率), y = b;
平面方程:
3D空间隐式定义:
ax + by + cz = d
p · n = d :其中n = 【a, b,c】,向量n成为平面的法向量。垂直于平面,且指向平面的正面,且n为单位向量,则计算方便,其中d是平面相的任意向量与法相单位向量的乘积d(无几何意义)
空间三点定义平面
形成相邻的两条有向边:e1= p3 -p2,e3 = p2 - p1, 即边,P1->P2, P2->P3
则平面法相:利用向量叉积获得法相n。然后确定d,可通过一个点p 与n点乘后的标量d。
点到平面的距离
不在平面的点q到一个已知平面s的距离a公式:
a = q·n - d;
其中,n是S的单位法线,且d是S平面方程的d值,且a是点到平面s的有符号距离。
三角形性质
三角形:需要用三个向量点来定义 vector3 v1, vector3 v2,vector3 v3,三角形网格中因为共用顶点关系可以通过邻接信息去掉冗余的顶点,或者可以通过索引缓存来去掉冗余的顶点。
三角形重要的定理有勾股定理,正弦定理,余弦定理,重要的定义有重心,内心,外心。
3D中的三角形面积为: A = | e1 x e2 | / 2, e1和e2向量的夹角和方向没有限制,任取三角形的两条边向量即可。
2D中的三角形面积, 也可以用坐标系下3边下的有符号面积相加得到,边是由左往右的面积为正数,反之面积为负:
y+
| v2
| /\
| / \
| v1 —— v3
---------------------------------x+
T = (y2+y1)(x2-x1)/ 2 + (y3+y2)(x3-x2)/ 2 + (y1+y3)(x1-x3) / 2 = ( y1(x2 - x3) + y2(x3 - x1) + y3(x1 - x2) ) / 2 // 直接乘出来,合并多项式了下 = ( (y1 - y3)(x2 - x3) + (y2 - y3)(x3 - x1) ) / 2 // 平移三角形不会改变面积,所有y值都减去了y3
记得v1,v2,v3是顺时针绕序的。
三角形中引入了重心坐标空间的概念,这样在三角形平面上移动就比较好表示了,否则用3D的点或者向量表示会比较复杂。
其实这也是一种分层模块化和转换的思想。
三角形重心坐标是三角形三个顶点向量在三角形表面上贡献的比例。
(b1,b2,b3) <=>b1v1 + b2v2 + b3v3
所以三角形三个顶点的重心分别为:(1,0,0), (0,1,0), (0,0,1)
重心坐标(b1,b2,b3)其实刚好是三角形内部点p划分的三个小三角形的面积和总面积的比:
y+
| v2
| / \
e3->T3 / p \e1->T1
| v1 —— v3
e2->T2
---------------------------------x+
b1 = T1/ T
b2 = T2/T
b3 = T3/T
2D中T1,T2,T3,T的面积可以直接求取从而得到三角形的重心坐标。
3D中可以用3D中求取面积的向量叉乘法,也可以通过将三角形投影到面积最大的2D平面上( 通过法向量的分量可以看出,分量越大的那么三角形投影到该分量上越小,所以投影到垂直于大分量的平面上即得最大投影),从而可以用2D的方法来进行三角形重心坐标的求取。在射线和三角形检查中,先求得射线和三角形平面的交点,然后计算交点的三角形重心坐标,以决定交点是否在三角形内部)。
3D中可以用3D中求取面积的向量叉乘法,向量叉乘会有一个小问题,就是叉乘结果总是正数,当对于三角形重心坐标在三角形外部的,那么不能够正确的表达出来,这个时候将叉乘结果点乘法向量,就会得到有符号的结果( 因为如果重心坐标在三角形外部,那么与在三角形内部的的两个向量围成的三角形绕序会相反 )。
1、三角形重心坐标为(1/3, 1/3,1/3),计算物理重心时候需要用到。
2、三角形内心重心坐标为(L1/p, L2/p, L3/p),L是三角形的边长,p是三角形的周长,当需要计算三角形内接圆时候用到。
3、三角形的外心重心坐标比较复杂些下面给出代码,当需要计算三角形外接圆时候才需要使用到。
//returnRadius是需要返回外接圆半径,returnG是返回的重心坐标 void caculateOutHeart( Vector3 &v1, Vector3 &v2, Vector3 &v3,float &returnRadius, Vector3 &returnG ) { Vector3 e1 = v3 - v2; Vector3 e2 = v1 - v3; Vector3 e3 = v2 - v1; float d1 = -(e2.x * e3.x + e2.y*e3.y + e2.z*e3.z); float d2 = -(e3.x*e1.x + e3.y*e1.y + e3.z*e1.z); float d3 = -(e1.x*e2.x + e1.y*e2.y + e1.z*e3.z); float c1 = d2*d3; float c2 = d1*d3; float c3 = d1*d2; float c = c1 + c2 + c3; float cc = 2*c; float g1 = ( c2 + c3 ) / cc; float g2 = ( c1 + c3 ) / cc; float g3 = (c1 + c2 ) / cc; returnG = Vector3( g1, g2, g3 ); float radius = 0.5 * sqrt( (d1+d2) * (d2+d3) * (d3+d1) / c ); returnRadius = radius; }
3D几何检测
几何检测是指在计算机视觉中,通过对图像或点云进行分析和处理,来检测和识别其中的几何形状和结构的过程,常见的几何检测任务包括物体识别、边缘检测、角点检测、直线检测等。
在几何检测中,可以使用各种算法和技术来实现不同的任务。例如,边缘检测可以使用Canny边缘检测算法、Sobel算子等方法来检测图像中的边缘信息。角点检测可以使用Harris角点检测算法、Shi-Tomasi角点检测算法等方法来检测图像中的角点位置。
几何检测中比较重要的是射线和平面的相交检测,射线和AABB的相交性检测,射线和三角形的相交性检测,射线和球的相交性检测;球和平面的相交性检测, AABB和平面的相交检测,两个AABB间静态和动态的检测。
还有更多的检测,具体的算法见AABB类。还有更多的检测,如果需要还要进行分析检测。
因为算法比较多和繁琐,下面总结下自己理解这些算法过程中和研究这些算法中得到的思想方法。
1、抽象建模为向量的思维
对研究的对象向量化,平面,射线,AABB,球都用向量表示,研究的空间关系,距离为向量的模,夹角是向量的cos thta,法向量为sin theta。
2、多运动简化为单一运动,多轴上的变换简化为单一轴的变换最后合并简化问题
如果是两个对象是动态类型的检测,那么将运动都假设放置到一个物体上,一个假设为静止的。向量的加法和减法刚好可以做到。
射线,三角形间的检测,需要考虑不同情形,投影到面上,AABB间检测需分开每个轴考虑,最后对时间轴求交集。
3、利用向量构建关系,引入辅助中间量,分解合并转化未知量,代入方程解决问题
利用向量的点乘,叉乘,和三角关系勾股正弦余弦,三角形相似,三角函数构建关系。根据几何意义引入中间辅助线辅助量,分解合并式子得到未知量。如果不行那么强解三角形也是可以的。得到未知量,将未知量代入物体向量方程得到结果。
有些问题,可以提前结束,比如计算比例,那么双方都不用除2是可以的,有些可以比较除法,避免平方根运算得到结果。
4、分类讨论和注意精度
对于关系式的结果,注意分类讨论,射线原点在平面正面反面;射线方向是否和需要检查的对象之间同向或者反向;射线的长度不够长;几何体内部或者几何体相交了;注意前提条件和运算的整个过程;在平面的正面反面,共线平行,共面的几何关系等情况。
还有因为浮点数精度问题,很多计算结果在合理的误差范围内,都是可以接受的。
具体的几何检测方面用到的众多几何图元和几何图元间的相交检测关系,见 AABB几何检测类的代码。
游戏三角网格
网格就是由很多个三角形或者多边形构成的,在图形学和建模中广泛应用,用来模拟复杂物体的表面。
三角形网格:
四边形网格:
当然,任意多边形网格都能转换成三角网格,我们讨论的大多数概念对多边形和三角网格都适用。三角网格以其简单性而吸引人,相对于一般多边形网格,许多操作对三角网格更容易。当然,多边形在某些情况下具有优势,在差别很显著的时候我们会作出解释。
对于某些应用程序,这种表示方法已经足够,然而,术语“网格”隐含的相邻三角形的联通性却在种简单表示中有任何体现。实际应用中出现的三角网格,每个二角形都和其他三角形共享边,于是三角网格需要存储三类信息:
1、顶点:每个三角形都有三个顶点。各顶点都有可能和其他三角形共享。
2、边:连接两个顶点的边。每个三角形有三条边。
3、面:每个三角形对应一个面。我们可以用顶点或边列表表示面。
游戏渲染管线流程
实践中,我们也许会为了性能的优化而并行或乱序执行一些任务,比如,考虑到不同的渲染API,我们可能首先变换和照明所有顶点,然后才进一步的处理(进行裁剪和剔除),或者会并行处理二者,也可能在背面剔除之后再进行光照会得到更高效率,游戏里的一个个物件都会经历下图的流程操作才能显示到设备屏幕上。
这个流程就是常说的游戏渲染管线流程。
还有一个我们将不详细讨论的要点,即工作负担如何在CPU与渲染硬件间分配,正确地组织渲染任务,以求得最大的并行效果对高效渲染是至关重要的。
考虑上述简化,就得到了图形管道中数据流的概况,如下所示:
1、建立场景:开始渲染之前,需要预先设定对整个场景有效的一些选项。比如,要建立摄像机位置,或者更具体些,要选择进行渲染的出发点---视点,渲染的输出---视图。还需要设定光照与雾化选项,同时准备z缓冲。
2、可见性检测:选好了摄像机,就必须检测场景中哪些物体是可见的。可见性检测对实时渲染极为重要,因为我们不愿意浪费时间去渲染那些根本看不到的东西。
3、设置物体级的渲染状态:一旦发现某物体潜在可见,就到了把它实际绘制出来的时候。每个物体的渲染设置可能是不同的,在渲染该物体的任何片元之前,首先要设置上述选项,最常见的此类选项是纹理映射。
4、几何体的生成与提交:接着实际向API提交几何体,通常提交的数据是种种形式的三角形,或是独立的三角形,或是索引三角网格与三角带。此阶段,我们可能会应用LOD,或者渐进式生成几何体。
5、变换与光照:一旦渲染API得到了三角形数据,由模型空间向摄像机空间的顶点坐标转换与顶点光照计算即开始。
6、背面剔除与裁剪:然后,那些背对摄像机的三角形被去除("背面剔除");三角形在视椎外的部分也被去除,称作裁剪---这可能导致产生多于三个边的多边形。
7、投影到屏幕空间:在3D裁剪空间中经裁剪产生的多边形,被投影到输出窗口的2D屏幕空间里。
8、光栅化:当把裁剪后的多边形转换到屏幕空间后,就到了光栅化阶段。光栅化指计算应绘制三角形上的哪些像素的过程,并为接下来的像素着色阶段提供合理的插值参数(如光照和纹理映射坐标)。
9、像素着色:最后,在管道的最后阶段计算三角形的色彩,此过程称作"着色"。接着把这些颜色写至屏幕,这是可能需要alpha混合与z缓冲。
游戏里的一个个物件在渲染流程里最总效果:
光照和雾化
在Unity项目中,灯光和摄像机是非常重要的游戏组件。下面就和大家介绍下Unity3D中的Light光源,帮助大家去掌握它。
Unity中提供了四种光源:
Directional light: 方向光,类似太阳的日照效果。
Point light: 点光源,类似蜡烛。
Spotlight: 聚光灯,类似手电筒。
Area Light:区域光,无法用作实时光照,一般用于光照贴图烘培。
标准光照模型:
标准光照方程(颜色向量): Clit = Cspec + Cdiff + Camb
其中:
1、Clit是打开光照下计算颜色值的结果。计算机图形学中的光照是“关闭光源”下的纹理颜色值的计算。一般计算结果比原来纹理计算值(关闭光源)暗
2、Cspec 是镜面反射下的颜色矢量
3、Cdiff是散射光下的颜色矢量
4、Camb是环境光下的颜色矢量
镜面反射分量:是模型有光泽
物体的外观影响因素:
1、物体表面材质属性
2、表面的方位和朝向
3、照射来的各个光源性质
4、观察者的位置
着色方式
如果对实时渲染(渲染速度)没有要求,可以逐像素来计算光照和雾化处理。但是,这样模型的计算量很大。
一般实际中采用以下方式处理:
1、flat着色,即以多边形为单位进行着色,整个三角形只计算一次光照,光照的位置以三角形中心,且三角形法向量为表面法向量。
2、Gourand着色, 即顶点为单位进行着色,可以保证模型表面的光滑性效果。
渲染缓存技术
缓存指示一个简单的存有像素数据的矩形内存块,最终要的是“帧缓存”和“深度缓存”
帧缓存
一般在“显卡”内存中,即显存。一般显卡都采用双缓存技术,即一个缓存放当前显示的图像,另一个,则离线换攒正在渲染的图像。
深度缓存,z-buffer,或者成为Z缓存
深度缓存,则存储像素的深度信息。一般反应物体到摄像机的距离,如果在渲染之前,如果有新的模型像素比深度缓存中的值比较,如果比之前的更近,则“更新”深度缓存中的值,否则不处理。
一般没有z-buffer的双缓存。
物体纹理映射
纹理示一个贴在模型表面的位图。一般由不同的映射方式,如“平面映射”“球形映射”、“柱形映射”、“立方体映射”
无论何种映射方式,每个网格的顶点都要设置一个纹理映射坐标,就是位图的2D笛卡尔坐标,通常称为u,v坐标,取值一般归格化为[0-1]之间的值。
因为每个三角形可以独立的映射,则纹理的不同部分可以任意映射到物体的不同的部分,即“纹理位图”不一定要是非常连续的图案。
三角形的三个定点都有纹理的映射坐标(u,v),则三角形面中的点可以使用“插值计算”的方式来求取其纹理坐标,然后读取纹理的值。
渲染光栅化
在裁剪操作后,就可以投影到输出的屏幕坐标中。每个像素保证只处理一次,则一个像素基本上需要经过一下过程:
1、着色,为像素计算颜色过程,即光照,然后雾化, 输出RGB + alpha(混合)
2、测试,需要通过3种测试:
(1)检测在渲染窗口外的像素
(2)深度测试检测,去除被遮挡的像素
(3)alpha测试,去除“过分透明”的像素,即不需要写入深度缓存
3、写入,如果像素通过了深度测试,以及alpha测试,则更新“帧缓存”和“深度缓存”。