RealTime-Rendering 第二章 自我学习和翻译

第二章 图像渲染管线

本章介绍了实时渲染图形学的核心部分,叫做图形渲染管线,也可以简称为管线。管线的主要作用就是根据给定虚拟相机,三维对象,光源等的情况下产生和渲染一个二维图像。渲染管线是实时渲染的核心工具。图2.1描述了使用管线的过程。图像中对象的位置和形状是由他们的几何图形,环境的特性以及相机在环境中的位置决定的。对象的外表被材质属性,光源,纹理贴图以及着色方程决定。图2.1我们将会解释渲染管线的不同阶段,会把重点放在功能而不是实现上。更多和每个阶段有关的细节会在之后的章节进行介绍。

2.1 架构

在现实世界中,从工厂装配线到快餐店厨房,流水线概念以多种形式体现。 管线也被用来描述图形渲染。 管道包含几个阶段,每个阶段都是执行任务的一部分。

管线阶段并行执行,每个阶段依赖于上一个阶段的结果。理想的情况下,一个非管线系统被分成n个流水阶段,可以将速度提升n倍。性能的提高是使用管线的主要原因。例如,一群人可以快速准备好大量三明治——一个人准备好面包,一个放肉,另一个加酱。每个人将自己的做好的三明治送到流水线的下一个人那里并且迅速开始准备下一个三明治。如果每个人花20秒执行自己的任务,每20秒最多可以做一个三明治,一分钟可以做三个。管线阶段是并行执行的,但是直到最慢的任务完成为止,他们都会停滞不前。例如,命令负责放肉的阶段耗时30秒,那么做三明治最快频率变成了一分钟两个。对于特定的管线,放肉阶段是瓶颈,因为她影响了整个制作过程的速度。在等待肉馅阶段完成的过程中,浇头阶段被饿死了(顾客也是如此)。

这种类型的流水线也在实时计算机图形学中找到。实时渲染管线大致被分成四个主要的阶段——应用阶段,几何过程阶段,光栅化阶段和像素处理阶段,如图2.2所示。这个结构是渲染管道引擎的核心,它在实时计算机图形应用程序被使用,因此是后续各章讨论的重要基础。每个阶段本身就是一个管线,这就意味着它是由几个子阶段组成的。我们将功能阶段及其实现的结构之间进行区分。功能阶段有具体执行的任务,但是没有指定执行任务的方式。给定的实现可以将两个功能阶段组合为一个单元,也可以使用可编程内核执行,同时将另一个耗时的功能阶段划分为多个硬件单元。
在这里插入图片描述

渲染速度可以用每秒帧数FPS表示,即每秒可以渲染的图像数。也可以用赫兹来表示,它只是1秒的表示法,即更新频率。通常也只列出渲染图像所需的时间(以毫秒为单位)。产生一张图像的时间是不同的,依赖于每帧执行的计算的复杂性。FPS不仅被用来表示一个特定帧的频率,或者表示使用期间的平均性能。 赫兹用于设置为固定速率的硬件(例如显示器)。

顾名思义,应用阶段是由应用程序驱动的,通常由运行在CPU上的软件实现。这些CPU通常是多核的,能够并行处理多个执行线程。这使得CPU可以高效的运行应用阶段负责的各种任务,传统在CPU上执行的一些任务,包括碰撞检测,全局加速算法,动画,物理模拟等等,依赖于应用程序的类型。下一个阶段是几何处理阶段,主要处理坐标转换,投影,或其他一些几何处理,这个阶段计算哪些要被绘制,怎么去绘制,在哪里被绘制。几何处理阶段主要是GPU执行的,该单元包含许多可编程核心以及固定操作硬件。光栅化阶段主要将输入的三个顶点变成一个三角形,找到所有被该三角形覆盖的像素,然后输出到下一个阶段。最后,像素处理阶段对每个像素执行操作,决定每个像素的颜色,也可能执行深度测试来判断像素是否可见,也可能会执行逐像素计算,例如把一个新颜色和像素原来的颜色进行混合,光栅化和像素处理阶段全部是在GPU进行处理的,所有这些阶段和他们内部的管线都会在后面四个章节进行讨论。关于GPU如何处理这些阶段的更多细节会在第三章进行介绍。

2.2 应用阶段

由于应用阶段通常在CPU上执行的,因此开发者可以完全控制应用阶段,因此,开发者可以完全确定实施方式,并且之后可以进行修改来提高性能。这个阶段的改变也会影响到后续阶段的性能。例如,应用阶段的算法或者设置会减少渲染的三角形数目。

综上所述,一些应用阶段的工作可以由GPU使用称为计算着色器的模式来执行。这个模式把GPU作为高度并行处理器,忽视了专门用于渲染图形的特殊功能,

应用阶段结束的时候,要渲染的几何会被输出到几何处理阶段。这些是渲染图元,即点,线,三角形,最终显示在屏幕(或者某个输出设备)上,这是应用阶段最主要的任务。

这个阶段基于软件实现,因此没有被分成几个子阶段,几何处理阶段,光栅化,像素处理阶段也是这样。然而,为了增加性能,这个阶段通常是在多个处理器上并行执行的。在CPU设计中,这些被称为超标量构造,因为能够在同一个阶段同时处理多个进程。第18.5节介绍了使用多个处理器内核的各种方法。

在一个阶段中最常用的过程是碰撞检测。两个对象之间检测到发生碰撞后,会产生响应并且发送到被碰撞的物体以及力反馈设备。应用阶段还要处理其他设备的输入,例如键盘,鼠标,头戴显示器等。根据输入的不同,会产生不同的行为动作。加速算法,例如特定的剔除算法(第19章),也会实现管道其余部分无法处理的其他任何东西。

2.2 几何处理阶段

几何处理阶段在GPU上执行,主要负责逐三角形计算和逐顶点计算。这个阶段被分成图
所示的几个阶段。
图2.3

2.3.1 顶点着色器

顶点着色器有两个主要任务,计算每个顶点的位置,估计程序员可能需要的顶点输出数据,例如法线坐标和纹理坐标。传统地,对象的大部分着色是通过每个顶点的光照位置,法线,顶点存储结果颜色来计算的。这些颜色之后会通过三角形进行插值计算,因此,这些可编程的顶点处理单元被称为顶点着色器。随着现代GPU的发展,一些或所有的着色发生在每个像素,顶点着色阶段变得更加普遍,可能根本不计算任何着色方程,这都依赖于编程者的意图。顶点着色阶段如今是一个普遍的单元,用来设置每个顶点有关的数据。例如,顶点着色器可以使用4.4和4.5节中的方法为对象产生动画效果。

我们从顶点位置是如何计算的开始说起,坐标的集合是必要的。在它渲染到屏幕的过程中,模型会变换到不同的空间和坐标系中。模型最开始位于他自身的模型空间,简单来说就是他还没有经过任何变换。每一个模型都可以和模型转换结合,因此它可以改变位置和转向。单个模型可能会应用多个模型变换,这使得同一个模型在同一个空间可以拥有几个具有不同的位置,转向和尺寸的拷贝(也可以称之为实例),而无需复制基本几何图形。

通过模型变换进行转换的是模型的顶点和法线,对象的坐标最开始称为模型坐标,当使用了模型转换后,模型就位于世界坐标或者世界空间中。世界空间是唯一的,当对模型进行他们各自的模型转换,所有的模型就会在同一个空间中。

和之前提到的一样,只渲染相机或者观察者可以看到的物体。相机在世界空间中有位置和方向,用来放置和定位相机。为了便于投影和裁剪,相机和所有的模型都会经过视图变换的转换。视图变换的目的是把相机作为原点并对准目标,确保他正前方是Z轴负方向,y轴指向上方,x轴指向右侧。我们使用-z坐标约定,一些文章中喜欢向下看+z轴,差异主要是语义上的,因为彼此之间的转换很简单。经过视图转换的实际位置和方向取决于基础应用程序编程接口(API)。如此划定的空间称为相机空间,更普遍的也有叫做视觉空间或者观察空间,视图转换是怎么影响相机和模型的如图2.4所示。模型转换和观察转换一般用4x4矩阵实现的,这在第四章会介绍。但是,重要的是要认识到可以用程序员喜欢的任何方式来计算顶点的位置和法线。
在这里插入图片描述

我们接着介绍顶点着色器的第二种输出类型。为了产生逼真的场景,仅仅渲染出对象的形状和位置是不够的,也要对他们的外形进行建模。这个说明包括每个对象的材质,以及对象身上光照的影响。 材质和灯光可以采用多种方式建模,从简单的颜色到物理描述的精细表示。

这个决定光照和材质效果的运算叫做着色,涉及到计算对象上各个点的着色方程。通常,在几何处理阶段对模型顶点进行一些计算,而其他一些计算则可能在逐像素期间执行。每个顶点可以存储各种材质数据,例如点的位置,法线,颜色或者其他需要用来计算着色方程的数据信息,然后将顶点着色结果(可以是颜色,顶点,纹理坐标或者其他种类的着色数据)或被送到光栅化阶段或者像素处理阶段进行插值,并用于计算表面的着色。

在本书中的第3章和第5章中,会更深入地讨论采用GPU顶点着色器形式的顶点着色。

作为顶点着色的一部分,渲染系统会进行投影而后进行裁剪,这会将视图体积转换为单位立方体,其极点位于 ( − 1 , − 1 , − 1 ) (-1,-1,-1) (1,1,1) ( 1 , 1 , 1 ) (1,1,1) (1,1,1)。 可以使用定义相同体积的不同范围,例如 0 ≤ z ≤ 1 0≤z≤1 0z1。单位立方称为规范视图体积。 首先完成投影,在GPU上是由顶点着色器完成的。 有两种常用的投影方法,即正交投影(也称为平行投影)和透视投影,如图2.5所示。 实际上,正交投影只是平行投影的一种类型。 还发现了其他的用途,特别是在建筑领域,例如倾斜和轴测投影。古老的街机游戏Zaxxon就是由后者命名的。
在这里插入图片描述

投影用矩阵来表示,因此有时候可能会与其他的几何变换连接在一起。

正交视图的视图体积通常是一个矩形框,而正交投影会将此视图体积转换为单位立方体。 正射投影的主要特征是,平行线在变换后仍保持平行。 此转换是平移和缩放的组合。

透视投影有点复杂,这种类型的投影,物体离摄像机越远,投影后出现的越小。 此外,平行线可能会聚在地平线上。因此,透视变换模仿了我们感知物体尺寸的方式。 从几何学上讲,视图体积称为视锥,是具有矩形底面的截顶金字塔。在变换之后视锥也变成了单位立方体。正交变换和透视变换都可以使用4×4矩阵构造(第4章),并且在任一变换之后,模型都称为裁剪坐标。 这些实际上是齐次坐标,会在第4章中进行讨论,这发生在被w除之前。 GPU的顶点着色器必须输出此类型的坐标,以便下一个功能阶段(剪切)正常工作。

尽管这些矩阵将一个体积转换到另一个,他们在展示后都叫做投影,Z轴存储在深度缓存,没有存储在生成的图像中,在2.5章会介绍。这样,模型就从三维转成了二维。

2.3.2 其他的顶点处理

每个管线都有上述的顶点处理,完成这个处理后,GPU可以按照以下顺序进行几个可选阶段:细分,几何着色器和流输出。他们的使用依赖于硬件的性能(不是所有的GPU都有)还依赖于程序员的需求,他们互相独立,并通常不常用。在第3章中将对每个进行更多说明。

第一个可选阶段是细分。想象一下你有一个弹性的球物体。如果用一组三角形集合表示他,就会遇到质量和性能的问题。你的球在五米之外看起来还不错,但是近距离就会发现一个个三角形,尤其是沿着轮廓的三角形,变得可见。如果你使用更多的三角形来表示球想要提高质量,当球离得较远并且只占用了屏幕上的几个像素,你会消耗较多的处理时间和内存。 通过细分,可以生成具有适当数量的三角形的曲面。

我们讨论了三角形,但是目前为止,我们就是在处理管线中的顶点而已。这可以用来表示顶点,线,三角形或其他对象。顶点可以用来表示曲面,例如球。表面可以指定成一组补丁,每个补丁都是由顶点组成的。细分阶段本身也包含了一系列阶段(船体着色器,细分和区域着色器),这些阶段将这些面片顶点集转换为更大的顶点集,然后用于创建新的三角形集。 场景中的相机用来决定要产生多少三角形,贴片关闭时会生成许多三角形,而距离贴片很远时则很少。

下一个可选阶段是几何着色器。该着色早于细分着色,因此在GPU上更常见。和细分着色器一样,就像细分着色器一样,它可以采用各种基本图元并可以产生新的顶点。 这个阶段更简单,因为此创建的范围受到限制,输出基元的类型也受到更多的限制。 几何着色器有多种用途,其中最常用的一种是生成粒子。 想象一下模拟爆炸。每一个火球都可以用一个点来表示,一个单一的顶点,几何着色器会把每个顶点转成面向观察者并覆盖多个像素的正方形(由两个三角形组成),从而为我们提供了更具说服力的图元进行着色。

最后一个可选阶段称为流输出。在此阶段我们将GPU用作几何引擎。此时,我们可以选择将其输出到数组以进行进一步处理,而不是将处理后的顶点向下发送到要渲染到屏幕的其余管道中。这些数据可以在后面的过程中被CPU或GPU自身使用。该阶段通常用于粒子模拟,例如我们的火球示例。

这三个阶段按细分,几何着色器和流输出此顺序执行,并且每个阶段都是可选的。无论使用哪个(如果有)选项,如果我们继续沿管线移动,我们都会具有一组具有齐次坐标的顶点,之后检查相机是否能够看到它们。

2.3.3 裁剪

只有全部或者部分在视锥体的图元能够被传递到光栅化阶段(并且后面的像素处理阶段),然后才把他们绘制到屏幕上。完全在视锥体的图元会完全传递到下一个阶段,同样,完全不在视锥体的图元不会传递到下一个阶段,因此他们不会被渲染,只需要裁剪部分在视锥体内的图元。例如,一根线有一个顶点在视锥体外,一个在里面,就会被裁剪,在视锥体之外的顶点就会被一个新的位于视锥体和直线交界处的顶点替代。 投影矩阵的使用意味着将变换后的图元剪裁在单位立方体上,在裁剪之前执行视图转换和投影的优点是使裁剪问题一致。 基元总是被裁剪在单位立方体上。

裁剪过程如图2.6所示。 除了视图体积的六个剪切平面之外,用户还可以定义其他剪切平面以明显地剪切对象。 显示这种类型的可视化效果的图像,称为切片,如818页19.1所示。
裁剪步骤使用投影产生的四元齐次坐标来裁剪,值通常不会在透视空间中跨三角形线性内插。第四个坐标是必要的这样当使用透视投影时候才能正确插值和裁剪数据。最终,进行透视划分,将所得三角形的位置放入三维归一化的设备坐标中。和前面提到的一样,这个视锥体在 ( − 1 , − 1 , − 1 ) (-1,-1,-1) (1,1,1) ( 1 , 1 , 1 ) (1,1,1) (1,1,1)之间。几何阶段的最后一步是从这个空间转成视口坐标系。
在这里插入图片描述

2.3.4 屏幕映射

只有在视锥体内的图元才会传递到屏幕映射阶段,进入这个阶段时坐标仍是三维的。每个图元的x和y坐标会被转成屏幕坐标系。屏幕坐标和z轴组合起来就叫做视口坐标系,假设场景被渲染进一个最小角为 ( x 1 , y 1 ) (x_1,y_1) (x1,y1),最大角为 ( x 2 , y 2 ) (x_2,y_2) (x2,y2)的窗口里,其中 x 1 < x 2 , y 1 < y 2 x_1<x_2,y_1<y_2 x1<x2,y1<y2, 然后,屏幕映射是平移,随后是缩放操作。得到的新的X和Y坐标就叫做屏幕坐标系,z轴 ( 在 O p e n G L 中 是 [ − 1 , + 1 ] , 在 D i r e c t X 中 是 [ 0 , + 1 ] ) (在OpenGL中是[-1,+1],在DirectX中是[0,+1]) OpenGL[1,+1]DirectX[0,+1]会被映射到 [ z 1 , z 2 ] [z_1,z_2] [z1,z2],默认值 z 1 = 0 , z 2 = 1 z_1=0,z_2=1 z1=0z2=1。 但可以使用API进行更改。 窗口坐标以及此重新映射的z值将传递到光栅化器阶段。屏幕映射过程如图2.7所示。
在这里插入图片描述接着,我们介绍整数和浮点值与像素(和纹理坐标)的关系。给定一组水平的像素阵列并且用笛卡尔坐标,在浮点坐标中最左边像素的左边缘是0.0。OpenGL一直用这个方案,DirextX10 和后续版本也使用这个方案。像素的中心是0.5,因此, [ 0 , 9 ] [0,9] [0,9]范围内的像素会覆盖 [ 0.0 , 10.0 ] [0.0,10.0] [0.0,10.0]的范围。转换很简单
d = f l o o r ( c ) d=floor(c) d=floor(c)
c = d + 0.5 c=d+0.5 c=d+0.5
其中d是像素的离散(整数)索引,c是像素内的连续(浮点)值。

尽管所有API的像素位置值都从左到右增加,但在某些情况下,OpenGL和DirectX之间的顶部和底部边缘的零位置不一致。OpenGL始终支持笛卡尔系,将左下角视为值最低的元素,而DirectX有时会根据上下文将左上角定义为最小值。 每个都有其逻辑,并且在不同的地方都不存在正确的答案。 例如,(0,0)位于OpenGL中图像的左下角,而在DirectX中位于左上角。 从一个API转到另一个API时,必须考虑到这种差异。

2.4 光栅化

给定经过转换和投影的顶点及其相关的着色数据(来自几何处理),下一个阶段主要找到所有要渲染的图元(例如三角形)内部的像素。我们把这个过程称为光栅化,它分为两个功能子阶段:三角形设置(也称为图元装配)和三角形遍历。如2.8左边所示。注意也可以处理点和线,但是三角形更加常用,因此子阶段的名称中带有“三角形”。因此,光栅化(也称为扫描转换)是从屏幕空间中的二维顶点(每个顶点具有z值(深度值)以及与每个顶点关联的各种着色信息)到屏幕上的像素的转换。光栅化也可以看作是几何处理和像素处理之间的同步点,因为在这里,三角形是由三个顶点形成的,并最终向下进行像素处理。

一个三角形是否会被像素覆盖取决于GPU管线的设置。例如,可以使用点采样来确定“内部”。 最简单的情况是在每个像素的中心使用一个单点样本,因此,如果该中心点在三角形内部,则相应的像素也将在三角形内部。 还可以使用超采样或多采样抗混叠技术对每个像素使用一个以上的采样(第5.4.2节)。 另一种方法是使用保守光栅化,是这样定义的,如果至少一部分像素与三角形重叠,则该像素位于该三角形内(第23.1.2节)。

2.4.1 三角形设置

在此阶段会计算三角形的差异,边缘方程和其他数据。 这些数据可用于三角形遍历(第2.4.2节),以及用于插值计算几何阶段产生的各种着色数据。 这个阶段使用固定功能硬件。

2.4.2 三角形遍历

这个阶段检查中心被三角形覆盖的每个像素,然后为三角形覆盖的像素部分产生一个片元。更多详细的采样方法可以在5.4节看到,找到在三角形内部的像素的过程称为三角形遍历,每个三角形片元的属性是根据三个三角形顶点的数据插值产生的,这些属性包括片元的深度,也有从几何体阶段得来的着色数据。 McCormack等提供有关三角形遍历的更多信息。 在这里,也可以在三角形上执行透视校正内插(第23.1.1节)。 然后将图元内部的所有像素或样本发送到像素处理阶段,接下来会有介绍。

2.5 像素处理

在这个阶段,经过先前所有的阶段,已经找到了在三角形或其他图元内部的所有像素。像素处理阶段被分为像素着色和混合,在图2.8中右边显示。 像素处理是对图元内部的像素或样本执行每个像素或每个样本的计算和操作的阶段。

2.5.1 像素着色

在这个阶段会用输入的插值数据执行逐像素着色计算。最终的结果会是一个或者多个颜色传递到下一个阶段。不同于三角形设置和遍历阶段,像素着色阶段是由可编程的GPU内核执行的。程序员提供一个像素着色或片段着色器,在OpenGL中众所周知)的程序,该程序可以包含任何所需的计算。可以使用多种技术,其中最重要的一种是纹理。在第6章中将更详细地讨论纹理化。简单地说,对一个对象进行纹理采样意味着将一个或多个图像“粘合”到该对象上。此过程的一个简单示例如图2.9所示。该图像可以是一维,二维或三维图像,其中二维图像是最常见的。简单来说,最终产品是每个片段的颜色值,并将它们传递到下一个子阶段。
在这里插入图片描述

2.5.2 混合

每个像素的信息存储在颜色缓存中,颜色缓冲区是颜色的矩形阵列(每个颜色是红绿蓝的组合)。混合阶段的任务是将像素着色阶段产生的片元颜色与当前存储在颜色缓冲中的元素进行混合。这个阶段称为ROP,代表“栅格操作(管道)”或“渲染输出单元”。 与着色阶段不同,执行此阶段的GPU子单元通常不是完全可编程的。 但它是高度可配置的,可以实现各种效果。

这个阶段还负责可见性。意味着当整个场景被渲染,颜色缓冲中应该包含场景中从照相机位置看过去可见的片元的颜色。对于大多数或者所有图形硬件,这个由Z缓冲(或叫做深度缓冲)计算的。深度缓冲和颜色缓冲的尺寸形状一样,每个像素存储了最近片元的Z值,这意味着当一个图元渲染到某个像素,这个像素的Z值就会被计算并和当前像素存储在深度缓冲中的Z值进行比较。如果新的值比原来的Z值小,则正在渲染的图元比之前在那个像素处最接近相机的图元更靠近相机。因此,该像素的z值和颜色将使用来自绘制图元的z值和颜色进行更新。如果计算出的z值大于z缓冲区中的z值,则颜色缓冲区和z缓冲区保持不变。 z − b u ff e r z-buffer zbuer算法很简单,具有 O ( n ) O(n) O(n)复杂度(其中n是要渲染的图元的数量),并且适用于任何可以为每个(相关)像素计算z值的绘图图元。还要注意的是该算法允许大多数图元以任何顺序呈现,这是它常用的另一个原因。但是,z缓冲区在屏幕上的每个点仅存储一个深度,因此不能用于部分透明的图元。必须在所有不透明图元之后,以从后到前的顺序或使用单独的与顺序无关的算法(第5.5节)呈现这些内容。透明度是 z − b u ff e r z-buffer zbuer的主要弱点之一。

我们之前提到颜色缓冲存储颜色,深度缓冲存储每个像素的Z值。但是还有其他的通道和缓冲用来筛选和存储片元信息,alpha通道和颜色缓冲有关,并存储了每个像素有关的不透明度值。在旧的API中,alpha通道用于在之后的alpha 测试中选择性丢弃像素。如今丢弃的运算操作可以在像素着色器编程中进行,并且任何类型的计算都可以用来触发丢弃。这种类型的测试可以用来确保完全透明的片元不会影响Z-buffer。

模板缓冲是一个屏幕缓冲,用来记录渲染图元的位置。每个像素包含8位,可以使用各种功能将图元渲染到模板缓冲区中,缓冲中的值可以用来控制是否渲染进颜色缓冲和深度缓冲。例如,假设一个实心圆被渲染进模板缓冲,可以和允许在当前圆存在的位置的后续的图元才可以渲染进颜色缓冲的运算符结合。模板缓冲在生成某些特殊的效果十分有用,管线最后阶段的所有功能都称为栅格操作(ROP)或者混合运算。可以混合当前颜色缓冲中的颜色和三角形内部要处理的像素颜色。这可以产生透明的效果或颜色累积的效果。前面提到,混合阶段使用了API进行配置,并不是完全可编程的。但是,某些API支持栅格顺序视图,也称为像素着色器顺序,可启用可编程混合功能。

帧缓冲包含了系统上的所有缓冲区。

当图元到达并且通过了光栅化阶段,那些从摄像机角度看过去可见的图元都会展现在屏幕上。屏幕上展示的是颜色缓冲中的内容。为了避免人类观察者看到正在进行光栅化并且送往屏幕过程中的图元,使用了双缓冲。意思是在后置缓冲中进行场景的渲染,一旦场景渲染完毕,就将后置缓冲的内容和之前展示在屏幕上的前置缓冲的内容进行交换。交换通常发生在垂直回扫过程中,这是安全的时间。

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

2.6 通过管道

点,线和三角形是用于构建模型或对象的渲染图元。 想象一下,一个交互式计算机辅助设计(CAD)程序,并且用户正在检查制纸机的设计。 在这里,我们将看到此模型通过整个图形渲染管道,包括四个主要阶段:应用程序,几何处理,光栅化和像素处理。 通过透视将场景渲染到屏幕上的窗口中。 在这个简单的示例中,制纸机既包含线(显示零件的边缘)又包含三角形(显示表面)。 制纸机的盖子可以打开。 一些三角形是由带有制造商徽标的二维图像制成的。 对于此示例,除了在光栅化阶段发生的纹理应用之外,表面着色是在几何阶段完全计算出来的。

应用阶段

CAD应用允许用户选择移动模型的各个部分。例如,用户可能会选择盖子然后拖动鼠标打开它。应用阶段会把鼠标移动转换成相应的旋转矩阵,然后当渲染的时候这个矩阵就会应用到盖子身上,另一个例子:播放一个动画使相机颜色定义好的路线移动从不同视角观察制纸机。相机的参数,例如位置,视角方向,必须由应用随着时间进行更新,每一帧被渲染的时候,应用阶段就会将相机位置,光照,模型的图元传送到下一个阶段——几何阶段。

应用阶段

对于透视图,假设应用阶段提供了投影矩阵。同样对于每个物体,应用程序会计算一个矩阵用来描述视图转换,物体本身的位置和转向。例如,制纸机基座有一个矩阵,盖子也有一个。在几何阶段模型的顶点和法线用这个矩阵进行转换,把对象放进视图空间。然后利用材质和光源属性对顶点进行着色和其他的计算。投影使用用户提供的一个投影矩阵进行计算,把物体转换到代表眼睛所见的单位正方体。所有在正方体之外的图元都会被丢弃。与该单位正方体相交的所有图元都裁剪到正方体上,获得一组完全位于该单位正方体内的图元。然后将这些顶点映射到屏幕上的窗口中。在完成所有这些三角形和每个顶点操作之后,将所得数据传递到光栅化阶段。

光栅化

然后将所有在上一阶段裁剪后幸存的图元进行光栅化,意味着找到图元内部的所有像素,并将它们进一步发送到管道的下一个阶段以进行像素处理。

像素处理

这个阶段的目的是计算每个可见图元的每个像素的颜色。那些与任何纹理(图像)相关联的三角形将根据需要应用这些图像进行渲染。 通过z-buffer算法以及可选的丢弃和模版测试可以解决可见性问题。 依次处理每个对象,然后将最终图像显示在屏幕上。

总结

该管道源于针对实时渲染应用程序的数十年的API和图形硬件演变。要注意的是这不是唯一可能的渲染管道。整个渲染管道经历了不同的进化路径。电影制作的渲染通常是使用微多边形管道完成的,但是近来采用射线追踪和路径追踪。 11.2.2节中介绍的这些技术也可以用于建筑和设计的预可视化。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值