取景變換
取景變換(也稱觀察變換)是在世界空間下架設(shè)一個攝像機,把各個頂點坐標從世界空間變換到攝影空間(觀察空間)。在攝影空間里,攝像機或者說觀察點位于原點,向著z軸正方向。因為Direct3D采用左手坐標系,所以z軸正方向指向屏幕里面。設(shè)三維頂點在世界坐標系的坐標為Pworld,在攝影空間內(nèi)的坐標為Pview,則:
Pview = Pworld * Mview
矩陣Mview稱為觀察矩陣。觀察矩陣根據(jù)攝像機在世界空間中的位置(即攝影空間的原點在世界坐標系中的相對位置)和攝像機的觀察方向在世界空間中的方向,將世界坐標系下的對象重新定位。在Direct3D中設(shè)置觀察矩陣非常簡單,首先調(diào)用Direct3D擴展實用庫提供的函數(shù)D3DXMatrixLookAtLH(),生成一個基于左手坐標系的觀察矩陣,該函數(shù)聲明如下:
Builds a left-handed, look-at matrix.
D3DXMATRIX * D3DXMatrixLookAtLH(
D3DXMATRIX * pOut,
CONST D3DXVECTOR3 * pEye,
CONST D3DXVECTOR3 * pAt,
CONST D3DXVECTOR3 * pUp
);
Parameters
- pOut
- [in, out] Pointer to the D3DXMATRIX structure that
is the result of the operation.
- pEye
- [in] Pointer to the D3DXVECTOR3 structure that
defines the eye point. This value is used in translation.
- pAt
- [in] Pointer to the D3DXVECTOR3 structure
that defines the camera look-at target.
- pUp
- [in] Pointer to the D3DXVECTOR3 structure
that defines the current world's up, usually [0, 1, 0].
Return Values
Pointer to a D3DXMATRIX structure that is a
left-handed, look-at matrix.
Remarks
The return value for this function is the same value
returned in the pOut parameter. In this way, the D3DXMatrixLookAtLH
function can be used as a parameter for another function.
This function uses the following formula to compute the
returned matrix.
zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)
xaxis.x yaxis.x zaxis.x 0
xaxis.y yaxis.y zaxis.y 0
xaxis.z yaxis.z zaxis.z 0
-dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1
然后調(diào)用函數(shù)IDirect3DDevice9::SetTransform(D3DTS_VIEW,
&mat_view)設(shè)置觀察矩陣,其中mat_view為函數(shù)D3DXMatrixLookAtLH()生成的觀察矩陣。
當然,也可以使用函數(shù)D3DXMatrixLookAtRH()建立一個基于右手坐標系的觀察矩陣,但因為Direct3D采用左手坐標系,所以通常不使用此函數(shù)。
創(chuàng)建并設(shè)置一個觀察矩陣的方法很容易,但真正理解構(gòu)造觀察矩陣原理卻不像理解構(gòu)造世界變換矩陣那么容易。有多種方法可以建立觀察矩陣,但無論對于哪種情況,攝像機都有自己在世界空間下的邏輯位置和方向。觀察矩陣的任務(wù)就是完成對象的平移和旋轉(zhuǎn),從而把它們定位在攝影空間里,而此時攝像機位于攝影空間的原點。所以,一種創(chuàng)建觀察矩陣的方法是用一個平移矩陣以及各個軸的旋轉(zhuǎn)矩陣來實現(xiàn)。下面以這種方法為例較簡單介紹構(gòu)造觀察矩陣的原理。這種方法使用下面的矩陣運算公式:
V = T * Rz * Ry * Rx
在這個公式里,V是將要創(chuàng)建的觀察矩陣,T是世界坐標系下的一個平移矩陣,Rx、Ry和Rz是繞x、y和z軸的旋轉(zhuǎn)矩陣。這些平移矩陣和旋轉(zhuǎn)矩陣以世界空間下攝影機的邏輯位置和方向為基礎(chǔ)。所以,如果一個攝影機在世界空間下的邏輯位置是(10,
20, 100),平移矩陣的作用是將對象沿x軸移動10個單位,沿y軸移動20個單位,沿z軸移動100個單位。公式中的旋轉(zhuǎn)矩陣以攝像機的方向為基礎(chǔ),表示攝影空間里的坐標軸相對于世界空間坐標軸應(yīng)該旋轉(zhuǎn)多少度。例如,如果攝像機的方向垂直向下時,攝影空間的z軸偏離世界空間z軸90度。那么就需要用公式中的旋轉(zhuǎn)矩陣對場景里的所有對象繞x軸旋轉(zhuǎn)負90度,也就是說,這時的旋轉(zhuǎn)是與偏離程度是等大反向的。把前面的平移矩陣和這個旋轉(zhuǎn)矩陣連接起來,就創(chuàng)建了一個觀察矩陣V。用它來調(diào)整場景里對象的位置和方向,使得它們的頂部沖著攝影機的鏡頭,就好像攝像機從對象的頂部向下拍攝一樣。