[toc]

# 颜色

DirectXMath 库使用 SIMD 技术加快数据的处理速度。

  • 32 位颜色 (RGBA 各 1 个字节), PackedVector::XMLoadColor (COLOR 转换为 VECTOR), PackedVector::XMStoreColor (VECTOR 转换为 Color)

# 渲染流水线概述

在输出合并阶段,数据会被写到像后台缓冲区这样的纹理当中。
事实上,输出合并阶段是 CPU 和 GPU 双向的

# 输入装配阶段

输入装配阶段从显存中读取几何数据,然后装配成三角 / 线段图元 DX12 可以将 顶点缓冲区 处理成如下几种拓扑形式 另外,DX12 可以通过使用 6 个顶点来描述与它相邻的三个三角形

# 索引

即每三个整型代表一个三角形在顶点数组的下标

# 顶点着色器阶段

可以理解为对每个顶点执行下述处理 (GPU 进行)

1
2
for(UINT i = 0;i<numVertices;++i)
outputVertex[i] = VertexShader(inputVertex[i]);

# 局部空间和世界空间

世界变换

将物体的每个局部坐标从局部空间转换到世界空间的过程叫 世界变换 ,矩阵称之为 世界矩阵(word matrix)

构建世界矩阵需要计算局部物体相对于世界的 旋转缩放位移 ,在 DX12 中记为 SRT

# 观察空间

实际的顶点最终会渲染至观察坐标系中,这一步会将顶点从 世界空间 转换到 观察空间 ,所以只需要一个矩阵即可 由于我们知道摄像机在世界空间的旋转,缩放和平移,所以我们可以通过求逆来获取世界空间到摄像空间的矩阵 通过世界坐标原点的 up 向量和摄像机观察的中心点 (世界坐标) 到摄像机位置的向量可以确定摄像机的 xyz 轴向量 观察矩阵如上,其中 Q 为摄像机位置, uvw 为摄像机三轴向量 这个矩阵被称为 LookAt 矩阵,在 DX12 中使用 XMMatrixLookAtLH(pos,target,up) 可以计算得来

# 投影和齐次裁剪

变换的最后一步是将平截头体内的 3D 物体投影到 2D 投影窗口之中

# 归一化深度值

投影操作结束后,所有的投影点都会位于 2D 投影窗口上,为了实现画家算法,我们会保留 z 坐标作为深度值,主要方式是,将近平面映射为 z=0, 远平面映射为 z=1, 设 (N,F) 分别为近平面和远平面深度,z 值即为:
为了防止因为计算深度值产生的浮点误差问题,通常建议近平面与远平面尽量接近

# 曲面细分阶段

dx11 以后,可以在 GPU 阶段进行曲面细分 (即添加顶点和索引)。

# 几何着色器阶段

几何着色器中要求输入的是完整的图元,可以在这个阶段中丢弃图元或者创建图元

# 裁剪

在视锥体阶段,需要进行几何图元的裁剪 裁剪操作是由硬件负责的 DX12 书中推荐了一个裁剪算法
Sutherland-Hodgman clipping algorithm 由于裁剪之后,几何图形不再是三角形,所以还需要进行三角化 (也是硬件,对于凸多边形,比较容易实现,如果是凹多边形,则需要耳朵法进行处理)

# 光栅化阶段

背面剔除 (不渲染背面的三角形)

d3d 可以切换正面。背面的设置

顶点属性插值

一般使用重心坐标进行透视矫正插值,重心坐标发前面有提到过 (目前也是硬件插值)

# 像素着色器阶段

根据前述得到的各种信息进入这一阶段,实际上在其他语言中被称为: 片元

# 输出合并阶段

通过像素着色器生成的像素片段会被移送到渲染流水线的输出合并阶段,即 在这个阶段中进行颜色混合,透明度混合等 ,但是要注意的一点是,有些片元会在这个阶段之前被透明度测试和模板测试丢弃掉,剩下的像素片段会被写入后台缓冲区,同时进行混合