这篇随笔,就不按照各种专业的解释来描述了,完全看自己发挥吧,写到哪儿算哪儿。若是哪里有说的不对的地方,请各位看官直说无妨!
说到游戏研发,就不可避免会提到图形学,图形学里面细去研究,就会牵涉到各种各样的数学知识,向量,矩阵之类的!而到这儿,咱们先开始从shader谈起,什么是shader?咱们通常说写个shader,其实也就是写了一个执行某种功能的程序,跟你写个普通的程序原理上说一样的,而不同之处在于,shader是写个GPU执行的,说到GPU执行,那么就得谈到3D游戏里面的那些人物啊,花鸟啊,是怎么看到的,或者说的专业一点,叫做渲染出来的!
如果在2D上面,很简单,完全可以看作是一张图贴在屏幕上就OK。在3D上面,就复杂了一点,首先,我们的屏幕上2D的,不像现实世界,是三维空间!那么怎么在屏幕上画东西才能看上去有3D效果呢,你可以试试在纸上画一个立方体,学过数学都会画,你第一眼看上去就会觉得这是3D的,而不是一个简单的矩形!
模型坐标系:在计算机的3D世界里,也是通过这样一种东西来实现了3D效果。如果在计算机屏幕上面绘制3D模型,那么我们首先在3D软件上制作出这个模型,这个模型会有一个原点,来建一个坐标系,无论是左手还是右手都差不多,这个坐标系,我们就叫做模型坐标系,那么这个模型的每个部位都相对于原点有一个坐标。
世界坐标系:既然每个模型都有一个坐标系,就相当于你自己举着手,你的手在脸的正前方,那么相对于旁边的人,你的手在哪儿。那么就会有了一个概念叫世界坐标系,在世界坐标系中,每个模型的坐标都是相对于世界坐标系原点的,那么除非重叠,否则是不可能出现坐标一样的情况。就相当于你站的位置,不会再有人站了一样。而我们的光照计算也会是在世界坐标系中进行。
摄影坐标系:每个人都是在以自己的眼睛来看这个世界,比如你转动你的眼睛,看到的事物就会不一样。同样,在计算机的世界里,每次只能从唯一的视角出发来渲染物体,3D游戏都会提供摄像机漫游的功能,屏幕显示的内容会随着摄像机的变化而变化,这是因为GPU将物体的顶点坐标从世界坐标系转到了摄像机坐标系。所谓的摄像机坐标系,是以摄像机为原点,由视线方向,视角和远近平面,组成的一个梯形体的三维空间,叫做viewing frustum(视锥体)如下图
既然可以看见的区域已经确定,那么GPU就得做一下筛检,就像你面朝大海,即便春暖花开,你也只能看到你朝着的那面,你背后的风景你是看不到的,但那又客观存在着。这个时候,GPU就得做一下裁剪,在这个区域内的东西才会渲染,不在这个区域内的,那就只能被抛弃了,这一步叫做裁剪(clip),怎么判断物体在不在这个区域的过程,叫做裁剪算法。
至于怎么裁剪的,过程算法比较复杂,请自行参阅资料(这个过程也可以在应用程序中做)。裁剪过后,你这些东西都还是在3D空间里面的概念,而始终得显示在二维的屏幕上面,那么就得有个过程叫做屏幕映射,也就是说将3D的东西在2D的平面上显示出来就如同将这个立方体画在纸上,而你一看到一张纸上画的图,还是看出3D效果来。
之后的步骤,叫做图元装配,根据顶点的位置和索引关系,组成线和面,然后将超出屏幕外的三角形进行裁剪,就像一个三角形有一个顶点在屏幕外,剪掉之后,这三角形就会变成四边形了。接下来的过程,叫做光栅化,所谓光栅化,就是给显示器的像素点赋值,屏幕是由一个一个的像素点构成,给每个点赋值上相应的颜色,连起来就是一整个屏幕了,结果之前的过程,我们可以得到每个点的屏幕坐标值,也知道我们要绘制成啥样(点,线,面)其中还有个问题,如图
之后,我们就需要知道每个顶点的颜色了,这个颜色也在顶点信息之中,其中会牵涉到一种情况叫做混色,是根据当前的颜色跟正在计算的颜色的透明值,混合为一种颜色进行输出,也就是我们常说的Alpha值,一般叫做alpha混合技术,每个像素都关联一个RGB颜色值和一个A值,Alpha值用来描述物体的透明度.
计算公式为newColor=curColor*a+(1-a)*nextColor 。混合之后,颜色被写入帧缓存中。那么如果同样一个位置的,有两个顶点,如果有两种颜色,而且都不透明,那么,到底是绘制那一种颜色呢?这里就有一个概念,叫做Z Buffer一般叫Z缓冲区,或者叫深度缓冲区,用来确定这个遮挡关系,这个值在(0,1)值越小,离近裁屏幕就更近,想象一下,在现实生活中,两块木板竖着叠在你面前,你当然只能看到近的那块。那么,GPU通过比较来判断顶点之间的遮挡关系,这个值其实也只是一个相对的大小,完全就是用来比较才有用的。
算了,暂时停一下先,好累的说