课程 图形学 Rendering Pipeline
收集各方资料,稍作整理,方便我的期中复习。若无说明,markdown 引用的内容来自于引用2,这篇博文写得非常清楚,而且很有条理,建议有需要的同学去看看这篇文章。
属于图形学系列文章。
Architecture
渲染管线的主要功能就是决定在给定虚拟相机、三维物体、光源、照明模式,以及纹理等诸多条件的情况下,生成或绘制一幅二维图像的过程。对于实时渲染来说,渲染管线就是基础。因此,我们可以说,渲染管线是实时渲染的底层工具。
渲染出的图像的位置、形状是由它们的几何形状,环境特性,摄像机位置决定的。而物体的外观由材质特性,光源,纹理和着色模型确定。—— 引用2
图片来自于引用2, 渲染过程被分为3个阶段:应用程序、几何处理、光栅化。
应用阶段 (The Application Stage)
开发者完全控制,以软件方式实现。这一阶段的作用是:
将几何处理阶段需要渲染的几何体成功地传递出去,这些几何体称为渲染图元(rendering primitives)
几何处理阶段(Geometry Processing)
在这个阶段GPU对应用阶段传递的几何图元进行逐多边形和逐顶点操作。
图片来自于引用2,该阶段被分为 模型视点变换(Model and View Transform)、顶点着色阶段(Vertex Shading)、投影阶段(Projection)、裁剪阶段(Clipping)、屏幕映射(Screen Mapping) 四个部分。
模型视点变换(Model and View Transform)
将模型变换到虚拟摄像头的视角,详见链接中的前两步变换。
下图生动形象地表达了这一过程,来自引用2
顶点着色(Vertex Shading)
目的:确定模型上顶点处材质的光照效果
确定材质上的光照效果的这种操作被称为着色(shading),着色过程涉及在对象上的各个点处计算着色方程(shading equation)。通常,这些计算中的一些在几何阶段期间在模型的顶点上执行(vertex shading),而其他计算可以在每像素光栅化(per-pixel rasterization)期间执行。可以在每个顶点处存储各种材料数据,诸如点的位置,法线,颜色或计算着色方程所需的任何其它数字信息。顶点着色的结果(其可以是颜色,向量,纹理坐标或任何其他种类的阴着色数据)计算完成后,会被发送到光栅化阶段以进行插值操作。
通常,着色计算通常认为是在世界空间中进行的。在实践中,有时需要将相关实体(诸如相机和光源)转换到一些其它空间(诸如模型或观察空间)并在那里执行计算,也可以得到正确的结果。这是因为如果着色过程中所有的实体变换到了相同的空间,着色计算中需要的诸如光源,相机和模型之间的相对关系是不会变的。
详见我的另一篇文章
投影(Projection)
这里对应链接中的第三步变换。
图片来自于引用2,左边为正交投影(orthographic projection,或称parallel projection),右边为透视投影(perspective projection)。
两种投影方式的主要异同点:
正交投影。正交投影的可视体通常是一个矩形,正交投影可以把这个视体变换为单位立方体。正交投影的主要特性是平行线在变换之后彼此之间仍然保持平行,这种变换是平移与缩放的组合。
透视投影。相比之下,透视投影比正交投影复杂一些。在这种投影中,越远离摄像机的物体,它在投影后看起来越小。更进一步来说,平行线将在地平线处会聚。透视投影的变换其实就是模拟人类感知物体的方式。
正交投影和透视投影都可以通过4 x 4的矩阵来实现,在任何一种变换之后,都可以认为模型位于归一化处理之后的设备坐标系中。
裁剪(Clipping)
这部分很好理解,如果物体在观察的范围外就不需要渲染了。
屏幕映射(Screen Mapping)
目的:找到屏幕上对应的坐标
进入到这个阶段时,*坐标仍然是三维的*(但显示状态在经过投影阶段后已经成了二维),每个图元的x和y坐标变换到了屏幕坐标系中,屏幕坐标系连同z坐标一起称为窗口坐标系。
假定在一个窗口里对场景进行绘制,窗口的最小坐标为
(x1,y1)
,最大坐标为(x2,y2)
,其中x1<x2
,y1<y2
。屏幕映射首先进行平移,随后进行缩放,在映射过程中z
坐标不受影响。新的x
和y
坐标称为屏幕坐标系,与z
坐标一起(-1≦ z ≦ 1)
进入光栅化阶段。屏幕映射阶段的一个常见困惑是整型和浮点型的点值如何与像素坐标(或纹理坐标)进行关联。可以使用Heckbert(书后参考文献第520篇)的策略,用一个转换公式进行解决。
总结:
在几何阶段,首先,对模型的顶点和法线进行矩阵变换,并将模型置于观察空间中(模型和视图变换),然后,根据材质、纹理、以及光源属性进行顶点光照的计算(顶点着色阶段),接着,将该模型投影变换到一个单位立方体内,并舍弃所有立方体之外的图元(投影阶段),而为了得到所有位于立方体内部的图元,接下来对与单位立方体相交的图元进行裁剪(裁剪阶段),然后将顶点映射到屏幕上的窗口中(屏幕映射阶段)。在对每个多边形执行完这些操作后,将最终数据传递到光栅,这样就来到了管线中的最后一个阶段,光栅化阶段。
光栅化(Rasterization)
给定经过变换和投影之后的顶点,颜色以及纹理坐标(均来自于几何阶段),给每个像素(Pixel)正确配色,以便正确绘制整幅图像。这个过个过程叫光珊化(rasterization)或扫描变换(scan conversion),即从二维顶点所处的屏幕空间(所有顶点都包含Z值即深度值,及各种与相关的着色信息)到屏幕上的像素的转换。
图片来自于引用2,该阶段被分为 三角形设定(Triangle Setup)阶段、三角形遍历(Triangle Traversal)阶段、像素着色(Pixel Shading)阶段、融合(Merging)阶段
光栅化阶段包括双线性插值计算、扫描线转换、法向插值,我觉得这部分在前两个阶段处理了。
三角形设定(Triangle Setup)
三角形设定阶段主要用来计算三角形表面的差异和三角形表面的其他相关数据。该数据主要用于扫描转换(scan conversion),以及由几何阶段处理的各种着色数据的插值操作所用。 该过程在专门为其设计的硬件上执行。
三角形遍历(Triangle Traversal)
在三角形遍历阶段将进行逐像素检查操作,检查该像素处的像素中心是否由三角形覆盖,而对于有三角形部分重合的像素,将在其重合部分生成片段(fragment)。
找到哪些采样点或像素在三角形中的过程通常叫三角形遍历(Triangle Traversal)或扫描转换(Scan Conversion)。每个三角形片段的属性均由三个三角形顶点的数据插值而生成。这些属性包括片段的深度,以及来自几何阶段的着色数据。
像素着色(Pixel Shading)
所有逐像素的着色计算都在像素着色阶段进行,使用插值得来的着色数据作为输入,输出结果为一种或多种将被传送到下一阶段的颜色信息。纹理贴图操作就是在这阶段进行的。
像素着色阶段是在可编程GPU内执行的,在这一阶段有大量的技术可以使用,其中最常见,最重要的技术之一就是纹理贴图(Texturing)。简单来说,纹理贴图就是将指定图片“贴”到指定物体上的过程。而指定的图片可以是一维,二维,或者三维的,其中,自然是二维图片最为常见。
(补充)纹理映射不全都是发生在该阶段:
- 在顶点处理阶段,给定顶点的纹理坐标
- 在光栅化阶段:插值得到每个片元的纹理坐标
- 在片元处理阶段,根据纹理坐标获取片元的每一个纹理值
融合(Merging)
每个像素的信息都储存在颜色缓冲器中,而颜色缓冲器是一个颜色的矩阵列(每种颜色*包含红、绿、蓝三个分量*)。融合阶段的主要任务是合成当前储存于缓冲器中的由之前的像素着色阶段产生的片段颜色。不像其它着色阶段,通常运行该阶段的GPU子单元并非完全可编程的,但其高度可配置,可支持多种特效。
此外,这个阶段还负责可见性问题的处理。这意味着当绘制完整场景的时候,颜色缓冲器中应该还包含从相机视点处可以观察到的场景图元。对于大多数图形硬件来说,这个过程是通过Z缓冲(也称深度缓冲器)算法来实现的。Z缓冲算法非常简单,具有O(n)复杂度(n是需要绘制的像素数量),只要对每个图元计算出相应的像素z值,就可以使用这种方法,大概内容是:
Z缓冲器器和颜色缓冲器形状大小一样,每个像素都存储着一个z值,这个z值是从相机到最近图元之间的距离。每次将一个图元绘制为相应像素时,需要计算像素位置处图元的z值,并与同一像素处的z缓冲器内容进行比较。如果新计算出的z值,远远小于z缓冲器中的z值,那么说明即将绘制的图元与相机的距离比原来距离相机最近的图元还要近。这样,像素的z值和颜色就由当前图元对应的值和颜色进行更新。反之,若计算出的z值远远大于z缓冲器中的z值,那么z缓冲器和颜色缓冲器中的值就无需改变。
一些额外的补充,摘自引用2:
而当图元通过光栅化阶段之后,从相机视点处看到的东西就可以在荧幕上显示出来。为了避免观察者体验到对图元进行处理并发送到屏幕的过程,图形系统一般使用了双缓冲(double buffering)机制,这意味着屏幕绘制是在一个后置缓冲器(backbuffer)中以离屏的方式进行的。一旦屏幕已在后置缓冲器中绘制,后置缓冲器中的内容就不断与已经在屏幕上显示过的前置缓冲器中的内容进行交换。注意,只有当不影响显示的时候,才进行交换。【涨姿势啦~】
总结:
在光栅化阶段,所有图元会被光栅化,进而转换为屏幕上的像素。首先,计算三角形表面的差异和三角形表面的其他相关数据(三角形设定阶段),然后,找到哪些采样点或像素在三角形中(三角形遍历阶段),接着计算所有需逐像素计算操作(像素着色阶段),然后,合成当前储存于缓冲器中的由之前的像素着色阶段产生的片段颜色,可见性问题可通过Z缓存算法解决,随同的还有可选的alpha测试和模版测试(融合阶段)。所有对像依次处理,而最后的图像显示在屏幕上。
rendering的过程(model-view、projection、clipping、rasterization)
以 OpenGL 为例: