GPU渲染3D图形的粗略步骤,虽然粗略但也是通用步骤

来源:互联网 发布:袁菱照片疯传网络 编辑:程序博客网 时间:2024/06/06 01:58

1,由于我们导入Unity的模型或者我们再Unity创建的模型,它们自身都有一个属于自己的坐标系,就像人一样,无论你站在什么方位,你总是知道自己的前后左右是什么方向,而这个前后左右就建立在你自身的坐标系,所以Unity里每一个模型并不知道其他模型的坐标系,那么为了方便计算和操作我们就要把他们转换到一个统一的空间坐标系里,前者是物体的模型空间,后者是世界空间,这是第一个空间变换:"模型空间"->"世界空间",然后我们要确定我们在摄像机里具体能看到哪些东西,同样为了方便计算和处理,我们要再一次把物体从世界空间转换到摄像机空间,其实就是以摄像机为坐标系原点建立一个三维空间,经过这一步操作就能知道每一个物体从摄像机的位置来看他在什么方位,这是第二个空间变换:"世界空间"->"摄像机空间".现在虽然知道了物体在相机空间的位置,但是还不能立刻进行渲染,为了方便后面要进行的空间裁剪和,屏幕坐标映射当然也是为了方便计算,我们要把摄像机空间内所有物体的坐标再一次转换到一个坐标范围是(-1,-1,-1)到(1,1,1)的正方体空间区域中,也就是整个空间变换中最难理解的"投影变换",这是第三个空间变换:"摄像机空间"->"投影空间".接下来就是把投影空间里的物体映射到屏幕坐标上去.第四个空间变换(严格来说这不应该叫空间变换):"投影空间"->"窗口空间".以上大概属于空间变换部分的内容,很多书本上的地方叫法和说法都不尽相同,理解大概意思即可.


  2,显卡来处理图形的过程中一般有三个最基本的要素:点,线,面(一般指三角面),而在上一步中我们只是针对模型中单个顶点来一一处理,接下来我们就把经过空间变换剩下来的顶点(为什么说剩下来呢,因为上一步有一点没有提,就是在投影变换的过程中, 会进行一步剔除处理,把一些不在显示区域内的顶点根据一定规则过滤点,这样可以减少接下来的运算量)进行组装,组装成点,线,面.也就是所谓的图元装配,图元装配进行完之后,我们需要进行栅格化:大家都知道我们面前的屏幕是由像素矩阵构成的,而我们处理的模型只是由有限的顶点构成的,经过图元装配后形成的基本图元(点线面),我们要把它和屏幕上的像素区域对应起来,也就是进行像素填充,一般模型的每个顶点都会带有一些基本信息(例如,法线,位置,纹理坐标,颜色等),即一个三角面其实只有三个顶点是有基本属性的,而其他填充进来的像素区域是并不直接拥有这些基本属性的,他们的属性都是通过在顶点间差值计算得来的(其实上面提到的像素应该称为片元fragment).有些书籍中把图元装配也归到栅格化中,请注意.经过这些处理模型基本在GPU中已经形成了他所要绘制到屏幕上的样子了.不过这并没有结束.


  3,经过上面的处理我们就仿佛得到了一个预备要绘制到屏幕上的临时数据区域,不过到底是将这些像素是否最终绘制到屏幕上,怎么绘制到屏幕上,还需要经过一些判断.制作游戏中最常见的现象,离摄像机近的物体要绘制在前面,会把离摄像机较远的物体挡住(不考虑半透明物体),如果没有某些判断的话,那如果GPU先渲染了离屏幕较近的物体,而后处理了离屏幕较远的物体,那么近的先画到屏幕上,远的后画就会把之前的覆盖掉了,这显然不是我们需要的效果(并不是所有引擎都可以自由的去控制物体的渲染顺序,即使可以控制,很多时候也十分麻烦,并不十分常用).所以说我们就需要在绘制的时候进行检测,上面这个问题使用的是ZTest(还有很多检测这里只提这一个,其他的以后遇到了再具体说),对于GPU来说拥有两个最基本的缓冲区:帧缓冲区和Z缓冲区(也叫深度缓冲区),这两个缓冲区都与屏幕上的每个像素一一对应,其中帧缓冲区对应着屏幕上的像素点的最终颜色,GPU最终都是通过把颜色写入这个区域来呈现在屏幕上的,而另一个深度缓冲区则存储着屏幕上每个像素的深度值,所谓的深度值就是离摄像机的远近(一般都被规范化为一个0~1的数值),数值越大说明离摄像机越远,刚才我们提到的ZTest就是通过将光栅化后的像素的深度值和当前屏幕上像素对应的深度值进行相应的比较,来绝定是不是把新的像素点覆盖掉原来的像素点(当然这并不是最终是否写入帧缓冲区的判断条件,还有一些其他判断),至于以什么模式来判断并无硬性要求,根据你具体的要求来选择判断方式.经过这一系列的判断和处理之后GPU会把最终结果写入帧缓冲区,我们会在下一帧看到刚刚处理过的最新画面了

0 0
原创粉丝点击