图形渲染管线的作用是在给定视角、三维物体、光源、着色方程、纹理等条件时,产生或者渲染出一幅二维图像。
实时渲染可以被粗略地分为三个连续的阶段,分别是application阶段、geometry阶段和rasterizer阶段。
管线系统中的最慢的一个阶段决定了渲染的速度。
application阶段通常在运行在CPU的软件上实施,geometry阶段通常在GPU上实施,而rasterizer阶段也在GPU中实施。
这个阶段的最重要的任务是为geometry阶段提供要被渲染的基元,例如点、线和三角形。
冲突检测常常在此阶段进行。来自键盘和鼠标的输入也需要在此阶段进行处理,另外,一些运算过程如纹理映射也在此阶段进行。
此阶段是进行顶点和多边形操作的关键阶段。它可以被更加详细的分为五个function部分:
1.model&view transform
2.vertex shading
3.projection
4.clipping
5.screen mapping
在被呈现在屏幕上之前,物体的模型需要经历几次变形。首先,每个模型都有自己的局部坐标系。为了对场景(scene)进行处理,需要先将这个场景中的所有模型都用同一个坐标系进行表示,这一坐标系就叫做世界坐标系。
为了减少渲染量,只有处于摄像机视角范围内的物体模型才需要被送往下一管线。为了便于进行投影和剔除,需要对摄像机和场景内的所有物体进行从世界坐标到相机坐标的变幻。
为了使场景更加真实,除了形状和位置以外,物体的外观比如颜色和材质也需要进行渲染。
决定光照在某种材料上的效果的过程被称为着色。这些计算有可能发生在geometry阶段,也有可能发生在rasterization阶段。
着色过程通常被认为发生在世界坐标系中,然而在实际中,将它在其他坐标系中进行计算可能更加方便。因为只要在着色过程中涉及到的物体都被变换到同一坐标系中,它们位置的相对关系就会得到保留。
投影分为平行投影和透视投影两种。
透视投影的原理和人眼观察世界的方法类似。远处的物体看起来较小,而近处的物体看起来则较大。
只有完全处于或者部分处于视锥内的基元才需要被送入rasterizer阶段进行绘制。前一种基元将原封不动的被送入下一阶段,完全处于视锥之外的基元由于不需要渲染,所以不需要被送入下一阶段,而部分处于视锥内的基元则需要进行剔除处理。例如,一条线的一个顶点位于视锥体内部,而它的另一个顶点位于视锥体外部,那么在进行剔除的时候,位于视锥体外部的那个顶点就被线段和视锥体边界的那个交点所取代。
剔除阶段通常是由固定操作的硬件所处理的,因此程序员无法直接进行控制。
只有视锥中经过剔除的基元才会被传递到这个阶段,此时坐标系仍然是三维的。基元的x和y坐标被转化形成了屏幕坐标系。它和z坐标合起来被称为窗口坐标系。
本阶段的目的是计算和设置像素点的颜色。此过程就是实现从带有z值的屏幕上的二维顶点和每个顶点的着色信息到屏幕上像素的转化。
这个阶段可以分为以下几个子步骤:
1. triangle setup
2. triangle traversal
3. pixel shading
4. merging
在此阶段,三角形表面的微分和其他数据被计算出来,这些计算结果被用来进行扫描转化和对几何阶段产生的着色数据进行插值。专门的硬件会负责处理此过程。
此阶段需要检测每个像素的中心是否被三角形所覆盖,如果覆盖的话,每一个三角形和像素点重叠的部分都要产生一个碎片。triangle traversal或者scan conversion都是指寻找到在三角形内部的采样点和像素的过程。每个三角形碎片的属性都是通过对三角形的三个顶点的数据插值产生的,这些属性包括了碎片的深度和着色数据。
所有的像素着色的计算都在这里,通过使用输入的已插值的着色数据而进行。结果是一种或者更多的颜色被送往下一个阶段进行处理。前两个阶段都需要专门的硬件进行处理,而此阶段可以通过可编程的GPU实现。在这个过程中所可能使用到的技术中,texturing可能是最重要的一种.
每个像素的信息都被存储在color buffer中。此阶段的主要功能就是将着色阶段产生的碎片颜色和在缓存区中存储的颜色进行混合。
另外一个职责,则是解决可见性的问题。也就是说,当整个场景都已经渲染完成的时候,颜色缓冲中应该包含着从摄像机视角能看到的场景中的基元的颜色信息。对于大部分硬件来说,这都是通过z-buffer算法完成的。z-buffer和color buffer的大小与形状相同,对于每个像素,z-buffer存储着从摄像机到最靠近的基元的z值。这意味着,当一个基元被渲染到某个像素上时,在那个像素点处的基元的z值会和z-buffer中存储的同一个基元的z值相比较。如果新的z值小于z-buffer中的z值,那么正在被渲染的那个基元就比原来最靠近摄像机的基元还要靠近摄像机,因此,z值和那个像素的颜色信息就被更新为正在被渲染的那个基元的相应值。如果z值大于z-buffer中的z值,那么color buffer和z-buffer都保持不变。
除了存储颜色信息的color buffer和存储z值的z-buffer之外,还有其他用来存储和捕捉碎片信息的通道或者缓冲。
∝缓冲通常和颜色缓冲有关,用来存储每个像素的不透明度值。当有一个新碎片时,在深度测试之前,可以进行一个可选的∝测试。这个测试就是将碎片的∝值与某些参考值进行比较。如果测试不通过的话,那么这些碎片就被移除。
stencil buffer是用来记录已渲染的基元位置的缓冲区,每个像素使用8bit来记录信息。