Share via


轉換概觀

矩陣轉換會負責處理 3D 圖形的許多低階數學運算。

幾何管線會將頂點做為輸入。 轉換引擎會將世界、檢視和投影轉換套用至頂點、裁剪結果,並將所有內容傳遞至轉譯器。

轉換和空間 描述
模型空間中的模型座標 在管線的開頭處,模型的頂點會相對於本機座標系統來進行宣告。 這會包含一個本機原點和一個方向。 座標的此一方向通常會稱為「模型空間」。 個別座標則稱為「模型座標」
將世界轉換至世界空間 幾何管線的第一個階段,會將模型頂點自本機座標系統轉換為場景中所有物件所使用的座標系統。  重新設定頂點方向的程序,就是所謂的世界轉換,也就是從模型空間轉換至稱為「事件空間」的新方向。 世界空間中的每個頂點,都會使用「世界座標」進行宣告。
將檢視轉換為檢視空間 (相機空間) 在下一個階段中,描述您 3D 世界的頂點會針對相機進行定向。 這表示,您的應用程式會選擇場景中的某個觀點,而世界空間座標會於相機檢視周邊重新定位和旋轉,已將世界空間轉換為「檢視空間」 (又稱為「相機空間」)。 這就是檢視轉換,旨在從世界空間轉換為檢視空間。
將投影轉換為投影空間 下一個階段為投影轉換,旨在從檢視空間轉換為投影空間。 在管線的這個部分中,物件通常會透過相對於與檢視人員之距離的方式進行縮放,以賦予場景深度的錯覺;距離較近的物件會看起來大於距離較遠的物件。 為了簡單起見,本文建會將頂點於投影轉換後的所在空間稱為「投影空間」。 有些圖形設計書籍可能會將投影空間稱為「透視後同質空間」。 並非所有投影轉換都會縮放場景物件的大小。 上述投影有時也稱為「仿射」或「正交投影」
在畫面空間中裁剪 在管線的最後一個部分中,畫面上看不到的任何頂點都會遭到移除,好讓轉譯器無需費時計算從不會顯示之項目的色彩和陰影。 此程序稱為「裁剪」。 裁剪之後,其餘的頂點都會依照檢視區參數進行縮放,並轉換為畫面座標。 其所產生的頂點會於場景點陣化後顯示在畫面上,並存在於畫面空間中。

 

轉換會用來將物件幾何從任一個座標空間轉換為另一個座標空間。 Direct3D 會使用矩陣來執行 3D 轉換。 矩陣會建立 3D 轉換。 您可以合併多個矩陣,以產生包含多個轉換的單一矩陣。

您可以在模型空間、世界空間和檢視空間之間轉換座標。

矩陣轉換

在使用 3D 圖形的應用程式中,您可以使用幾何轉換來進行下列作業:

  • 表示某個物件相對於其他物件的位置。
  • 旋轉和調整物件大小。
  • 變更檢視位置、方向和檢視方塊。

您可以使用 4x4 矩陣,將任何點 (x,y,z) 轉換為另一個點 (x', y', z'),如同下列方程式所示。

equation of transforming any point into another point

使用 (x, y, z) 和矩陣執行下列方程式,就會產生點 (x', y', z')。

equations for the new point

最常見的幾種轉換,分別為轉譯、旋轉和縮放。 您可以將產生這些效果的多個矩陣合併為單一矩陣,以一次計算多個轉換。 舉例來說,您可以建置單一矩陣來轉譯和旋轉一系列的點。

矩陣會以資料列、資料行的順序撰寫。 沿著每個軸平均縮放頂點的矩陣 (也就是所謂的統一縮放矩陣),會以使用數學符號的下列矩陣表示。

equation of a matrix for uniform scaling

在 C++ 中,Direct3D 會使用矩陣結構,將矩陣宣告為二維陣列。 下方範例顯示了如何初始化 D3DMATRIX 結構,以將其做為統一縮放矩陣 (比例因素為 "s")。

D3DMATRIX scale = {
    5.0f,            0.0f,            0.0f,            0.0f,
    0.0f,            5.0f,            0.0f,            0.0f,
    0.0f,            0.0f,            5.0f,            0.0f,
    0.0f,            0.0f,            0.0f,            1.0f
};

翻譯

下列方程式會將點 (x, y, z) 轉譯為新的點 (x', y', z')。

equation of a translation matrix for a new point

您可以在 C++ 中手動建立轉譯矩陣。 下方範例顯示建立矩陣來轉譯頂點之函式的原始程式碼。

D3DXMATRIX Translate(const float dx, const float dy, const float dz) {
    D3DXMATRIX ret;

    D3DXMatrixIdentity(&ret);
    ret(3, 0) = dx;
    ret(3, 1) = dy;
    ret(3, 2) = dz;
    return ret;
}    // End of Translate

縮放比例

下列方程式會使用 x、y 和 z 方向的任意值,將點 (x, y, z) 縮放為新的點 (x', y', z')。

equation of a scale matrix for a new point

Rotate

此處所提到的轉換,皆適用於左手座標系統,因此可能和您在其他地方看到的轉換矩陣有所差異。

下列方程式會沿著 x 軸旋轉 (x, y, z),以產生新的點 (x', y', z')。

equation of an x rotation matrix for a new point

下列方程式會沿著 y 軸旋轉點。

equation of a y rotation matrix for a new point

下列方程式會沿著 z 軸旋轉點。

equation of a z rotation matrix for a new point

在這些範例矩陣中,會以希臘字母 theta 代表旋轉角度,並以弧度為單位。 角度會從旋轉軸朝向原點的方式來順時針測量。

下列程式碼顯示了處理 X 軸旋轉的函式。

    // Inputs are a pointer to a matrix (pOut) and an angle in radians.
    float sin, cos;
    sincosf(angle, &sin, &cos);  // Determine sin and cos of angle

    pOut->_11 = 1.0f; pOut->_12 =  0.0f;   pOut->_13 = 0.0f; pOut->_14 = 0.0f;
    pOut->_21 = 0.0f; pOut->_22 =  cos;    pOut->_23 = sin;  pOut->_24 = 0.0f;
    pOut->_31 = 0.0f; pOut->_32 = -sin;    pOut->_33 = cos;  pOut->_34 = 0.0f;
    pOut->_41 = 0.0f; pOut->_42 =  0.0f;   pOut->_43 = 0.0f; pOut->_44 = 1.0f;

    return pOut;
}

串連矩陣

使用矩陣的其中一個優勢,在於可透過相乘的方式,以合併兩個或多個矩陣的效果。 這表示,您無需套用兩個矩陣,就能旋轉模型,然後將其轉譯至某個位置。 相較之下,只要將旋轉和轉譯矩陣相乘,即可產生包含所有效果的複合矩陣。 這個程序就是所謂的矩陣串連,可使用下列方程式來撰寫。

equation of matrix concatenation

在這個方程式中,C 代表要建立的複合矩陣,而 M₁ 到 Mₙ 則為個別矩陣。 在多數情況只會串連兩個或三個矩陣,但數量則沒有限制。

執行矩陣的相乘的順序十分重要。 先前的公式會反映矩陣串連的從左到右規則。 這表示,您用來建立複合矩陣的可見效果,將以從右到左的順序發生。 下列範例顯示了一般的世界矩陣。 假設您正在為典型的飛碟建立世界矩陣。 您或許想要沿著中心 (模型空間的 y 軸) 來旋轉飛碟,並將其轉譯至場景中的其他某些位置。 若要完成此效果,請先建立旋轉矩陣,然後將其乘以轉譯矩陣,如下列方程式所示。

equation of spin based on a rotation matrix and a translation matrix

在這個公式中,Ry 為沿著 y 軸旋轉的矩陣,而 Tw 則會用來轉譯至世界座標內的某個位置。

將矩陣相乘的順序相當重要,因為不同於將兩個純量值相乘,矩陣相乘不具交換性質。 以相反的順序將矩陣相乘,就會將飛碟的視覺效果轉譯至其世界空間位置,然後沿著世界原點旋轉。

無論所建立的矩陣類型為何,請務必記住從左到右的規則,以確保您達到預期的效果。

轉換