光照包含光源种类(点光源point,方向光源directional和聚光灯光源spot),光源位置信息,光源颜色,强度信息。
2.2 图形渲染管线
图形渲染管线可以大致理解为定点数据经过定点变换后进入图元装配,并进行纹理映射、片元处理、光照等操作后,进行光栅化并输出倒帧缓冲里。
具体在顶点变换时其实过程还是比较复杂的,不能一笔带过。
比如最初送进来的是模型坐标系(Model Coodinates)坐标信息,经过模型变换(Model Transform)后变为世界坐标(World Coodinates)。模型变换通过对模型执行平移(translation)、缩放(scale)、旋转(rotation)、镜像(reflection)、错切(shear)等操作,来调整模型的过程。通过模型变换,我们可以按照合理方式指定场景中物体的位置等信息。
这里插一段对模型变换的解释。我们为什么需要模型变换?我们在OpenGL中通过定义一组顶点来定义一个模型,或者通过其他3D建模软件事先建好模型然后导入到OpenGL中。顶点属性定义了模型。那么如果我们要在一个场景中不同位置、不同的比例、不同角度显示同一个模型怎么办?如果继续以类似的顶点属性数据定义同一个模型,调整它满足上述需求的话,不仅浪费显卡内存,而且效率很低。所以,我们定义的模型根据需要可以进行放大、缩小等操作来不同比例显示,可以通过平移来放在不同位置,可以通过旋转来按不同角度显示。这种方式就是执行模型变换。
世界坐标(World Coodinates)经过视变换(View Transform)后得到眼坐标系(Eye Coodinates)。OpenGL成像采用的是虚拟相机模型,但这个相机并不存在。在现实生活中,我们通过移动相机来拍照,而在OpenGL中我们通过以相反方式调整物体,让物体以适当方式呈现出来。
在世界坐标系中,对于顶点进行顶点光照处理(Per-vertex Lighting)后,进行投影变换(Projection Transform),得到裁剪坐标系(Clip Coodinates)。这部分内容后期再着重介绍。
之后经过透视除法或者也可以叫做(Homegeneous Division)得到规范化设备坐标系(Noramlized Deviced Coodinates)坐标信息。这些坐标信息经过视口变换(Viewport Transform)后得到最终屏幕坐标系(Screen Coodinates)坐标信息。视口变换主要是将视景体内投影的物体显示到二维的视口平面上。在计算机图形学中,它的定义是将经过几何变换, 投影变换和裁剪变换后的物体显示于屏幕指定区域内。就好比照片拍好了,要确定照片的大小,放大照片还是缩小照片,也就是把图形画下来,是要占据整个屏幕还是屏幕的一部分。注意和视变换(View Transform)区别开。
这些过程便是顶点变换全过程。之后继续进行最初我们讲的光栅化,片元处理,纹理处理,片源光照等处理后进行光栅处理,最后输出到帧缓冲(Framebuffer)中去。
下图为全管线流程图:
OpenGL渲染管线流程图
到此为止就已经将前期知识都讲解完毕,请务必记号管线渲染技术流程图,很重要,很重要,很重要,说三遍!
3. OpenGL图形编程
我想现在你已经彻底对图形学懵了对吧,各种坐标,各种变换,各种不知道干什么用的名词。没关系,先了解一下,现在进入OpenGL 图形编程。
3.1 几何 vs. 拓扑
假设原始图形如下图所示:
如果改变几何,就是改变顶点位置,比如我们移动顶点3的位置到下图所示位置: