nicetry12138 1 год назад
Родитель
Сommit
0cf03e8fff

BIN
图形学/DirectX学习/Image/014.png


BIN
图形学/DirectX学习/Image/015.png


BIN
图形学/DirectX学习/Image/016.png


BIN
图形学/DirectX学习/Image/017.png


BIN
图形学/DirectX学习/Image/018.png


BIN
图形学/DirectX学习/Image/019.png


BIN
图形学/DirectX学习/Image/020.png


BIN
图形学/DirectX学习/Image/021.png


BIN
图形学/DirectX学习/Image/022.png


+ 129 - 0
图形学/DirectX学习/README.md

@@ -1048,3 +1048,132 @@ int D3DApp::Run()
 }
 ```
 
+### 渲染流水线
+
+![](Image/014.png)
+
+#### 输入装配器阶段
+
+输入装配器(`Input Assembler`, IA) 阶段会从现存中读取几何数据(顶点和索引, `Vertex And Index`),再将他们装配为几何图元(`geometric primitive`,如三角形和线条这种构成图形的基本元素)
+
+在 `Direct3D` 中通过 `Vertex Buffer` 的特殊数据结构将顶点与渲染流水线绑定
+
+`Vertext Buffer` 利用连续的内存来存储一系列顶点
+
+除了顶点之外,还需要指定**图元拓扑**(`primitive topology`)来告知如何用顶点数据来表示几何图元
+
+```cpp
+mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+```
+
+上述代码就是在设置**图元拓扑**类型,枚举类型为: `D3D_PRIMITIVE_TOPOLOGY`,枚举值有点多,在[官方文档](https://learn.microsoft.com/zh-cn/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_primitive_topology)中有详细说明
+
+```cpp
+D3D_PRIMITIVE_TOPOLOGY_POINTLIST,		// 将顶点数据解释为点列表
+D3D_PRIMITIVE_TOPOLOGY_LINELIST,		// 将顶点数据解释为线条列表
+D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,		// 将顶点数据解释为线条带
+D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,	// 将顶点数据解释为三角形带
+// ....
+```
+
+| 点列表 | 线条列表 | 线条带 | 三角形条带 |
+| --- | --- | --- | --- |
+| ![](Image/015.png) | ![](Image/017.png) | ![](Image/016.png) | ![](Image/018.png) |
+
+可以通过顶点坐标构成各种图形,但是有一个问题,那就是数据冗余的问题,以下图纹理
+
+![](Image/019.png)
+
+```cpp
+Vertex quad[6] = {
+	v0, v1, v2,	// 三角形1
+	v0, v2, v3,	// 三角形2
+}
+```
+
+通过 `quad` 数组可以获得俩个三角形拼成的四边形,但是两个三角形中有两个数据(v0, v2)冗余了
+
+顶点中除了坐标信息,还可以存储颜色、法线等信息,这就意味着内存的浪费,为了处理这个冗余的问题,于是采用**索引**的方式来记录图元的顶点信息
+
+```cpp
+Vertex v[4] = {v0, v1, v2, v3};
+UINT indexList[6] = {
+	0, 1, 2,	// 三角形1
+	0, 2, 3,	// 三角形2
+}
+```
+
+让图元的顶点信息通过索引获得, 这样顶点信息就没有冗余
+
+#### 顶点着色器阶段
+
+图元装配完毕之后,其顶点就会被送入**顶点着色器**阶段
+
+可以把顶点主送二七看作一种输入与输出皆为单个顶点的函数。每个要被绘制的顶点都须经过顶点着色器的处理,再送往后续阶段
+
+```cpp
+for(UINT i = 0; i < numVertices; ++i) {
+	outputVertex[i] = VertexShader(inputVertex[i]);
+}
+```
+
+> 顶点着色器函数就是 `VertexShader` 要实现的部分
+
+通过顶点着色器可以实现变换、光照、位移贴图等特效。顶点着色器也可以访问顶点数据、纹理和其他存于显存中的数据(如变换矩阵、光照信息等)
+
+#### 曲面细分阶段
+
+曲面细分阶段利用镶嵌化处理技术对网格中的三角形进行细分,以此来增加物体表面上的三角形数量。再将新增的三角形偏移到适当的位置,是网格表现出更加细腻的细节
+
+![](Image/020.png)
+
+1. 可以实现细节层次机制(`Level-of-Detail`, `LOG`),即离虚拟相机近的三角形镶嵌化处理得到更丰富的细节,离相机远的三角形不进行任何更改
+2. 内存中只需要维护简单的**低模**网格,再根据需要动态增添额外三角形面
+3. 处理动画和物理模拟时采用简单的低模网格,仅在渲染的过程中使用经镶嵌化处理的高模网格
+
+#### 几何着色器
+
+几何着色器接受的输入应该是完整的图元,例如正在绘制三角形列表,那么几何着色器传入的将是定义三角形的三个顶点
+
+几何着色器可以创建或者销毁几何体,可以利用几何着色器将输入的图元拓展为一个或者多个其他图元
+
+#### 裁剪
+
+位于视锥体之外的几何体需要被丢弃,而处于平截头体交界意外的几何部分也一定要接受被裁剪的操作。因此只有在平截头体之内的物体对象才能最终保留下来
+
+![](Image/021.png)
+
+> 顶视图
+
+#### 光栅化
+
+光栅化阶段(rasterization stage, RS),也称栅格化、像素化,主要是为投影主屏幕上的3D三角形计算出对应的颜色
+
+当裁剪操作完成之后,硬件会通过透视除法将物体从齐次裁剪空间变换为规格化设备坐标(NDC)。一旦物体的顶点位于 NDC 空间内,构成 2D 图像的 2D 顶点 x、y 坐标就会被变换到后台缓冲区称为视口的矩形里。这些 x、y 坐标都将以像素为单位,z坐标通常用作深度值
+
+每个三角形都有两个面,假设三角形的顶点顺序为 v0,v1,v2
+
+一般规定如果顶点绕序为顺时针的三角形为正面朝向,而顶点绕序为逆时针的三角形为背面朝向,摄像机将看不到实体对象中背面朝向的三角形,**背面剔除**就是用于将背面朝向的三角形从渲染流水线中除去的处理流程
+
+`Direct3D` 可以通过设置将顺时针为正面的规则倒过来
+
+#### 顶点属性插值
+
+顶点除了位置信息外还有颜色、法向量、纹理坐标等属性
+
+经过视口变换之后,需要为求取三角形内所有像素所附的属性而进行插值运算
+
+除了顶点属性,还需要对顶点的深度进行插值,继而得到每个像素参与实现深度缓冲的深度值
+
+为了得到屏幕空间中各个顶点的插值属性,往往要通过一种名为**透视矫正插值**的方法,对3D空间中三角形的属性进行线性插值
+
+#### 像素着色器阶段
+
+也称片段着色器
+
+pixel shader PS 是一个中由 GPU 来执行的程序。它会针对每一个像素片段进行处理,并根据顶点的插值属性作为输入来计算出对应的像素颜色
+
+像素着色器既可以直接返回一种单一的恒定颜色,也可以实现如逐像素光照、反射、以及阴影扽给更为复杂的效果
+
+### 绘制几何体
+