有一定OpenGL ES开发经验的朋友都知道,最终传入渲染管线的是由摄像机矩阵(视图矩阵),投影矩阵,基本变换总矩阵相乘得到的总变换矩阵。在顶点着色器中,着色器将接收到的原始顶点位置与传入的总变换矩阵相乘(OpenGL ES中采用的是列向量,矩阵在左,向量在右进行相乘),得到顶点最终的绘制位置,基本代码如下:
gl_position = uMVPMatrix * vec4(aPosition,1);
有些朋友或许有个疑问:“传入的原始顶点位置aPosition中已经包含x,y,z这3个坐标分量了,为啥与总变换矩阵相乘时还需要加上一个分量1,变成四维坐标向量呢?”这个技术在图形学中被称为齐次坐标表示,所谓的齐次坐标表示就是用N+1维坐标表示N维坐标。齐次坐标还分为规范化和非规范化的,规范化的齐次坐标在x,y,z分量后增加的那个分量的值必须为1,这也就是上述代码中增加的分量1了。这个增加的分量一般称为w分量。后面所谓的执行透视除法实际上很简单,就是将齐次坐标[x,y,z,w]规范化,即将四个分量分别除以w,结果为[x/w,y/w,z/w,1]。
对于简单的开发需求而言,了解这些是最基本的。但需要进行更灵活深入的开发,还需对上述三类矩阵进行更深层次的了解。很有必要需要了解几种不同的空间,如下详细介绍。
1、物体空间:
需要绘制的3D物体所在的原始坐标系代表的空间。比如,在进行设计时,物体的几何中心是摆放到坐标系原点的,这个坐标系代表的就是物体空间。
2、世界空间:
物体在最终3D场景中的摆放位置对应的坐标所属的坐标系代表的空间。比如,要在[1,2,3]位置摆放一个立方体,在[10,20,30]位置摆放一个球体,这里面[1,2,3]和[10,20,30]两组坐标所属的坐标系代表的就是世界空间。
3、摄像机空间(视图空间):
物体经摄像机观察后,进入摄像机空间。摄像机空间指的是以观察场景的摄像机为原点的一个特定坐标系代表的空间。在这个坐标系中,摄像机位于原点,视线沿z轴负方向,y轴方向与摄像机Up向量方向一致。需要注意的是,在摄像机空间中,摄像机永远位于原点,视线一直沿z轴负方向,y轴一直沿摄像机Up向量方向。但是相对于世界坐标系,摄像机坐标系可能是歪的或斜的。也就是说,摄像机空间代表的是以摄像机本身为中心的一种坐标系,就像人眼观察世界时若将头歪过来看,感觉是物体斜了,其实物体在世界坐标系中是正的,只是经过眼睛观察后进入了眼睛(摄像机)坐标系,在这个坐标系里是歪的而已。
4、剪裁空间
只有在视景体里面的物体才能最终被用户观察到。也就是说并不是摄像机空间中的所有物体都能最终被观察到,只有在摄像机空间中位于视景体内的物体才能最终被观察到。因此,将摄像机空间内视景体内的部分独立出来经过处理后就成了剪裁空间。
5、标准设备空间
对剪裁空间执行透视除法后得到的就是标准设备空间了,对于OpenGL ES而言,标准设备空间3个轴的坐标范围都是-1.0到1.0。
6、实际窗口空间
一般代表的是设备屏幕上的一块矩形区域,其坐标以像素为单位。即视口对应空间。
通过上述的介绍,朋友们应该对各种空间有了更加深入的了解,那么所有变化的完整流程是什么,我们可以用一张图来形象说明: