深度探索DxFramework 10-2
请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com
第10章 进入三维的世界 2 10.4 Direct3D的渲染流水线 10.4.1.渲染流水线的体系架构和速度 渲染流水线的主要功能就是,在给定如三维的物体、摄像机、光源、光照模式、纹理等条件下,如何在显示器屏幕或者是其他输出设备中生成绘制一幅二维的图像。和现实生活中的流水线,比如工厂的装配线类似,渲染流水线也可以分为多个“阶段”(stage)。就是指在整个渲染过程中,执行了其中一部分功能的一个过程。如果各个阶段是以并行的方式运行的话,那么流水线整体的快慢程度是由流水线中最慢的那个阶段所决定的。在实时计算机图形学中,渲染流水线可以在概念上将其大约分成三个阶段:应用程序阶段、几何阶段和光栅化阶段。每个阶段有可以看成是一个比较细的流水线,可以由其他阶段组成,而且这些个子阶段有些是可以并行运行的,如下图:
最慢的流水线阶段决定了绘制速度,即图像更新速度,这个速度一般用fps(frame per second)表示。也就是每秒绘制的图像数。在这里请注意,在渲染流水线中,绘制一帧所需的时间,不能简单地对数据通过各阶段所花费的时间做一个简单的相加。而是只需要找到最慢的阶段的速度,就是能得到整个阶段的绘制速度。这也就是渲染流水线的特性。在此举一个例子来说明:
假定某个输出设备(比如是显示器)的绘制速度最高是60fps,整个流水线中最费时的阶段为50毫秒每帧。那么每绘制一帧。在先不考虑输出设备的情况下,流水线能提供的最高渲染速度为1/0.05=50fps。接着可以把这个值调整为输出设备的频率。输出设备最高的可以是60fps,那么也就是说,输出设备的所能调整到的、小于或者等于50fps的绘制速度,就是整个流水线的最大绘制速度。
如其名字,应用程序阶段是由使用渲染流水线的应用程序来驱动的。可以通过软件实现之。比如在这一阶段,可以计算物体的碰撞检测,力反馈等物理仿真运算。(在本书写作之际,物理加速卡已经开始进入实际应用阶段,在往后发展中这部分阶段也可以用硬件完成。)接着的就是几何阶段,在这阶段中实现对三维物体的变换、投影、光照等处理,可以用软件或者硬件实现。这阶段的主要内容是计算绘制的内容、如何绘制、何处绘制等等。最后,光栅化阶段是利用了前面阶段产生的数据进行图像绘制。
10.4.2.渲染流水线的应用程序阶段 应用程序阶段在几何阶段之前。在这一阶段的功能就是把要渲染的几何体输入到几何阶段。在应用程序阶段,通常实现了物体之间的碰撞检测。此外,应用程序也是检查其他输入信息的地方,比如鼠标,键盘,各种各样的虚拟现实设备的输入信息。在这一阶段中还实现了一些不在其他阶段执行的计算。
10.4.3.渲染流水线的几何阶段 几何阶段主要负责了大部分的顶点和几何操作。几何阶段可以划分成如下几个子阶段。在一些情况下。一些子阶段是可以并行运行的。几何阶段可以进一步划分成如下图的几个子阶段。
在极端情况下,渲染流水线中所有的阶段都可以用软件来实现。但是值得注意的是,几何阶段执行的是计算量非常高的任务。正因为如此,现代显卡把几何阶段所需完成的很多功能都用硬件实现了。
10.4.4.模型和观察变换 在往屏幕显示的物体过程中,表征物体的模型往往是需要变换到一些不同的坐标系统中去。最开始物体是处于它自身的模型空间里,这个模型可以认为它没有进行任何的变换。对模型进行模型变换,便可指定它在所处场景中的位置(position)和朝向(orientation)。同一模型可以和多个模型变换联系在一起,允许同一个模型有多个副本。这样子可以使得同一模型在同一场景中有多个不同的位置朝向。而不需要对这模型做复制操作。模型变换的变换对象是模型的顶点和法线。如果将模型应用模型变换之后,所有的模型都将处于同一世界中。这时候可称为此模型处于世界空间或者是世界坐标中。世界空间是唯一的,所有的模型经模型变换后都处于同一个世界。
在实际绘制中,只有能被摄像机观察到的模型才进行绘制。相机在世界坐标中有位置和三个相互正交的朝向,用来对相机自身进行定位。为了便于裁剪和投影,在完成模型变换之后,必须对所有的模型进行变换。变换到以相机坐标为原点。以其三个相互正交的朝向方向为坐标轴方向的空间中去,这个空间便称为观察空间。
10.4.5.光照和着色计算 为了使得渲染结果更加真实,可以给场景配上一个或多个光源。同时还可以选择是否使用灯光影响几何体的外观。几何模型可以给其每个顶点指定相关联的颜色,或者是覆盖上一副图像(就是所谓的纹理,后面章节将详细介绍)。对于存在着灯光的场景来说,可以用光照方程计算模型上每一个顶点的颜色,这个方程近似地模拟了光子和物体表面之间的实际作用。在现实世界中,光源发出光子,然后被表面反射或者是吸收。在实时计算机图形学中,是没有过多的时间来模拟这种现象的。因此,这些简单的光照方程并没有包含着非常真实的反射和阴影。此外,模型在图形上通常是以三角形来表示。目前大部分的图形硬件也都是采用三角形为基本渲染图元(primitive)。物体表面每个顶点的颜色可由光源及其自身的顶点位置和法线、顶点所在的材质等属性来计算。当在屏幕中绘制三角形的时候,可以通过对三角形的顶点进行插值运算。为了模拟更加高级真实的光照效果,可以采用像素着色技术。
一般地,光照计算是在世界空间中进行的。但是如果在对物体模型做观察变换的同时也把光源变换到观察空间中去的话,其光照效果将会是一样的。因为这时候,光源,摄像机,和物体模型之间的相对位置依然保持不变。
10.4.6.投影变换 完成光照处理之后,渲染流水线开始进行投影,目的就是为了将视体变换成为一个单位立方体。这个立方体的对角顶点分别为(-1,-1,-1)和(1,1,1)。通常地也称为单位立方体为规范化视体(canonical view volume)。现在主要有两种投影方法:正交投影(orthogonal projection)和透视投影(perspective projection)。
正交投影的视截体通常是一个矩形的盒子,正交投影就是把这个视体变换成为单位立方体。正投影的主要特性就是平行线在变换之后彼此之间仍然能保持平行。这种变换是平移和缩放的组合。相比之下,透视投影要复杂一些。在透视投影中,物体的投影后大小遵循“近大远小”的原则。即物体离相机越远,投影之后将会变得越小;平行线在地平线处可以相交。从几何上而言,透视投影的视截体可以称为视锥,即一个以矩形为底面的,顶部被截掉的金字塔。同样的视锥也可以通过透视投影变换成一个单位立方体。经过投影变换后,图像的Z坐标信息将不存在(存储在Z缓冲区中了),这种投影变换将模型从三维投影到二维。
10.4.7.裁剪 只有当模型部分或者完全地存在于视体内部的时候,才需要将其发送到光栅化阶段绘制出来。如果一个图元完全地位于一个视截体内部的时候,可以直接将其送入下一阶段。完全不在视截体内部的模型,可以完全不将其送入下一阶段。对那些只有部分在视截体内部的模型,则需要对其进行裁剪。例如:当一条线段的一个端点在视截体内部而另一端点在外部的时候,就需要根据视截体对该线段进行裁剪。位于视截体外部的端点将被新的端点所代替,新的端点是线段和视截体的交点。投影变换之后的模型只对单位立方体进行裁剪。在裁剪之前进行观察变换和投影变换的优势就在于可以使得裁剪方法和问题比较一致。除了视截体的6个平面之外,用户可以自定义裁剪平面来进行裁剪操作。
10.4.8.屏幕映射 在视截体内部经过裁剪了的图元才能进入屏幕映射阶段。进入此阶段。坐标仍然三维的,每个图元的x坐标和y坐标都将变换到屏幕坐标系上。屏幕坐标系连同z坐标一起称为窗口坐标系。假定一个窗口里对场景进行了绘制,窗口的左下角坐标为(x1,y1),右上角坐标为(x2,y2)。其中x1<X2,y1<y2。屏幕映射首先进行平移,然后进行缩放。在映射过程中z坐标不受影响。新的x和y坐标系称为屏幕坐标系,与z坐标一起(-1≤z≤1)进入光栅阶段。
10.4.9.光栅化阶段 给定来自几何阶段,经过变换投影之后的顶点、颜色和纹理坐标。光栅阶段的目的就是给每个像素(pixel,picture element的所写)指定正确的颜色,以便于正确绘制整幅图像。这个过程称为光栅化或者是扫描转换,也就是说把屏幕空间中的二维顶点转化为屏幕上的像素。屏幕空间中,每个顶点右一个z值(通常称之为深度值)、一种或者两种颜色、以及一组或者多组纹理坐标。其中纹理坐标将会和顶点或者是屏幕上的像素联系在一起。
在几何阶段中,渲染流水线操作的对象是一些多边形。而在光栅化阶段中,是对像素进行操作。每个像素的信息存储在颜色缓冲器(color buffer)里。颜色缓冲器是一个矩形的颜色序列。每种颜色都含有红色,绿色,蓝色三种分量。
为了避免在绘制时产生撕裂现象,图形系统一般都使用双重缓冲机制。也就是说:渲染流水线首先在后台缓冲区(back buffer)中绘制好要绘制的内容,然后切换到前台缓冲区(front buffer)中。如此不断地绘制,切换。
光栅化阶段还负责可见性问题。这也就是意味着当绘制完整个场景之后,颜色缓冲区将包含从摄像机观察点从可以观察得到的图元。大部分的图形硬件通过Z缓冲器来解决可见性问题。Z缓冲器和颜色缓冲器的大小形状是一样的。每个像素都存储着一个Z值。这个Z值是从摄像机到最近图元的距离。当将某图元绘制成像素的时候,就要把同一像素位置处的图元Z值和同一像素的Z缓冲器的内容进行比较。如果新得到的Z值小于Z缓冲器的Z值,则说明将要绘制的图元与摄像机的距离比原来距离相机最近的图元还要近。这样子,像素的Z值和颜色值就由当前图元所对应的值来更新。反之,则保持不变。
因为Z缓冲区对每次将要绘制在同一像素位置上的图元都要进行比较操作,所以使用了Z缓冲区算法,对于不透明的像素绘制顺序是任意的。对于部分透明的像素而言则不能任意顺序绘制。必须在绘制所有非透明像素之后进行。而且必须从后到前的顺序进行。
在三维场景的绘制中,纹理是一种能够提高真实感的有效技术。简单而言,对某一物体进行纹理贴图就是指把一幅图像贴到该物体表面上。纹理图像可以是一维,二维,或者是三维。其中二维图像最为普遍。目标物体可以是一系列连在一起的三角形,也可能是一些四边形,球体,圆柱体等等。
颜色缓冲区用来存储像素的颜色。Z缓冲区用来存储每个像素的Z值。还能使用其他的缓冲器来产生一些特殊的图像效果。使用alpha通道和颜色缓冲器联系在一起可以存储一个与每个像素相关的不透明值。从而使得图像产生一些半透明的效果。
帧缓冲器(frame buffer)通常包含一个系统中所具有的所有缓冲器。还有一种缓冲器称为累积缓冲器(acceleration buffer)。在这个缓冲器中可以用一组操作符对图像进行累积。例如为了产生运动模糊。可以对一系列表示运动的图像进行累积和平均。图元发送到并通过光栅化阶段后。从相机视点能看到的东西就可以在屏幕中显示出来了。
10.4.10 Direct3D的渲染流水线架构