DirectX12 3D 第一章內容
學習目標
1、學習向量在幾何學和數學中的表示方法
2、了解向量的運算定義以及它在幾何學中的應用
3、熟悉DirectXMath庫中與向量有關的類和方法
1.1 向量
向量是一種兼具大小和方向的量,具有這兩種的量都稱為向量值物理量,在幾何學中我們一般用一條有向線段來表示一個向量
1.1.1 向量與坐標系
前提:計算機無法直接處理以幾何方法表示的向量,所以需要尋求一種用數學方法來表示向量
在這里我們會引入一種3D空間坐標系,通過平移操作使向量的尾部位於原點,然后我們就可以通過向量頭部的坐標來確定該向量了,可以記作 v = (x,y,z),xyz分別為計算機程序中的浮點數。一個向量如果用數學方法表示的話,它對應的坐標總是相對於某一種參考系而言的,因此,在計算機圖形學中,我們會用到較多的參考系,因此我們要記錄向量在每一種坐標系中的對應坐標,也需要掌握將向量坐標在不同標架之間進行轉換
1.1.2 左手坐標系和右手坐標系
左手坐標系:伸出你的左手,使大拇指,食指和中指之間兩兩垂直,其中大拇指為x軸正方向,食指為y軸正方向,中指為z軸正方向
右手坐標系:同上。
1.1.3 向量的基本運算
簡單的向量加減法
1.2 長度和單位向量
前提:向量大小的幾何意義是對應有向線段的長度,3D向量的模長可以通過運用兩次畢達哥拉斯定理得出,單位向量是指長度為1的向量
向量的規范化:在某些情況下,我們不關心向量的長度,僅用它來表示方向。對此我們希望此向量的長度為1,所以我們可以將向量的每一個分量/該向量的模長。把一個向量的長度變為單位長度便是向量的規范化了。
1.3 點積
點積的定義點積是一種計算結果為標量值的向量乘法運算,因此也稱為標量積。點積就是向量之間對應分量的乘積之和。
點積的幾何意義:uv = ||u||||v||*cos0(0為兩向量的夾角)。
正交投影:p = (vn)n(p,v,n都是向量,其中p為向量v在向量n上的正交投影,n為單位向量)
利用點積進行正交化:略
1.4 叉積
叉積的計算結果和點積不同,叉積的計算結果也是向量。只有3D向量有叉積,2D向量沒有叉積。假設向量u和向量v的叉積為w,則w既正交與u,也正交與v。
計算方式:w = u x v = (UyVz-UzVy,-(UxVz-UzVx),UxVy-UyVx)
叉積不符合交換律,但符合反交換律,即u x v = -v x u
利用叉積進行正交化:略
1.5 點
通過一個處於標准位置的向量就能表示出3D空間中的特定位置,這種向量稱為位置向量,在這種情況下,向量箭頭的位置才是主要特征,方向和大小都無足輕重。
標准位置:向量通過平移使向量的尾部位於原點的向量。即從原點出發的向量
注意點:位置向量和點這兩個術語可以互相替代,但是用向量表示點有缺點也有優點
1.6 利用DirectXMath庫進行向量運算
前言:DirectXMath庫是一款為Direct3D應用程序專門設計的一個3D數學庫,它也是Windows SDK的一部分,該數學庫可以利用一條SIMD指令對4個32位浮點數或整數進行運算,可以加大的提高效率。
為了使用DirectXMath庫,我們要添加頭文件
#include <DirectXMath.h>
為了使用一些相關的數據類型,我們要添加頭文件
#include <DirectXPackVector.h>
其中DirectXMath文件的代碼都存在DirectX的命名空間中,DirectXPackVector文件中的代碼都位於DirectX::packVector的命名空間中。
1.6.1 向量類型
DirectXMath中最核心的數據類型就是XMVECTOR,它會被映射到SIMD硬件寄存器中
1、局部變量和全局變量建議使用XMVECTOR數據類型,因為XMVECTOR類型的數據需要按16字節對齊,在局部變量和全局變量中這都會自動實現
2、對於類中的成員,建議使用XMFLOAT2,XMFLOAT3或者XMFLOAT4.
3、在運算之前,建議使用加載函數將XMFLOATn類型轉換為XMVECTOR類型(可以加快運算速率)
4、用XMVECOTR實例進行運算
5、通過存儲函數將XMVECTOR類型轉換為XMFLOATn類型
1.6.2 加載方法和存儲方法
加載方法:
XMMATRIX XM_CALLCONV XMLoadFloatn(const XMFLOATn * pSource);
存儲方法:
void XM_CALLCONV XMStoreFloatn(XMFLOATn * pDestination,FXMVECTOR V);
1.6.3 參數的傳遞
為了提高效率,可以將XMVECTOR類型的值作為函數的參數,直接傳送到SSR/SSE2寄存器里,而不存在棧中。單數為了使代碼更具通用性,不受到平台和編譯器的影響,我們將利用FXMVECTOR,GXMVECTOR,HXMVECTOR和CXMVECTOR類型來傳遞XMVECTOR類型的參數。
1.6.4 常向量
XMVECTOR類型的常量實例應當用XMVECTORF32類型來表示。例如
static const XMVECTORF32 g_vHaifVector ={ 0.5f,0.5f,0.5f,0.5f };
static const XMVECTORF32 g_vZero = { 0.0f,0.0f,0.0f,0.0f };
基本上我們在運用初始化語法的時候就要使用XMVECTORF32類型了
1.6.5 重載運算符
XMVECTOR類型針對向量的加減運算以及標量的乘法運算都提供了對應的重載運算符
1.6.6 雜項
DirectXMath定義了一組覺pi有關的常用數學常量近似值,如:
XM_CONST float XM_PI= 3.141592654f;
XM_CONST float XM_2PI = 6.283185307f;
XM_CONST float XM_1DIVPI= 0.318309886f;
XM_CONST float XM_1DIV2PI = 0.159154943f;
XM_CONST float XM_PIDIV2= 1.570796327f;
XM_CONST float XM_PIDIV4= 0.785398163f;
還有弧度和角度相互轉換的內聯函數,求兩個數之間最大值和最小值的內聯函數等等
1.6.7 Setter函數
DirectXMath庫提供了下列函數以設置XMVECTOR類型中的數據
//返回0向量
XMVECTOR XM_CALLCONV XMVectorZero();
//返回(1,1,1,1)向量
XMVECTOR XM_CALLCONV XMVectorSplatone();
//返回(x,y,z,w)向量
XMVECTOR XM_CALLCONV XMVectorSet(float x,float y,float z,float w);
//返回(Value,Value,Value,Value)向量
XMVECTOR XM_CALLCONV XMVectorReplicate(float Value);
//返回(Vx,Vx,Vx,Vx)向量
XMVECTOR XM_CALLCONV XMVectorSplatX(FXMVECTOR V);
//返回(Vy,Vy,Vy,Vy)向量
XMVECTOR XM_CALLCONV XMVectorSplatY(FXMVECTOR V);
//返回(Vz,Vz,Vz,Vz)向量
XMVECTOR XM_CALLCONV XMVectorSplatZ(FXMVECTOR V);
1.6.8 向量函數
DriectXMath庫提供了一些函數用來執行各種向量運算,比如計算向量的模長,計算模長的平方,叉積,兩向量之間的夾角等等,這里不一一列舉函數原型。
1.6.9 浮點數誤差
在用計算機處理有關向量的工作時,我們應該要了解,比較浮點數時是存在誤差的,在計算機中,相等的兩個浮點數時有細微的差別的,比如在數學上規范化的向量的模長是1,但是在計算機上,規范化的向量的模長只能是接近1。
小結
1、向量的幾何和數學表達方式
向量可以用來模擬同時具有大小和方向的物理量,在幾何學上,我們用有向線段來表示向量,對向量進行標准化(將向量平移至尾部與坐標原點重合的位置)之后,我們便可以把向量的
2、向量的運算
加法,減法,標量乘法,求向量的模(長度),規范化向量,點積,叉積
3、XMVECTOR類型
DirectX一般用DirectXMath庫中的XMVECTOR類型來描述向量,這樣就可以利用SIMD技術進行高效的運算,對於類中的成員來說,要使用XMFLOAT2,XMFLOAT3,XMFLAOT4等等來表示向量。我們可以通過加載方法和存儲方法實現XMFLOATn和XMVECTOR之間的相互轉換。如果要使用常向量的初始化語法時,要使用XMVECTORF32類型
4、XMVECTOR類型做函數參數注意點(括號后面的數字為函數中對應的第幾個參數)
為了提高效率,當XMVECTOR作為參數時,可以將它直接存入SSE/SSE2寄存器中而不是棧上,如果要使代碼與平台無關,我們可以使用FXMVECTOR(1-3),GXMVECTOR(4),HXMVECTOR(5-6)和CXMVECTOR(其余)類型來傳遞XMVECTOR參數
5、一些常用運算符和方法
XMVECTOR類型重載了一些運算符用來實現向量的加法、減法、標量乘法
DirectXMath庫還提供了一些便捷的方法用來計算向量的模、,模的平方、兩個向量的點積、兩個向量的叉積、對向量進行規范化處理。
