引擎一些基础知识的理解

与项目有关的

1.三角函数和幂指数的优化主要是创建一个表,每一次都是一个查表的过程,可能会有精度的问题。

2.进入游戏的时候就会把网络模块启动,并且是和主线程并行的

基础的知识点:

3.可编程管线的流程:从顶点着色器到片元着色器。顶点着色器的输入信息来自CPU,处理的单位是顶点,主要完成的是坐标变换和逐顶点光照。 顶点着色器是从模型空间到裁剪空间的的变换;将输出的信息传递给片元着色器,片元着色器主要进行渲染等,最后逐片元操作,将每个像素会知道屏幕上,经过了裁剪空间到屏幕空间的映射。一个三角形片元主要是经过了:

三角形设置:计算光栅化一个三角形网格所需要的信息

三角形遍历:得到哪些像素被三角形片元覆盖

片元着色器:完成一些渲染技术,例如纹理采样

逐片元操作:决定每个片元的可见性,做了很多测试工作,深度测试,模版测试等;将这个片元的颜色和存储在颜色缓冲区的颜色进行混合。

4.模型空间到裁剪空间是怎样做的?

裁剪的主要目的就是将观察范围外的图元裁切掉,之所以要在裁剪空间进行裁剪因为不同的视锥体(摄像机可以看见的范围,由六个平面组成,每个平面为裁剪平面)会有不同的裁剪处理过程,特别是透视投影,因此需要通过一个投影矩阵,把顶点转换到裁剪空间。投影矩阵不是做了真正的投影,真正的投影是在齐次除法过程中,投影矩阵做的是准备,经过投影后,将顶点的 w分量作为一个范围值,x y z坐标在范围内说明在裁剪空间内。

投影是一个降维的过程,真正的投影在屏幕映射时完成,经过齐次除法得到二维坐标。

在裁剪空间之前,虽然我们使用了齐次坐标来表示点和矢量,但它们的第四个分量都是固定的:点的w分量是1,方向矢量的w分量是0。经过投影矩阵的变换后,我们就会赋予齐次坐标的第4个坐标更加丰富的含义。

5.两个ARGB颜色的相加是要将每个一通道的对应相加,该通道大于FF时就为FF

6.法线贴图:

每个fragment使用了自己的法线,我们就可以让光照相信一个表面由很多微小的(垂直于法线向量的)平面所组成,物体表面的细节将会得到极大提升。这种每个fragment使用各自的法线,替代一个面上所有fragment使用同一个法线的技术叫做法线贴图(normal mapping)或凹凸贴图(bump mapping)。

凹凸映射是最好的例子。利用一张纹理来修改模型表面的法线。法线的范围是[-1,1],而像素的范围是[0,1],因此需要做一个映射:pixel = (normal + 1)/2。将法线向量变换为像这样的RGB颜色元素,我们就能把根据表面的形状的fragment的法线保存在2D纹理中,一般来说是五颜六色的,因为所有的法线所在的坐标空间是同一个坐标空间,即模型空间,而且每个点存储的法线方向是各异的,如(0,1,0),映射为RGB(0.5,1,0.5)浅绿色。

很多时候我们会用切线空间来存储法线,这种为切线空间的法线纹理。每个顶点都有一个属于自己的切线空间,Z轴就是法线方向,x轴是顶点的切线方向, y轴是由 X*Z叉积得到的。切线空间下的法线纹理都是蓝色的,每个法线所在的空间不一样,这种法线纹理就是存储在每个点在的格子的切线空间中的法线扰动方向,新的法线方向为(0,0,1),经过映射后存储的纹理对应为(0.5,0.5,1)浅蓝色。

无论是哪种坐标系中,最后光照计算才是最终的目的。如果我们选择切线空间,从法线纹理中得到的法线方向从切线空间转换到世界空间中。使用模型空间时,法线纹理记录的是绝对法线信息,仅用于创建时的那个模型;而切线空间下的法线纹理记录的是相对的法线信息,即使映射到不同的网格上也是正确的信息。如果用一个纹理的UV坐标来进动画,实现一个凹凸移动的效果,模型空间下的法线纹理会得到完全错误的答案。切线纹理便于重用,而且便于压缩,只需要存储XY即可,Z方向可以推导。

7.骨骼蒙皮动画

优点:骨骼动画与传统的顶点动画相比,会节省很多内存空间,代替了每一帧都存储大量的顶点信息。传统的关键帧动画上,会对两个关键帧之间进行插值,但并没有关节的旋转,缺乏真实性。

过程:当移动骨头上游的一根骨头,下由的也会跟着移动。根关节是模型空间的终端关节,任何其他关节都会连接到跟关节,它的操作也会影响到模型中的每个顶点。每个父关节都会影响其每个子关节。骨骼动画的关键帧再现的是一个瞬时状态。骨骼动画的关键帧或这叫做骨骼帧包含了旋转和平移的相关信息。插值一般用球面线性插值,而不用线性插值,创建出一个较为平滑的效果。

数据基础:最归根结底就是矩阵的变换。相对矩阵是旋转和平移矩阵结合的结果,绝对矩阵是相对矩阵乘以父关节的矩阵的结果。

骨骼动画的基本原理可概括为:在骨骼控制下,通过顶点混合动态计算蒙皮网格的顶点,而骨骼的运动相对于其父骨骼,并由动画关键帧数据驱动。

一个骨骼动画通常包括骨骼层次结构数据,网格(Mesh)数据网格蒙皮数据(skin info)骨骼的动画(关键帧)数据

蒙皮是指将Mesh中的顶点附着(绑定)在骨骼之上,而且每个顶点可以被多个骨骼所控制这样在关节处的顶点由于同时受到父子骨骼的拉扯而改变位置就消除了裂缝在骨骼动画中,不是把Mesh直接放到世界坐标系中,Mesh只是作为Skin使用的,是依附于骨骼的,真正决定模型在世界坐标系中的位置和朝向的是骨骼对于骨骼动画,我们设置模型的位置和朝向,实际是在设置根骨骼的位置和朝向,然后根据骨骼层次结构中父子骨骼之间的变换关系计算出各个骨骼的位置和朝向,然后根据骨骼对Mesh中顶点的绑定计算出顶点在世界坐标系中的坐标,从而对顶点进行渲染。要记住,在骨骼动画中,骨骼才是模型主体,Mesh不过是一层皮,一件衣服。骨骼可理解为一个坐标空间,关节可理解为骨骼坐标空间的原点关节的位置由它在父骨骼坐标空间中的位置描述。关节既决定了骨骼空间的位置,又是骨骼空间的旋转和缩放中心用一个4X4矩阵就可以表达一个骨骼,因为4X4矩阵中含有的平移分量决定了关节的位置,旋转和缩放分量决定了骨骼空间的旋转和缩放。骨骼就是坐标空间,骨骼层次就是嵌套的坐标空间关节只是描述骨骼的位置即骨骼自己的坐标空间原点在其父空间中的位置,绕关节旋转是指骨骼坐标空间(包括所有子空间)自身的旋转。建立了骨骼层次结构,那么每一块骨骼的位置都依赖于其父骨骼的位置,而根骨骼没有父,他的位置就是整个骨骼体系在世界坐标系中的位置。可以认为root的父就是世界坐标系。但是初始位置时,根骨骼一般不是在世界原点的。

最核心的部分,更新骨骼由于动画的作用,某个骨骼的变换(TransformMatrix)变了,这时就要根据新的变换来计算,所以这个过程一般称作UpdateBoneMatrix因为骨骼的变换都是相对父的,要变换顶点必须使用世界变换矩阵,所以这个过程是根据更新了的某些骨骼的骨骼变换矩阵(TransformMatrix)计算出所有骨骼的世界变换矩阵(也即CombinedMatrix)。需要首先将模型顶点从模型空间变换到某块骨骼自身的骨骼空间,然后才能利用骨骼的世界变换计算顶点的世界坐标。

顶点类的定义的代码片段:

#defineMAX_BONE_PER_VERTEX 4       //用来设置可同时影响该顶点的最大骨骼数

classVertex

{

floatm_x, m_y, m_z; //local pos in mesh space

floatm_wX, m_wY, m_wZ;//blended vertex pos, in world space

//skininfo

intm_boneNum;        //影响该顶点的骨骼数目

Bone*m_bones[MAX_BONE_PER_VERTEX];  //指向这些骨骼的指针

floatm_boneWeights[MAX_BONE_PER_VERTEX];  //这些骨骼作用于该点的权重

};

由于骨骼的TransformMatrix(作用是将顶点从骨骼空间变换到上层空间)是基于其父骨骼空间的只有根骨骼的Transform是基于世界空间的,所以要通过自下而上一层层Transform 变换。在动画中模型中顶点的位置是根据骨骼位置动态计算的,也就是说顶点跟着骨骼动,但首先必须确定顶点和骨骼之间的相对位置(即顶点在该骨骼坐标系中的位置),一个骨骼可能对应很多顶点,如果要保存这个相对位置每个顶点对于每块受控制的骨骼都要保存,这样就要保存太多的矩阵了。。。所以只保存mesh空间到骨骼空间的变换(即OffsetMatrix),然后通过这个变换计算每个顶点在该骨骼空间中的坐标,所以OffsetMatrix也反应了mesh和每块骨骼的相对位置,只是这个位置是间接的通过和世界坐标空间的关系表达的,在初始位置将骨骼按照模型的形状摆好是关键之处

顶点混合(vertexblending)这是骨骼动画的精髓所在,正是这个技术消除了关节处的裂缝。顶点混合后得到了顶点新的世界坐标,对所有的顶点执行vertexblending后,从Mesh的角度看,Mesh deform(变形)了,变成动画需要的形状了。对于多块骨骼,对每块骨骼执行这个过程并将结果根据权重混合(即vertex blending)就得到顶点最终的世界坐标

制作动画时,一般会把整个骨架层次画出来,调整成一个初始姿势,又叫绑定姿势,并由这个姿势来制作动画关键帧;每帧中记录了各关节相对于绑定姿势的旋转,平移,缩放,一般只有根关节才有平移跟缩放,其他关节只有旋转。

一个动画数据文件头保存有动画名字、关节数、关键帧数以及动画的持续时间;接着分别为每个关节保存关键帧数据,其中平移和旋转关键帧都分开存。

8.shadow map阴影问题:Shadow Map 阴影是把摄像机放在和光源同样的位置,阴影区就是摄像机看不到的地方。在前向渲染路径中,如果场景中最重要的平行光开启了阴影,Unity就会为该光源生成阴影映射纹理,本质上就是一张深度图,记录了从该光源的位置出发,能看到的场景中距离它最近的表面位置(深度信息)。Unity的ShadowCaster 会生成一张额外的Pass,这个Pass的渲染目标不是帧缓存,而是阴影映射纹理,将深度信息输入到阴影映射纹理中,当光源开启了阴影效果后,会先找到这个Pass,用它来更新光源的阴影映射纹理。传统的阴影映射纹理实现会使用 x y分量对阴影映射纹理进行采样,得到深度信息,当深度值小于该顶点的深度值z时,说明该点位于阴影中。Unity有所不同,采用了屏幕空间的阴影映射技术,是延迟渲染中产生的结果。

(1)如果一个物体接收来自其他物体的阴影,就必须在Shader中对阴影进行采样,把采样结果和光照结果进行相乘来看阴影效果。

(2)如果一个物体像其他物体投射阴影,就必须把物体加入到光源的阴影映射纹理中,让其他物体在对阴影进行采样时可以得到该物体的相关信息。

9.延迟渲染:

当光源较多了,前向渲染的性能会急速下降,延迟渲染用来解决这个问题(仅进行一次光照计算)。除了前向渲染中使用的颜色缓冲和深度缓冲外,延迟渲染还会利用额外的缓冲区,为G缓冲区(Geometry)。G缓冲区存储了我们关系的表面的其他信息,例如该表面的法线、位置,用于光照计算的材质属性等。

延迟渲染的实现原理:包含两个Pass,第一个Pass不进行任何光照计算,仅计算哪些片元是可以见的,主要通过深度缓冲技术实现,如果可见,就存入G缓冲区中,我们会把物体的漫反射颜色、高光反射颜色、平滑度、法线、自发光和深度等信息渲染到屏幕空间的G缓冲区中,每个物体这个Pass只执行一次;第二个Pass利用G缓冲区的各个片元信息,进行真正的光照计算。与光源数无关。

延迟渲染的优点:一遍渲染多个光源光照方法中,所有光照运算都在一个着色器中进行。但一个着色器有指令数量的限制,所以这个技术只适用于光源数量较少的情况。在某些游戏中,只需要少量光源,例如室外白天场景,这就是个较好的选择。这个技术的缺点是不能支持光源数量较多的情况。多遍渲染多个光源这种方法物体光照的计算只在当前光源着色器中进行。这会导致非常高的batch数量(调用Draw的次数),最坏的情况会达到光源数量乘以物体数量。某些操作会重复多次,例如顶点的转换。延迟渲染这主要是因为大部分模型在渲染的时候并不需要光照计算,而在渲染场景已经接近完成的时候,才会使用光照信息就好像在渲染一个二维图像一样。在这个阶段所做的改变通常被称为在屏幕空间进行了一些计算。知道这一点以后,我们可以说延迟渲染的光照是发生在屏幕空间。

延迟渲染的缺点:

不支持真正的抗锯齿功能

不能处理半透明物体

对显卡有一定的要求,显卡必须支持MRT,shader mode 3.0及以上,深度渲染纹理以及双面的模板缓冲。

最重要的是,在大多数情况下,移动设备上延迟渲染的性能会比前向渲染的性能要差一些。这是因为每一帧渲染的时候都需要增加一次额外的渲染。如果你的场景中只有一个光源,那么使用延迟渲染可能是不划算的。另外一方面,增加额外的灯光带来的计算消耗也非常低。在最坏的情况下性能的下降也是与光源的数目成正比的,而且与前向渲染相比较,延迟渲染的性能是与场景中的物体数量无关的。

10.PBR 帧缓冲等 像素的各种格式 压缩格式

http://blog.csdn.net/jxw167/article/details/63710248












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值