顶点定义
当我们用顶点去定义几何图元时,我们可能用两个顶点去表达一条线,或者三个顶点去表达一个三角形。那么D3D是如何去理解我们给定的N个点的信息呢?
Primitive Topology
一个顶点的集合被称为vertex buffer,他仅仅储存了一个顶点列表在一个连续的内存空间中。当我们需要D3D去组合这个几何图元时,我们需要告诉他顶点的几何拓扑信息。利用void ID3D12GraphicsCommandList::IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY Topology);
enum D3D_PRIMITIVE_TOPOLOGY
定义了一些例如线,三角等原始拓扑信息。我们提供列表时,利用上一次的设置。直到我们再次调用接口改变了这个信息。
- Point List:
D3D_PRIMITIVE_TOPOLOGY_POINTLIST
当设置为此时,每一个列表中的顶点都被画为独立的点。 - Line Strip:每一个相邻的顶点相连组成的一些连接的线段。
- Line List:每两个相邻的顶点组成独立的线段。与Line Strip不同的是,他不假设所有的点都相连。
- Triangle Strip:每相邻的3个顶点组成了一些连接的三角形。
- Triangle List:3个顶点组成独立的三角形。
Primitives with Adjacency
对于一个三角形,你可以画出3个相邻的3个三角形(adjacent triangles)。这样的信息用于geometry shader
几何着色器,其中的某些阴影算法需要用到adj。为了使几何着色器能获取到这些adj,我们必须提交这些数据与三角形一起在vertex buffer中,在这之前我们需要指定D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ
。需要注意的是,这些adj信息只是用于几何着色器——他们并不会画出来。如果没几何着色器的话,同样的他们并不会画出来。
Control Point Patch List
D3D_PRIMITIVE_TOPOLOGY_N_CONTROL_POINT_PATCHLIST
拓扑类型表明了顶点信息用于N个补充控制点。在曲面细分阶段被使用。
Indices
当我们定义多个三角形共顶点时,我们可以使用顶点索引去构建。虽然我们可以使用Triangle strips
来解决共顶点问题。但是他没有Triangle Lists
那么灵活。所以顶点索引使用例如这样:
Vectex v[4] = {v0,v1,v2,v3};
UINT indexList[6] = { 0, 1, 2,//Triangle 0
0,2,3//Triangle 1
}
这样我们把顶点数据的重复放到了索引上。这样的做法not bad当:
- 索引是一个整型,不需要那么多的内存。
- 对于高速缓存更加适合。
顶点Shader阶段
顶点shader可以理解为一个输入和输出为顶点的函数。其中的某些函数是由我们自己实现的,所以他被跑在GPU上,十分的快速。一些特殊的效果可以被实现在顶点shader上,例如转换、光照。因为我们顶点shader输入的格式可以多种多样。
本地空间和世界空间
一个物体的定义基本都被定义在他自己的本地空间,这是为了便利性和复用性起见。所以一个物体的世界坐标用 他的本地坐标和本地坐标系与世界坐标系的关系给出。
假定:
Qw=(Qx,Qy,Qz,1),uw=(ux,uy,uz,0),vw=(vx,vy,vz,0),ww=(wx,wy,wz,0)
是分别描述本地坐标系的原点、x轴、y轴和z轴相对于世界坐标系。所以我们知道,由本地坐标系转换为世界坐标系的矩阵为:
我们可以看到,当构建一个世界矩阵时,我们必须直接找出局部空间原点和轴相对于世界空间的坐标。但这在某些时候并不是很简单。一个更普遍的方法是定义W作为一个转换的序列。
View Space
为了形成一个2D的图像,我们必须放置一个虚拟相机在场景中。如果我们知道View Space的
Qw=(Qx,Qy,Qz,1),uw=(ux,uy,uz,0),vw=(vx,vy,vz,0),ww=(wx,wy,wz,0)
,描述了原点,x轴、y轴和z轴那么我们能得到从View Space转换到世界空间的矩阵。
得到这个矩阵以后,我们便可以利用 W−1 来从世界空间转换到View Space。
世界坐标系和ViewSpace通常上只有位置和方向的差异。所以我们可以简化为
W=RT
。所以这能简化矩阵的逆:
假定
Q
为摄像机的位置,
相机的右方向为:
所以 最后的相机的上方向为:
这样,通过相机瞄准的点、相机的位置和世界坐标系的上方向,我们就可以确定相机坐标系的三个轴在世界坐标系中的表达。就可以求出转换矩阵。
在DirectXMath中,有这样的函数
XMMATRIX XM_CALLCONV XMMatrixLookAtLH( FXMVECTOR EyePosition, // Q
FXMVECTOR FocusPosition, // T
FXMVECTOR UpDirection); // j