D3D座標轉換淺析

在開始介紹前還有一些問題需要提前聲明,以下的介紹都以左手座標系爲基準,因爲D3D就是採用的左手座標系。在左手座標系下,涉及到旋轉時的正方向是指:從座標軸的正方向向負方向看,順時針方向爲正方向。

(1)世界變換

把物體的本地座標變換成世界座標,這個座標變換稱爲世界變換(World Transformation)。例如我們要在世界座標系中放置一個立方體定位在(-3,2,6),在D3D環境下我們可以這樣寫程序:

// Build the cube world matrix that only consists of a translation
D3DXMATRIX cubeWorldMatrix;
D3DXMatrixTranslation(&cubeWorldMatrix, -3.0f, 2.0f, 6.0f); 
// Set the cube’s transformation
Device->SetTransform(D3DTS_WORLD, &cubeWorldMatrix);
drawCube(); // draw the cube

以上提到的cubeWorldMatrix實際上爲4X4矩陣:

 1 0 0 0
 0 1 0 0
 0 0 1 0
-1 2 6 1
假如某點在本地(物體)座標系中座標爲P = (x,y,z,1),則經過轉換後獲得該點在世界座標系中的座標,即P' = P*cubeWorldMatrix。
以上是以物體平移舉例子,相似的世界變換還有繞軸旋轉。

(2)視角變換

把物體從世界空間轉換到視角空間,這個座標變換稱爲視角變換(View Transformation)。

我們可以通過調用D3DXMATRIX *D3DXMatrixLookAtLH(D3DXMATRIX* pOut, CONST D3DXVECTOR3* pEye, CONST D3DXVECTOR3* pAt, CONST D3DXVECTOR3* pUp),來獲得相應的轉換矩陣,在函數中pEye 參數指定攝相機在世界座標系中的位置,pAt 參數指定攝相機所觀察的世界座標系中的一個目標點,pUp參數指定3D世界中的上方向,通常設Y軸正方向爲上方向,即取值爲(0,1,0),pOut獲得相應的轉換矩陣。例如:假設我們要把攝相機放在點(0,3,-4),並且目標點爲世界座標系的中點(0,0,0),我們可以這樣獲得視圖變換矩陣:

        D3DXVECTOR3 eye( 0.0f, 3.0f,-4.0f ); 
        D3DXVECTOR3 lookat( 0.0f, 0.0f, 0.0f ); 
        D3DXVECTOR3 up( 0.0f, 1.0f, 0.0f ); 
        D3DXMATRIX matView;
        ::D3DXMatrixLookAtLH( &matView, &eye, &lookat, &up );
        Device->SetTransform( D3DTS_WORLD, &matWorld );

上面的matView矩陣爲:
        1    0    0   0
        0  0.8 -0.6 0
        0  0.6  0.8  0
        0    0    5    1
在該例子中相當於把世界座標系順時針旋轉α度,其中α滿足tanα=3/4,在把旋轉後的世界座標沿z軸負方向移動5,最後獲得的座標系相當於攝像機座標系(視角空間),還以點P爲例,轉換後點的新座標(在攝像機座標系的座標)爲P' = P*matView。

(3)投影變換

把物體從視角空間投影到投影窗口中,這個座標變換稱爲投影變換(Perspective Transformation)。

 投影變換的實質就是定義可視體並將可視體內的幾何圖形投影到投影窗口上去,我們通過以下的函數來求得投影矩陣:
D3DXMATRIX *D3DXMatrixPerspectiveFovLH( D3DXMATRIX* pOut, FLOAT fovY, FLOAT Aspect, FLOAT zn, FLOAT zf );
其中forY是Y方向上的可視角,Aspect參數爲投影平面的寬高比例值,zn爲前(near)裁剪平面的z座標,zf爲後(far)裁剪平面的z座標。
投影矩陣的計算比較複雜可以先不追究(我也還沒弄懂O(∩_∩)O~),下面再以實例說明:

    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(
        &proj, 
        D3DX_PI * 2 / 3, // 120 - degree
        (float)Width / (float)Height,
        1.0f,                   // distance to near plane
        1000.0f);               // distance to far plane
    Device->SetTransform(D3DTS_PROJECTION, &proj);
上面程序中fovY爲120°,即Y軸方向上的視角爲120°,XZ平面上下各有60°,Width / Height爲投影平面的寬高比例值,總體上來說就是將視角空間中從z=1到z=1000,攝像機從上到下120°範圍內的物體顯示到投影窗口上(在Direct3D 中定義的投影平面(即投影窗口所在的平面)是 Z = 1 的平面)。要注意的是程序中的Width和Height代表要顯示相應圖像的窗口客戶區的寬和高,對Aspect進行這樣的設置可以使得要顯示的物體保持原來的比例。下面舉例進行解釋:

假設顯示圖像的窗口Width = 480,Height = 480,而Aspect不爲Width / Height而是Aspect = 0.5,其他參數不變這就相當於攝像機Y方向(上下方向)的範圍是120°,而X方向(左右方向)上的範圍是60°,即要把寬和高比值爲1:2的圖像顯示到比值爲Width / Height = 1:1的窗口上,顯示的結果相當於圖像被左右拉伸了。

發佈了5 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章