[ ![img](https://github.com/QianMo/Game-Programmer-Study-Notes/raw/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/title.jpg)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/title.jpg) # # 【《Real-Time Rendering 3rd》 提炼总结】(二) 第二章 · 图形渲染管线 The Graphics Rendering Pipeline 这篇文章是提炼总结计算机图形学界“九阴真经总纲”一般存在的《Real-Time Rendering 3rd》系列文章的第二篇。将带来RTR3第二章内容“Chapter 2 The Graphics Rendering Pipeline 图形渲染管线”的总结、概括与提炼。 文章分为全文内容思维导图、核心内容分章节提炼、本章内容提炼总结三个部分来呈现,其中: - 文章的第一部分,“全文内容思维导图”,分为“章节框架思维导图”和“知识结构思维导图”两个部分。 - 文章的第二部分,“核心内容分节提炼”,是按原书章节顺序分布的知识梳理。 - 而文章的第三部分“本章内容提炼总结”,则是更加精炼,只提炼出关键信息的知识总结。 ## ## 一、全文内容思维导图 ### ### 1.章节框架思维导图 [ ![img](Real-TimeRendering3rd_02.assets/0.png)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/0.png) ### ### 2.知识结构思维导图 [ ![img](Real-TimeRendering3rd_02.assets/1.png)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/1.png) ## ## 二、核心内容分节提炼 ### ### 2.1 图像渲染管线架构概述 Architecture 渲染管线的主要功能就是决定在给定虚拟相机、三维物体、光源、照明模式,以及纹理等诸多条件的情况下,生成或绘制一幅二维图像的过程。对于实时渲染来说,渲染管线就是基础。因此,我们可以说,渲染管线是实时渲染的底层工具。 图2.1展示了使用渲染管线步骤。渲染出的图像的位置、形状是由它们的几何形状,环境特性,摄像机位置决定的。而物体的外观由材质特性,光源,纹理和着色模型确定。 [ ![img](Real-TimeRendering3rd_02.assets/2.png)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/2.png) 原书图2.1 左图中,相机放在棱椎的顶端(四条线段的交汇点),只有可视体内部的图元会被渲染。 在概念上可以将图形渲染管线分为三个阶段: - 应用程序阶段(The Application Stage) - 几何阶段(The Geometry Stage) - 光栅化阶段(The Rasterizer Stage) 如下图: [ ![img](Real-TimeRendering3rd_02.assets/3.png)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/3.png) 原书图2.2 绘制管线的基本结构包括3个阶段:应用程序、几何、光栅化。 几个要点: - 每个阶段本身也可能是一条管线,如图中的几何阶段所示。此外,还可以对有的阶段进行全部或者部分的并行化处理,如图中的光栅化阶段。应用程序阶段虽然是一个单独的过程,但是依然可以对之进行管线化或者并行化处理。 - 最慢的管线阶段决定绘制速度,即图像的更新速度,这种速度一般用FPS来表示,也就是每秒绘制的图像数量,或者用Hz来表示。 ### ### 2.2 应用程序阶段 The Application Stage - 应用程序阶段一般是图形渲染管线概念上的第一个阶段。应用程序阶段是通过软件方式来实现的阶段,开发者能够对该阶段发生的情况进行完全控制,可以通过改变实现方法来改变实际性能。其他阶段,他们全部或者部分建立在硬件基础上,因此要改变实现过程会非常困难。 - 正因应用程序阶段是软件方式实现,因此不能像几何和光栅化阶段那样继续分为若干个子阶段。但为了提高性能,该阶段还是可以在几个并行处理器上同时执行。在CPU设计上,称这种形式为超标量体系(superscalar)结构,因为它可以在同一阶段同一时间做不同的几件事情。 - 应用程序阶段通常实现的方法有碰撞检测、加速算法、输入检测,动画,力反馈以及纹理动画,变换仿真、几何变形,以及一些不在其他阶段执行的计算,如层次视锥裁剪等加速算法就可以在这里实现。 - 应用程序阶段的主要任务:在应用程序阶段的末端,将需要在屏幕上(具体形式取决于具体输入设备)显示出来绘制的几何体(也就是绘制图元,rendering primitives,如点、线、矩形等)输入到绘制管线的下一个阶段。 - 对于被渲染的每一帧,应用程序阶段将摄像机位置,光照和模型的图元输出到管线的下一个主要阶段——几何阶段。 ### ### 2.3 几何阶段 The Geometry Stage 几何阶段主要负责大部分多边形操作和顶点操作。可以将这个阶段进一步划分成如下几个功能阶段: - 模型视点变换 Model & View Transform - 顶点着色 Vertex Shading - 投影 Projection - 裁剪 Clipping - 屏幕映射 Screen Mapping 如图2.3所示。 [ ![img](Real-TimeRendering3rd_02.assets/4.png)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/4.png) 原书图2.3 几何阶段细分为的功能阶段管线 需要注意: - 根据具体实现,这些阶段可以和管线阶段等同,也可以不等同。在一些情况下,一系列连续的功能阶段可以形成单个管线阶段(和其他管线阶段并行运行)。在另外情况下,一个功能阶段可以划分成其他更细小的管线阶段。 - 几何阶段执行的是计算量非常高的任务,在只有一个光源的情况下,每个顶点大约需要100次左右的精确的浮点运算操作。 #### #### 2.3.1 模型和视图变换 Model and View Transform - 在屏幕上的显示过程中,模型通常需要变换到若干不同的空间或坐标系中。模型变换的变换对象一般是模型的顶点和法线。物体的坐标称为模型坐标。世界空间是唯一的,所有的模型经过变换后都位于同一个空间中。 - 不难理解,应该仅对相机(或者视点)可以看到的模型进行绘制。而相机在世界空间中有一个位置方向,用来放置和校准相机。 - 为了便于投影和裁剪,必须对相机和所有的模型进行视点变换。变换的目的就是要把相机放在原点,然后进行视点校准,使其朝向Z轴负方向,y轴指向上方,x轴指向右边。在视点变换后,实际位置和方向就依赖于当前的API。我们称上述空间为相机空间或者观察空间。 下图显示了视点变换对相机和模型的影响。 [ ![img](Real-TimeRendering3rd_02.assets/5.png)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/5.png) 原书图2.4 在左图中,摄像机根据用户指定的位置进行放置和定位。在右图中,视点变换从原点沿着Z轴负方向对相机重新定位,这样可以使裁剪和投影操作更简单、更快速。可视范围是一个平截椎体,因此可以认为它是透视模式。 【总结】模型和视图变换阶段分为模型变换和视图变换。模型变换的目的是将模型变换到适合渲染的空间当中,而视图变换的目的是将摄像机放置于坐标原点,方便后续步骤的操作。 #### #### 2.3.2 顶点着色 Vertex Shading 为了产生逼真的场景,渲染形状和位置是远远不够的,我们需要对物体的外观进行建模。而物体经过建模,会得到对包括每个对象的材质,以及照射在对象上的任何光源的效果在内的一些描述。且光照和材质可以用任意数量的方式,从简单的颜色描述到复杂的物理描述来模拟。 确定材质上的光照效果的这种操作被称为着色(shading),着色过程涉及在对象上的各个点处计算着色方程(shading equation)。通常,这些计算中的一些在几何阶段期间在模型的顶点上执行(vertex shading),而其他计算可以在每像素光栅化(per-pixel rasterization)期间执行。可以在每个顶点处存储各种材料数据,诸如点的位置,法线,颜色或计算着色方程所需的任何其它数字信息。顶点着色的结果(其可以是颜色,向量,纹理坐标或任何其他种类的阴着色数据)计算完成后,会被发送到光栅化阶段以进行插值操作。 通常,着色计算通常认为是在世界空间中进行的。在实践中,有时需要将相关实体(诸如相机和光源)转换到一些其它空间(诸如模型或观察空间)并在那里执行计算,也可以得到正确的结果。 这是因为如果着色过程中所有的实体变换到了相同的空间,着色计算中需要的诸如光源,相机和模型之间的相对关系是不会变的。 【总结】顶点着色阶段的目的在于确定模型上顶点处材质的光照效果。 #### #### 2.3.3 投影 Projection 在光照处理之后,渲染系统就开始进行投影操作,即将视体变换到一个对角顶点分别是(-1,-1,-1)和(1,1,1)单位立方体(unit cube)内,这个单位立方体通常也被称为规范立方体(Canonical View Volume,CVV)。 目前,主要有两种投影方法,即: - 正交投影(orthographic projection,或称parallel projection)。 - 透视投影(perspective projection)。 如下图所示。 [ ![img](https://github.com/QianMo/Game-Programmer-Study-Notes/raw/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/6.png)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/6.png) 原书图2.5 左边为正交投影,右边为透视投影 两种投影方式的主要异同点: - 正交投影。正交投影的可视体通常是一个矩形,正交投影可以把这个视体变换为单位立方体。正交投影的主要特性是平行线在变换之后彼此之间仍然保持平行,这种变换是平移与缩放的组合。 - 透视投影。相比之下,透视投影比正交投影复杂一些。在这种投影中,越远离摄像机的物体,它在投影后看起来越小。更进一步来说,平行线将在地平线处会聚。透视投影的变换其实就是模拟人类感知物体的方式。 - 正交投影和透视投影都可以通过4 x 4的矩阵来实现,在任何一种变换之后,都可以认为模型位于归一化处理之后的设备坐标系中。 虽然这些矩阵变换是从一个可视体变换到另一个,但它们仍被称为投影,因为在完成显示后,Z坐标将不会再保存于的得到的投影图片中。通过这样的投影方法,就将模型从三维空间投影到了二维的空间中。 【总结】投影阶段就是将模型从三维空间投射到了二维的空间中的过程。 #### #### 2.3.4 裁剪 Clipping 只有当图元完全或部分存在于视体(也就是上文的规范立方体,CVV)内部的时候,才需要将其发送到光栅化阶段,这个阶段可以把这些图元在屏幕上绘制出来。 不难理解,一个图元相对视体内部的位置,分为三种情况:完全位于内部、完全位于外部、部分位于内部。所以就要分情况进行处理: - 当图元完全位于视体内部,那么它可以直接进行下一个阶段。 - 当图元完全位于视体外部,不会进入下一个阶段,可直接丢弃,因为它们无需进行渲染。 - 当图元部分位于视体内部,则需要对那些部分位于视体内的图元进行裁剪处理。 对部分位于视体内部的图元进行裁剪操作,这就是裁剪过程存在的意义。裁剪过程见下图。 [ ![img](Real-TimeRendering3rd_02.assets/7.png)](https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AReal-TimeRendering3rd%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/Content/BlogPost02/media/7.png) 原书图2.6 投影变换后,只对单位立方体内的图元(相应的是视锥内可见图元)继续进行处理,因此,将单位立方体之外的图元剔除掉,保留单位立方体内部的图元,同时沿着单位立方体将与单位立方体相交的图元裁剪掉,因此,就会产生新的图元,同时舍弃旧的图元。 【总结】裁剪阶段的目的,就是对部分位于视体内部的图元进行裁剪操作。 #### #### 2.3.5 屏幕映射 Screen Mapping 只有在视体内部经过裁剪的图元,以及之前完全位于视体内部的图元,才可以进入到屏幕映射阶段。进入到这个阶段时,坐标仍然是三维的(但显示状态在经过投影阶段后已经成了二维),每个图元的x和y坐标变换到了屏幕坐标系中,屏幕坐标系连同z坐标一起称为窗口坐标系。 假定在一个窗口里对场景进行绘制,窗口的最小坐标为(x1,y1),最大坐标为(x2,y2),其中x1