在d3d中默認使用左手系座標,其實就是在生成變換矩陣時,習慣使用帶有LH後綴的函數,如LookAtLH、PerspectiveFovLH等。但是大部分編輯器(如Maya)使用的是右手系座標,所以會在導入相關模型的時候轉換到左手系。但這樣會導致應用程序空間和編輯器控件不一致,寫程序時非常麻煩。
我這邊決定直接使用右手系座標,終結下需要注意的事項:
模型空間
如果使用的模型是左手系空間的,則需要對定點、法線等數據的 z 值取反,但是Maya默認使用右手系,則在導入時可以將數據原封不動的裝入
Culling Mode
理論上,右手系空間應當使用逆時針順序(CCW,counterclockwise)作爲三角形的正面,但是這也可以取決於編輯器,如Maya使用順時針,那也以可直設置成CW模式
View空間
View空間右可理解爲相機空間,這裏要注意的是左手系的View空間是 Z 軸向外,而右手系則是 Z 軸向內(即正 Z 軸方向與相機相反),所以在生成 uvn 矩陣的時候要注意
n=normalize(eye - at),參見 D3DXMatrixLookAtRH
Vector3 zaxis = (eye - at).normalize();
Vector3 xaxis = up.cross(zaxis).normalize();
Vector3 yaxis = zaxis.cross(xaxis);
return Matrix4(
xaxis.x, yaxis.x, zaxis.x, 0,
xaxis.y, yaxis.y, zaxis.y, 0,
xaxis.z, yaxis.z, zaxis.z, 0,
-xaxis.dot(eye), -yaxis.dot(eye), -zaxis.dot(eye), 1);
Projection空間
既然右手系中 Z 軸與相機正方向相反,那麼這裏的 Near Z、Far Z 的理解就不同了,由於通常 Near Z、Far Z 描述成正值,那麼在求解透視矩陣時,就要對其反向處理(這一點和左手系是不同的),參見 D3DXMatrixPerspectiveFovRH
float yScale = cot(fovy / 2);
float xScale = yScale / aspect;
return Matrix4(
xScale, 0, 0, 0,
0, yScale, 0, 0,
0, 0, zf / (zn - zf), -1,
0, 0, zn * zf / (zn - zf), 0);