2.3.5光照(Lighting)
光照定義在世界坐標(biāo)系中,但必須變換到視圖坐標(biāo)系才可使用。視圖坐標(biāo)系中光源給物體施加的光照大大增加了場(chǎng)景中物體的真實(shí)性。
2.3.6裁剪(Clipping)
我們刪除那些超出了可視體范圍的幾何圖形的過(guò)程就叫做裁剪。這會(huì)出現(xiàn)三種情況:
完全包含——三角形完全在可視體內(nèi),這會(huì)保持不變,并進(jìn)入下一級(jí)。
完全在外——三角形完全在可視體外部,這將被刪除。
部分在內(nèi)(部分在外)——三角形一部分在可視體內(nèi),一部分在可視體外,則三角形將被分成兩部分,可視體內(nèi)的部分被保留,可視體之外的則被刪除。
圖2.13展示了上面三種情況:

2.3.7投影(Projection)
視圖坐標(biāo)系的主要任務(wù)就是將3D場(chǎng)景轉(zhuǎn)化為2D圖像表示。這種從n維轉(zhuǎn)換成n-1維的過(guò)程就叫做投影。投影的方法有很多種,但是我們只對(duì)一種特殊的投影感興趣,那就是透視投影。因?yàn)橥敢曂队翱梢允闺x照相機(jī)越遠(yuǎn)的物體投影到屏幕上后就越小,這可以使我們把3D場(chǎng)景更真實(shí)的轉(zhuǎn)化為2D圖像。圖2.14展示了一個(gè)3D空間中的點(diǎn)是如何通過(guò)透視投影到投影窗口上去的。

投影變換的實(shí)質(zhì)就是定義可視體,并將可視體內(nèi)的幾何圖形投影到投影窗口上去。投影矩陣的計(jì)算太復(fù)雜了,這里我們不會(huì)給出推導(dǎo)過(guò)程,而是使用如下的Direct3D函數(shù)通過(guò)給出平截頭體的參數(shù)來(lái)求出投影矩陣。
|
D3DXMATRIX
*D3DXMatrixPerspectiveFovLH(
D3DXMATRIX* pOut,
//
返回的投影矩陣
FLOAT fovY,
//
用弧度表示的視野角度vertical
field of view angle in radians
FLOAT Aspect,
//
寬高比
FLOAT zn,
//
前裁剪面距離
FLOAT zf
//
后裁剪面距離
);
|
(fovY定義鏡頭垂直觀(guān)察范圍,以弧度為單位。對(duì)于這個(gè)參數(shù),下面是我的理解:如果定義為D3DX_PI/2(90度角),那么就是表示以攝像機(jī)的觀(guān)察方向?yàn)槠椒志€(xiàn),上方45度角和下方45度角就是攝像機(jī)所能看到的垂直范圍了。嗯,可以想象一下自己的眼睛,如果可以把自己眼睛的fovY值設(shè)為D3DX_PI(180度角),那么我們就可以不用抬頭就看得見(jiàn)頭頂?shù)臇|西了。如果設(shè)為2
x D3DX_PI的話(huà)。。。我先編譯一下試試(building…)。哈哈,結(jié)果啥也看不見(jiàn)。很難想象如果自己能同時(shí)看到所有方向的物體,那么將是一個(gè)怎樣的畫(huà)面?。?/p>
如圖2.15所示視錐的描述參數(shù)。

Aspect參數(shù)為投影平面的寬高比例值,由于最后都為轉(zhuǎn)換到屏幕上,所以這個(gè)比例一般設(shè)為屏幕分辨率的寬和高的比值。如果投影窗口是個(gè)正方形,而我們的顯示屏一般都是長(zhǎng)方形的,這樣轉(zhuǎn)換后就會(huì)引起拉伸變形。
aspectRation = screenWidth / screenHeight
我們還是通過(guò)調(diào)用IDirect3DDevice9::SetTranform方法來(lái)進(jìn)行投影變換,當(dāng)然,要把第一個(gè)投影類(lèi)型的參數(shù)設(shè)為D3DTS_PROJECTION。下面的例子基于一個(gè)90度視角、前裁剪面距離為1、后裁剪面距離為1000的平截頭體創(chuàng)建投影矩陣:
|
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, PI * 0.5f, (float)width
/ (float)height, 1.0, 1000.0f);
Device->SetTransform(D3DTS_PROJECTION, &proj);
|
2.3.8視口變換(Viewport
Transform)
視口變換主要是轉(zhuǎn)換投影窗口到顯示屏幕上。通常一個(gè)游戲的視口就是整個(gè)顯示屏,但是當(dāng)我們以窗口模式運(yùn)行的時(shí)候,也有可能只占屏幕的一部分或在客戶(hù)區(qū)內(nèi)。視口矩形是由它所在窗口的坐標(biāo)系來(lái)描述的,如圖2.16。

在Direct3D中,視口矩形通過(guò)D3DVIEWPORT9結(jié)構(gòu)來(lái)表示。它的定義如下:
|
typedef
struct _D3DVIEWPORT9 {
DWORD X;
DWORD Y;
DWORD Width;
DWORD Height;
DWORD MinZ;
DWORD MaxZ;
} D3DVIEWPORT9;
|
前四個(gè)參數(shù)定義了視口矩形與其所在窗口的關(guān)系。MinZ成員指定最小深度緩沖值,MaxZ指定最大深度緩沖值。Direct3D使用的深度緩沖的范圍是0~1,所以如果不想做什么特殊效果的話(huà),將它們分別設(shè)成相應(yīng)的值就可以了。
一旦我們填充完D3DVIEWPORT9結(jié)構(gòu)后,就可以如下設(shè)視口:
|
D3DVIEWPORT9 vp{ 0, 0, 640,
480, 0, 1 };
Device->SetViewport(&vp);
|
這樣,Direct3D就會(huì)自動(dòng)為我們處理視口變換。現(xiàn)在還是給出視口變換矩陣作為參考:

2.3.9光柵化(Rasterization)
在把三角形每個(gè)頂點(diǎn)轉(zhuǎn)換到屏幕上以后,我們就畫(huà)了一個(gè)2D三角形。光柵化是計(jì)算需要顯示的每個(gè)三角形中每個(gè)點(diǎn)顏色值(如圖2.17)。

光柵化過(guò)程是非常繁重的計(jì)算,它應(yīng)該通過(guò)硬件圖形處理來(lái)完成。它的處理結(jié)果就是把2D圖象顯示在顯示器上。