渲染管线导论(龙书笔记)

发布时间 2023-05-26 16:05:36作者: 阿初

渲染管线

总体流程

Input Assembler(IA) -> VS Shader(VS) -> Hull Shader(HS) -> Tessellator Stage -> Domain Shader(DS) -> Geometry Shader(GS) -> [Stream Output(SO)] -> Rasterizer(RS) -> Pixel Shader(PS) -> Output Merget(OM)
输入(图元)装配 -> 顶点着色器 -> 外壳着色器阶段 -> 曲面细分阶段 -> 域着色器 -> 几何着色器 -> 流输出 -> 光栅化阶段 -> 像素着色器 -> 输出合并

裁剪阶段发生在VS之后,RS之前。顺序是视椎体裁剪 -> 视口剔除 -> 背面剔除。

片元和图元的一些概念

按照顺序排列:顶点 -> 图元 -> 片元 -> 像素。

图元是顶点组成的,一个顶点,一个线段,一个三角形或多边形都可以是图元。

片元是图元经过光栅化的产物,被分割成一个个像素大小的基本单位,但它不是像素!
片元是包含了各种信息的集合(比如屏幕坐标,深度,法线,纹理等信息),片元经过一些测试(比如深度测试)后才能成为像素。
可能会有多个片元竞争同一个像素,经过测试后筛选出一个合适的片元,丢弃法线和纹理坐标等不需要的信息后才能成为像素。

输入(图元)装配

从内存中读取几何数据,一般是顶点和索引,并将数据组合成几何图元(三角形或直线)。

图元拓扑

图元拓扑告诉D3D定点列表如何组织成三角形,三角形的线怎么连接。

  1. 点列表 D3D11_PRIMITIVE_TOPOLOGY_POINTLIST
    点的集合,每个点都是独立的点,不连接。

  2. 线带 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP 和线列表 D3D11_PRIMITIVE_TOPOLOGY_LINELIST
    线的集合,线带n+1个顶点可以形成n条直线。而线列表则是每2个顶点形成一条独立的直线,直线和直线之间不连接,2n个顶点形成n条直线。

  3. 三角形带 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP 和三角形列表 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
    三角形列表会每3个定点组成一个独立的三角形,三角形带也是同样。区别是三角形列表中的三角形是分开的,三角形带是自动连在一起。
    如果使用三角形带,n个顶点可以形成n-2个三角形。

  4. 带有邻接信息的图元 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ
    每个三角形有与之相邻的3个邻接三角形,共6个顶点组成4个三角形。
    主要用于几何着色器,因为某些几何着色算法需要访问邻接三角形。邻接三角形必须通过原三角形通过顶点/索引缓冲区提交给管线。
    邻接三角形只能做和几何着色器的输入数据。

索引

索引指的是顶点列表的索引,运用索引可以减小内存的需求量(索引只是整数),减小图形硬件的处理负担(不用多次处理相同的顶点数据)。

顶点着色器

顶点着色器可以视为将顶点作为输入输出数据的函数,每个需要绘制的顶点都会通过顶点着色器送至硬件。
顶点着色器可以实现许多效果,比如顶点变换,光照和置换贴图映射。

顶点着色器还能访问内存中纹理和其他数据,比如变换矩阵和场景灯光。

局部坐标系和世界坐标系

局部坐标系:局部空间
世界坐标系:世界空间(全局空间)

模型会先定义在局部空间内(比如自己的空间),而后添加到整体城建内,局部坐标系就会转换成世界坐标系称,也称为世界变化,相应的矩阵称为世界矩阵。

当有多次绘制相同的物体时,可以只改变在世界空间中的位置方向和大小,不用多次复制物体数据(instancing)。

观察坐标系(观察空间)

摄像机所在的坐标系
虚拟摄像机指定了观察者可以看到的范围,或者说是生成的2D图像所显示的场景范围。
观察坐标系指定了摄像机的位置和方向。

从世界空间到观察空间的坐标转换称为观察转换,相应的矩阵称为观察矩阵。

投影与齐次裁剪空间

能看到的视锥体内容
摄像机可以看到的空间范围。目的是为了不去渲染视锥体之外的内容(剔除)。
从观察空间转换至裁剪空间,相应的矩阵被称为投影矩阵。
摄像机是一个椎体,所以

曲面细分阶段

曲面细分是指通过添加三角形的方式对一个网格的三角形进行细分,这些新添加的三角形可以偏移到新的位置,让网格细节更加丰富。

优点

  1. 曲面细分可以做LOD。
    靠近相机的三角形通过细分产生更多细节,远离相机的三角形则保持不变。
  2. 可以保存一个低细节的(三角形少)网格,实时动态的额外添加三角形,但是这样计算量会上升。
  3. 在一个低细节网格上处理动画和物理效果,而只在渲染时才使用细分过的高细节网格。

曲面细分阶段是D3D11中的,D3D11之前都是在CPU中计算,之后就移到GPU中了。

几何着色阶段

顶点格式中的带有邻接信息的图元就是在这个阶段。

几何着色器以完整的图元作为输入数据(比如三角形的三个点)。
几何着色器主要优势是可以创建或者销毁几何体。通常用于一个点扩展为一个四边形,或者将一条线扩展为四边形。

与顶点着色器的不同:顶点着色器无法创建顶点,只要输入一个顶点,那么就必须输出一个顶点。

裁剪阶段

裁减掉视锥体之外的几何体。

光栅化阶段

为投影后的3D三角形计算像素颜色。

视口变化

在裁剪之后,硬件会自动执行透视除法,从齐次裁剪空间变换到规范化设备空间。构成2D图像的2Dx, y坐标变换到后台缓冲区的一个被称为视口的矩形区域内。
(变成显示器后台缓冲区的坐标,坐标单位变成像素px)

图元遍历

这个过程将检验屏幕上某个像素是否被一个三角形网格覆盖,被覆盖的区域会生成一个片元。
片元会用于最终计算每个像素的颜色。

可以理解为这一阶段是将三角形如何转换成屏幕中的像素的,会占用哪些像素。

背面消隐

按照计算三角形发现的方式,按顺时针方向环绕的三角形是朝向的,反之朝后。

因为3D空间中的大部分物体都是封闭实心的物体,当每个三角形的方向指向物体外侧时,朝前的三角形挡住了朝后的三角形,所以绘制后面(看不见)的面是无意义的。
背面消隐就是让管线放弃朝后三角形的处理,这样可以将所要处理的三角形的数量降低到原数量的一半。

当以透明方式绘制立方体时,如果不做背面消隐可以看到6个面,但是开启之后,就看到3个面。
更改背面消隐的方向,可以让效果颠倒(只渲染前面/后面)。

像素着色器

PS Shader输入是插值后的顶点属性,由此计算出一个颜色。可以实现逐像素光照,反射或阴影等效果。

输出合并阶段

像素片段生成之后,在这个阶段,一些像素片段会被丢弃(alpha测试),未丢弃的像素会被写入后台的缓冲区。

这一阶段也可能会发生混合,一个像素可以与后台缓冲区的当前像素进行混合来确认最终颜色,比如可以实现透明效果。