图形渲染流水线(渲染管线)

(本文翻译自Real-Time Rendering 4th Edition)

渲染流水线的主要作用是,在给定的一个虚拟相机、一些三维物体、光源以及其他的条件下,生成或渲染出一张二维图片。因此,渲染流水线是实时渲染最基本的工具。在图1中描绘了渲染流水线的处理过程。二维图像中的物体的位置和形状取决于它们的几何形状、环境的特征和相机在环境的位置。物体的外观受材质、光源、纹理(贴在物体表面的图片),和着色计算方程式影响。

图2.1 在左图中,一个虚拟相机位于棱锥体的尖端(即四条直线的交汇处)。只有在视景体中的图元才会被渲染。对于以透视的方式渲染的图像(正如上图),视锥体是一个截头椎体。右图展示了相机方向看到的景色。要留意,因为左图中的环形物体不在视锥体内,所以它没有被渲染到右图中。同样,左图中扭曲蓝色棱镜被视锥体的截面截断了。

1.构架

在现实世界中,流水线概念以各式各样的形式表现出来,例如工厂装配流水线和快餐店的厨房。它也应用于图像渲染。图像渲染流水线由几个阶段组成,每个阶段执行一个更大的任务的一部分。

流水线的各阶段是并行执行的,并且每个阶段都依赖与前一个阶段的结果。理想情况下,一个非流水线系统被分割为n个流水线阶段后可以加速n倍。采用流水线的主要原因就是为了获得这种性能提高。例如,一批工人快速地准备大量三文治,一个人准备面包,一个人添加肉类,一个人添加佐料。每个人将本阶段的结果传递给下个人,并且立即着手制作下个三文治的工作。如果每个人都需要20秒完成他们的工作,那么最快可能以20秒一个,一分钟3个的速度生产三文治。虽然流水线阶段的执行是并行的,但是在最慢的阶段完成之前,其他阶段都将停滞不前。举个例子,添加肉类的阶段需要更多的时间,现需30秒。那么现在最快的速度可以在一分钟完成两个三文治。对于这个特殊的流水线,因为肉类环节决定了整个生产过程的速度,所以这个环节是该流水线的瓶颈。在添加肉类环节完成之前,佐料环节可以称之为“挨饿”(对客人来说也是如此)。

这类流水线结构也可以在实时计算机图形学的背景中发现。实时渲染流水线可以大致分为四个主要阶段——应用、几何处理、光栅化、像素处理。这四个阶段如图2所示。这个构架是渲染流水线的核心。

图2 渲染流水线的基础构架由四个阶段组成:应用(Application)、几何处理(Geometry Processing)、光栅化(Rasterization)、像素处理(Pixel Processing)。其中每个阶段本身可能都是一条流水线,正如插图中几何处理阶段,也有可能是(部分)平行化的,正如插图中的像素处理。在这插图中,应用阶段是一个单独的过程,但是这个阶段也可能是流水线型或平行化的。注意:光栅化是在图元(例如三角形)中找出像素。

  每个阶段通常也是一个流水线意味着它们可能由几个子阶段组成。我们将在这里展示的功能阶段和实现的结构区分开来。一个功能阶段需要去执行一个特定的任务,但在这个流水线中这个完成这个任务的方法却是不确定的。一个给定的实现可以将两个功能阶段合并成一个单元或者使用可编程核心执行,而将另外一个更加耗时的功能阶段划分为几个硬件单元。

  渲染速度可以在帧每秒中体现出来,帧每秒是指在每秒中可以渲染出来的图像数量。渲染速度也可以用Hz(一个表示1/second的简单符号)表示,即利用刷新的频率表示。还可以利用毫秒记录渲染一张图片的时间来表示渲染时间。生成一张图片的时间通常是变化的,这取决于每帧所需执行的运算的复杂程度。每秒帧数可用来表示特定帧的速率和一段使用时间内的平均性能。Hz也可以用于描述硬件的性能,例如被固定为一固定刷新速率的显示器。

  顾名思义,应用阶段是由应用程序驱动,因此通常是由在通用CPU中运行的软件执行的。这些CPU通常具有多个核心,进而有能力并行执行多线程。这使CPU高效运行大量与应用阶段相关的的任务成为可能。一些通常在CPU上执行的任务取决于应用的类型,例如碰撞检测、全局加速算法、动画、物理模拟及许多任务。接下来的是几何处理阶段,它主要处理几何变换、投影及所有其他类型所有其他几何操作。这个阶段计算需要绘制的是什么,应该怎么绘制和应该绘制在哪里。几何处理阶段通常在包含大量可编程核心和具有特定操作的硬件的图像处理单元(CPU)里执行。光栅化阶段通常以三个顶点作为输入,形成一个三角形,并找出所有可以认为在三角形以内的像素,然后将这些像素转发到下一阶段。最后,像素处理阶段执行程序决定每一个像素的颜色,并对每一像素进行深度测试以检测其是否可见。它还可以执行每像素操作,例如将新计算的颜色与缓冲里旧的颜色进行混合。光栅化和像素操作两个阶段都是全部在GPU中进行的。

2.应用阶段

因为应用阶段是在CPU上执行的,所以开发者可以完全操控本阶段上发生的一切。因此,开发者可以完整地决定执行计划和随后的改善性能的修改计划。改变这里也会影响后续阶段的性能。举个例子,一个应用阶段的算法或设置可以减少需要渲染的三角片的数量。

综上所述,利用一种名为计算机着色器的独立模式,一些应用工作也可以由GPU中执行。这种模式视GPU为一种高度并行化的通用处理器,而忽视其专门渲染图像的特殊功能。

在应用阶段的最后,需要被渲染的几何图形将输入几何处理阶段。点、线和三角片等渲染图元可能最终会出现在屏幕(或其他任何正在使用的输出设备上)。这是应用阶段最重要的任务。

这个阶段的一系列基于软件的操作没有被划分为子阶段,不像几何处理、光栅化、像素处理阶段[1]。然而,为了增强性能,这个阶段进程被并行执行于多个处理器核心中。在CPU设计中,这被称为超标量体系结构,因为它可以在一阶段、同一时间执行多个进程。18.5节将呈现多种多样的运用多处理器核心的方法。

碰撞检测通常是一个被执行与该阶段的程序。在两个物体之间的碰撞被检测到后,将产生一个反馈,并发送给正发生碰撞的物体和力反馈设备。应用阶段也是处理来自其他源(例如键盘、鼠标、头戴式显示器)的输入的地方。根据这种输入,可能会采取几种不同的操作。加速算法(例如特定的剔除算法)也会在这里执行,以及不能在剩下流水线阶段中处理的其他操作。

3.几何处理阶段

在GPU上的几何处理阶段负责大部分的每三角片和每顶点操作。该阶段可以进一步划分为以下结果功能阶段:顶点着色、投影、裁剪、屏幕映射(图2.3)。

 

图3 几何处理阶段划分为一系列的功能阶段

3.1顶点着色

顶点着色阶段由两个主要的任务,即去计算每一个顶点的位置和去求程序员想要的任何顶点输出数据,例如法线和纹理坐标系。在传统上,许多物体的着色是通过将光照射到每个顶点的位置和法线上,并且只将结果颜色存储在顶点上。然后将颜色内插到三角片上。因此,可编程顶点处理单元被称为顶点着色器。随着现代GPU的出现,并随着一些甚至所有的着色都发生在每一个像素上,顶点着色阶段变得更加的常规,可能不再计算任何着色函数,这取决于程序员的意图。顶点着色器现在是一个更加规范的单元,它用于设置与每个顶点相关联的数据。顶点着色器可以用于顶点动画。

在介绍顶点坐标的计算方式之前,必须介绍一系列的坐标空间。在映射到屏幕的过程中,一个模型被变换到几个不同的空间或坐标系统。原本一个模型停留在它自己的模型空间,这意味着它根本没有被变换。每个模型都可以与模型变换相关联,以便对其进行定位和定向。一个模型与多个模型变换相关联是可能的。这意味着在相同场景中,同一个模型可以具有多个拥有不同位置、方向和大小的实例,而无需要求复制基础的几何图形。

它是由模型变而来的顶点和法线。对象的坐标系被称为模型坐标系,在对这些坐标系进行模型变换后,这些模型将被移至世界坐标系或世界空间。世界空间是独一无二的,以及当经历各自的模型变换之后,所有模型都将存在于同一空间中。

正如先前所说,只有摄像机(或观察者)视野内的对象才能被渲染。摄像机在世界空间有一个用来放置位置和一个指示照相机朝向的方向。为了方便投影和裁剪,摄像机和所有模型需进行观察变换。观察变换的目的是将它放置在原点并固定方向,来让它看向负z轴方向,并且y轴指向上,x轴向右。我们习惯用-z轴。一些书上可能更喜好看向+z轴。这两者的区别大部分只是表达方式不同,它们之间的转换是简单的。在进行观察变换后的实际位置和方向依赖于底层应用程序编程接口。因此这个空间被描述为摄像机空间,或者更常说的是观察空间或眼睛空间。在图4中有一个描述了观察变换对摄像机和模型的影响方式的例子。模型变换和观察变换都可以实现为4×4的矩阵,这是第四章的主题。然而,意识到顶点的位置和法线可以以任何程序员喜欢的方式来计算这一点是很重要的。

图4 在左图中,在一个自顶向下的视图展示了用户想要相机位置和方向,在一个+z轴指向上方的世界里。观察变换调整了这个空间,将摄像机置于原点,并且-z轴指向前方,+y轴指向上方,如右图所示。这样做事为了让裁剪和投影工作变得更简单、更快速。浅蓝色区域是可视范围。这样,由于这个可视范围是一个截头锥体,所以透视图是可以被推测的。这种技术可以应用在其他任何类型的投影上。

接下来,我们将描述第二种顶点着色的输出类型。为了产生逼真的场景,虽然仅仅渲染物体的形状和位置是不够的,但是它们的外表必须被建模。所谓建模包括了每个物体的材质和光源照射下的特效。材质和光源可以运用从简单颜色到基于物理的复杂表达等方式来建模。

确定光照对材质的影响的操作被称为着色。它需要计算物体上不同点的着色方程。通常,这些运算有一部分是在几何阶段的物体顶点上进行的,以及另一部分是在逐像素处理阶段进行的。每个顶点都存储这大量的材质数据,例如顶点位置、法线、颜色或者其他在着色等式上需要用到的数字信息。顶点渲染的结果(这可能是颜色、向量、纹理坐标,或者是其他类型的渲染数据)之后被传送到栅格化和像素处理阶段进行插值并用于计算物体表面的颜色。

作为顶点渲染的一部分,渲染系统执行投影和之后的裁剪,这使得视体变换为一个顶点为(-1,-1,-1)和(1,1,1)的单位正方体。也可以用不同的范围来定义相同的视体,例如,0≤z≤1。这个单位正方体被称作正则视体。首先完成的是投影,以及它是在GPU上由顶点着色器完成的。常用的投影方法有两种,分别称为正交投影(或者称为平行投影)和透视投影。见图2.5。实际上,正交只是其中一种平行投影。其他的几种也有他们的用处,特别是在建筑设计领域,例如斜向投影和轴向投影。老街机游戏《Zaxxon》就是以后者来命名的。

请注意到,投影被表示为一个矩阵,所以有时候它会和其他的几何变换串联在一起。

正交投影的视见约束体是一个普通的正方盒,并且正交投影是将这个视见约束体变换为一个单位正方体。正交投影的主要特征是在进行正交投影变换后平行的线段依旧平行。这种变换结合了平移和缩放。

透视投影则比较复杂一点。在这种投影中,远离摄像机的物体会在投影后会显得比较小。另外,平行的线可能会在地平线上交会。因此,透视变换模仿了我们感知物体大小的方式。从几何上看,透视投影的视见约束体被称为截头锥体,它是由一个矩形平面截去顶端的锥体。截头锥体也被转换为单位立方体。正交和透视的变换都可以被变为4*4的矩阵,并且在变换后,模型进入裁剪坐标系。这些坐标实际上被称作齐次坐标,齐次坐标将在第四章中讨论,并且这些发生在除

以w分量之前。CPU顶点着色器必须总是输出这种类型的坐标,以便在下一个功能阶段——裁剪阶段中正确工作。

尽管这些矩阵只是将一个约束体变换为另一个,但他们还是被称为投影。这是因为在展示后,z轴分量是不会保存在生成的图像中,而是保持在z缓冲中,这将会在2.5节中描述。以这种方式,模型从三维空间被投影至二维空间。

3.2可选的顶点处理

每项渲染管线都会有以上描述的部分。一旦这部分过程完成了,为了曲面细分,几何着色和数据流输出,我们还可以加入一些发生在CPU中的可选阶段。它们的运用依赖于硬件的能力(不是所有GPU都有实现它们的能力),和程序员的愿望。它们之间一般是相互对立的,并且一般来说它们是不常用的。我将会在第三章更多地讨论它们。

第一个可选的阶段是曲面细分。想象你有一个弹性球形物体。如果你只用一组三角片来表示它,那么你可能会遇到质量上或性能上的问题。你的球在五米远处看起来也许不错,但是如果近距离,特别是沿着轮廓看,是可以看出是由三角片组成的。如果你想让更多三角片表示球来改善其质量,那么当球的距离很远且只占小部分屏幕像素时,你可能会浪费可观的处理时间和内存。利用曲面细分,可以使用恰当数量的三角片生成一个曲面。

下一个可选的阶段是几何着色器。这个着色器比曲面细分着色器的出现时间更早,所以在GPU上更常见。它与曲面细分着色器类似,能够生成各种各样的图元和产生新的顶点。由于在创建新顶点的范围是有限的,而输出单元的类型则更加有限,所以几何着色器是一个简单很多的阶段。几何着色器有几种用途,其中最流行的是粒子生成。想象一些模拟烟火爆炸。每个火球可以被表示为一个点,一个独立的顶点。几何着色器处理每个点并让他们变为一个矩形(由两个三角片组成)。这个矩形是面向观察者,并且覆盖几个像素的,因而可以提供一个更有说服力的图元让我们去渲染。

最后的可选阶段称为流输出。这个阶段让我将GPU用做几何引擎。此时,我们可以选择将这些处理过的顶点输出到一个数组中进行进一步处理,而不是将处理过的顶点发送到管道的剩余部分以呈现到屏幕上。在后面的通道中,这些数据既能被CPU利用,也能被GPU利用。这个阶段通常用于粒子模拟,例如我们的烟火示例。

这三个阶段是按曲面细分,几何着色和流输出的顺序执行的,而且每个都是可选择是否执行的。不管哪个选项被使用,如果我们继续将沿着管道向下走,我们将会得到一组以齐次坐标表示的顶点,这些顶点将会被检查相机是否能看到它们。

3.3裁剪

只有全部或部分包含在视见约束体的图元才需要传输到能将光栅化阶段(以及随后的像素处理阶段),然后将他们画在屏幕上。如果图元完全置于视见约束体中,那么它将按其原样被传输到下一阶段。如果图元完全置于视见约束体之外,那么它将不被渲染,也就不会进一步往下传输。只有部分置于视见约束体中的图元需要被裁剪。例如,一条两端点分别在视见约束体的内部和外部的直线段应该被裁剪到视见约束体中,这样位于视见约束体外部的顶点就会被位于该线和视图体之间的新顶点所取代。投影矩阵的使用意味着被变换的图元被裁剪至单位立方体上。在裁剪之前进行视图变换和投影的优点是在裁剪时保持坐标系的一致性;毕竟图元最终还是会被裁剪至单位立方体中。

在图2.6中描述了裁剪的过程。除了视见约束体的六个裁剪平面外,用户还可以定义额外的裁剪平面来切割平面。在818页的图19.1中有一张图片展示了名为切片的形象化类型。

裁剪步骤使用由投影产生的4值齐次坐标来执行裁剪。(Values do not normally interpolate linearly across a triangle in perspective space)透视空间中的值通常不会通过三个坐标进行线性插值。在进行透视投影时,数据需要第四个坐标,才能够正确进行插值和裁剪。最终,执行透视除法。透视除法将产生的三角片的位置放进三维正则设备坐标系中。正如此前所述,这个视见约束体的范围是(-1,-1,-1)到(1,1,1)。在几何阶段的最后一步是将该空间转换为窗口空间。

图2.6 在投影转换后,只有在单位立方体中的图元(相当于在视见截头锥体中的图元)需要进行后续处理。因此,在外面的图元将被丢弃,而完全处于图元会被保留下来。与单位正方体相交的图元被单位立方体截断,并且抛弃旧顶点,产生新的顶点。

 

3.4 屏幕映射

只有在视见约束体中(被截断)的图元可以被传递到屏幕映射阶段,并且在进入该阶段时各坐标都仍然是三维坐标。每个图元的x轴和y轴分量都会被转换到屏幕坐标形式。带上深度z的屏幕坐标被称为窗口坐标。假设场景应被渲染至一个最小角点在(x1,y1)和最大角点在(x2,y2)的窗口中,并且x1<x2和y1<y2。然后屏幕投影是一个坐标转换,随后的是缩放操作。新的x轴分量和y轴分量被称为屏幕坐标。Z轴的分量(在OpenGL中其值范围为[-1,1],而在DirectX中则是[0,1])也会被映射至[z1,z2],其默认值为z1=0和z2=1。尽管这些值都可以通过API(用户程序编程接口)来改变。窗口坐标和这个重新映射的z值被传递到光栅化阶段。屏幕映射过程如图2.7所示。

 

图2.7 在投影转换之后这些图元将位于定位立方体内部,屏幕映射过程负责在屏幕上找到坐标。

接下来,我们将描述整型和浮点数的坐标值如何与像素(和纹理坐标)相关。

图2.8 左:光栅化过程被分为两个功能阶段,这两个阶段名为三角片设置和三角片遍历。右:像素处理过程被分为两个功能阶段,这两个阶段被称为像素着色和像素合并。

是否认为一个像素被一个三角片覆盖,取决于你如何设置GPU管线。举个例子,你可能利用点采样去确认是像素是否在三角片内部。最简单的方式是对每个像素的中心进行点采样,如果该中心点在三角片内部,则可认为该像素也在三角片内部(节5.4.2)。你也可以使用超采样或多采样抗锯齿技术在每个像素中使用多个采样。还有另一种方法可以实现保守的光栅化,这种方法是如果一个像素至少有一部分与三角形重叠,那么就可以认为这个像素在这个三角片内部(节23.1.2)。

4.1 三角片设置

在这个阶段将会计算三角形的微分、边方程和其他数据。这些数据将会被用于三角形遍历,以及对几何阶段的各种着色数据的插值中。该任务以硬件方式实现。

4.2 三角片遍历

在这个阶段,每个中心点(或采样点)被三角形覆盖的像素被检测和为像素和三角形重叠的部分产生一个片元。在5.4节会描述更详细的采样方法。找出哪些样本或像素在三角形中通常称为三角形遍历。每个三角形片元的属性都是利用插值法从三角片元的三个顶点之间的数据中生成的(第五章)。这些属性包括片元的深度,以及所有来自几何阶段的数据。McCormack等人【1162】提供了更多在三角形遍历的的信息。三角形遍历阶段也执行了对三角片的透视校正差值【694】(节23.1.1)。在一个图元中的所有像素和样本点接下来会被发送至像素处理阶段。接下来将会描述它。

5 像素处理

在这个位置,所有被认为处于一个三角片或其他图元内的像素都已经被找出,这是前面所有阶段的工作的结果。如图2.8右边所示,像素处理阶段将被分为像素着色和合并阶段。像素处理阶段将对在图元内的像素或样本进行逐像素或逐样本的计算或运筹。

5.1像素着色

全部逐像素着色计算都是在这个阶段被执行的,该过程以插值得到的着色数据作为输入。最终的结果是一种或更多的颜色被传递到下一阶段。不像三角形设置和遍历阶段(它们通常是由专用的硬件执行的),像素着色阶段是在可编程的GPU核心中被执行的。为了得到想要的结果,程序员需要为像素着色器提供一个程序(或一个片元着色器,这是OpenGL对此的称呼),这个程序可以包含任意被需求的计算。在这里可以使用各种各样的计算,其中最重要的纹理技术。在第6章将会提供更多关于纹理的细节。简单来说,对一个物体进行纹理化类似于为了各种目的,将一张或以上的图片贴在物体的表面。图9描述了这个过程的一个简单示例。图像可以是一维、二维、或三维的,其中二维图像最常见。在最简单的情况下,最终产物是每个片元的颜色值,并且这些数据将会被传递到下一个子阶段。

图9 在图的左上方展示了一个没带纹理的巨龙模型。图像纹理中的片段被贴在巨龙的表面后,其结果就如图的左下方。

5.2 合并

每个像素的信息都存在颜色缓冲中,这是一个用来存储颜色数据(每种颜色数据包含红、绿、蓝三种通道)的矩阵。合并阶段的任务是将在像素着色阶段生成的片元颜色数据与现存于缓冲的颜色进行混合。这个阶段被也被称为ROP,表示“raster operations pipeline(光栅操作管道)”或者“Render output unit(渲染输出单元)”,怎么称呼这个阶段取决于你问的是什么人。不像着色阶段,负责执行合并阶段的GPU组件通常只支持部分可编程。然而,它是高度可配置的,可以实现各种效果。

这个阶段还负责解决可见性问题。这意味着当整个场景被渲染后,颜色缓冲应该包含摄像机视景中可见图元的颜色。对于大部分甚至全部图形硬件,为了实现这个效果,需要用到z缓冲(也称为深度缓冲)算法。z缓冲的大小和形状与颜色缓冲相同,并且z缓冲的每个像素储存着最接近摄像机位置的图元的z值。这意味着,当一个图元被渲染到某个像素时,将计算该像素上图元的z值,并将其与相同像素上z缓冲区的内容进行比较。如果新的z值小于z缓冲区中的z值,那么在这个像素上,正在渲染的图元比在z缓冲中的更接近摄像机。因此,该像素的z值和颜色将使用正在绘制的图元的z值和颜色进行更新。如果正在计算的z值大于z缓冲中的z值,那么颜色缓冲和z缓冲的值保持原样。Z缓冲算法是简单的,它趋于O(n)(n是指被渲染的图元数量),并且适用于任何可以为每个(相关)像素计算z值的绘图图元。还需注意到,这个算法允许以任何顺序渲染大部分图元,这是它流行的另一个原因。然而,z缓冲只保存屏幕上每个点的深度信息,所以它不能被用于部分透明图元。这些透明图元必须在所有非透明图元之后进行渲染,并且以从深到浅的顺序或者使用单独的顺序无关算法进行渲染。透明度是基础z缓冲算法的主要弱点之一。

我们已经提到了,颜色缓冲的作用存储每个像素的颜色,z缓冲的作用则是存储每个像素的深度。然而,还有其他通道和缓冲可以用来过滤和捕捉片元信息。Alpha通道与颜色缓冲相关联,它是用来保存每个像素的与不透明度相关的值(节5.5)。在旧的API中,alpha通道也被用来通过alpha测试特性有选择地丢弃片元。如今抛弃的操作可以插入像素着色器程序中,以及任何类型的计算都可以触发抛弃动作。这类型的测试可以被用于确保完全透明的片元不会影响z缓冲。(节6.6)。

模板缓冲是一种幕后缓冲,它用于记录被渲染的图元的位置。它通常每像素包含8比特。可以利用各种函数将图元渲染进模板缓冲。在此之后,这个缓冲的内容可以用于控制对颜色缓冲和z缓冲的渲染。例如,假定模板缓冲已绘入一个实心圆。这可以实现只允许将后续的图元渲染到颜色缓冲与模板缓冲中实心圆重叠位置的操作。模板缓冲可以作为一种生成某些特殊效果的强大工具。所有这些管线末端的函数都被称为光栅操作(ROP)或混合操作。我们可以将颜色缓冲区中当前的颜色与三角片中正在处理的像素的颜色混合,从而产生透明和累积样本颜色等效果。如前所述,混合操作通常是可配置且不完全可编程的。然而,一些API已经支持光栅化顺序视图(也被称为像素着色排序),这可以启用可编程混合功能。

帧缓冲通常由系统上的所有缓冲组成。

当到达并通过光栅化阶段后,从摄像机的角度可见的图元都将显示在屏幕上。屏幕显示颜色缓冲的内容。我们需要双缓冲来避免用户发现图元被光栅化和发送到屏幕的过程。这意味着场景的渲染在屏幕之外的后台缓冲区里进行。一旦场景在后台缓冲区渲染完毕,后台缓冲的内容将与之前在屏幕上显示的前台缓冲的内容交换。交换通常发生在垂直回描期间,此时这样做是安全的。

关于不同缓冲区和缓冲方法的更多信息,请参见第5.4.2节,23.6节和23.7节。

2.6 总结

点、线和三角形是用来构建模型或对象的渲染图元。假设应用程序是一个交互式计算机辅助设计(CAD)应用程序,用户正在检验华夫饼制作机的设计模型。在这里,我们将遵循这个模型来完成整个图形渲染流程,包括四个主要阶段:应用、几何、光栅化和像素处理。场景通过透视投影渲染到屏幕上的一个窗口。在这个简单的例子中,华夫饼制作机的模型既包括线条(以显示部件的边缘),也包括三角面(显示表面)。华夫饼制作机有一个可以打开的盖子。一些三角面由带有制造商标识的二维图像纹理。在这个例子中,在光栅化阶段只进行纹理粘贴,而表面着色是在几何阶段完成计算的。

应用阶段

对于透视图,我们假设应用程序已经提供了一个投影矩阵。此外,对于每个对象,应用程序都计算了一个矩阵,该矩阵描述视图转换以及对象本身的位置和方向。在我们的例子中,华夫饼制作机的基座有一个矩阵,盖子有另一个矩阵。在几何阶段,对象的顶点和法线被这个矩阵转换,将对象放入视景空间。然后可以使用材质和光源属性在顶点处进行着色或其他计算。然后使用一个单独的用户提供的投影矩阵来执行投影,将对象转换为代表肉眼所见的单位立方体空间。立方体外的所有图元都将被丢弃。所有与这个单元立方体相交的图元都被裁剪到这个立方体上,以获得一组完全位于这个单元立方体内的图元。然后这些顶点被映射到屏幕上的窗口中。在执行了每三角片和每顶点的操作之后,得到的数据被传递到光栅化阶段。

光栅化

所有在前一阶段的剪切中存留下来的图元都将被光栅化,这意味着找到原语中的所有像素,并将其进一步发送到像素处理流程中。

像素处理

这里的目标是计算每个可见图元的每个像素的颜色。那些已经与任意纹理(图像)相关联的三角形将根据需要使用这些应用于它们的图像进行渲染。可见性是通过z缓冲算法,以及可选的弃置片元和模板测试来解决的。每个对象依次处理,最后的图像然后显示在屏幕上。

结论

这一管线源于数十年来针对实时渲染应用程序的API和图形硬件的发展。需要注意的是,这不是唯一可行的渲染管线;脱机渲染管线经历了不同的演进路径。用于电影制作的渲染通常使用微多边形管道来完成[289,1734],但光线跟踪和路径跟踪最近开始流行。包含在11.2.2节的这些技术也可用于建筑和设计的预演。

多年来,应用程序开发人员使用这里描述的过程的唯一方法是通过使用的图形API定义的固定函数管道。固定函数管道之所以如此命名,是因为实现它的图形硬件由无法以灵活方式编程的元素组成。最后一个大型固定功能游戏机的例子是任天堂(Nintendo)在2006年推出的Wii。最后一个大型固定功能游戏机的例子是任天堂(Nintendo)在2006年推出的Wii。另一方面,可编程的GPU可以精确地确定在整个管道的各个子阶段中应用了哪些操作。对于本书的第四版,我们假设所有的开发都是使用可编程GPU完成的。

 

 

posted @ 2022-07-21 22:50  mshentai  阅读(646)  评论(0编辑  收藏  举报