本 章 重 點 9-1 3D座標系 9-2 座標矩陣 9-3 投影轉換 9-4 裁剪 9-5 隱藏面消除
9-1 3D座標系 座標轉換的作用是用來產生物件讓我們可以看到,其中不同的座標系統所呈現出來的方式會有所不同,如同我們以不同的角度去觀看一個特定的目標,以不同角度所看到的物件顯像會有所不同。
座標轉換 座標系統必須要有一個基本的原點位置,從原點再延伸出去兩個或三個座標軸,形成一個特定的空間,這個空間即是我們所謂的2D空間或3D空間。
如果在空間中形成了兩個以上的座標系統,我們就必須要使用其中的一個座標系統來描述其他不同的座標系統,這些不同的座標系統必須要經過一些特殊的轉換才能讓這個座標系統所接受,而這種轉換的過程我們就稱為「座標轉換」。
Model座標系統 即是物體本身中的座標環境,物體本身也有一個原點座標,而物體其他的參考頂點是由原點所衍生出來的,如下圖所示:
World座標系統 在3D的世界裡,有幾個目標物體就會有幾個Model座標系統,而這些Model座標又不能表示自己在3D世界裡的真正位置,所以必須再定義出另外一個可供3D世界裡的物體參考之座標系統,並且使得所有的物體可以正確地被擺放自己應該的位置座標上,這種另外再定義出來的座標系統則稱為「World座標系統」。
View座標系統 當我們有了物體本身的「Model座標系統」與能夠表現物體在3D世界的位置座標之「World座標系統」,接下來必須要有一個觀看上述兩者的座標系統,這樣螢幕的顯示才會有依據,而這個可以觀看的座標系統我們稱為「View座標系統」。
9-2 座標矩陣 矩陣的表示方式是以4X4矩陣來呈現的,因為這種矩陣的表現方式可以用來表示平移、旋轉及縮放等三種轉換功能,而這就已經包含了3D世界的轉換型式了。這一種矩陣的運算對象及所產生的結果座標,我們稱之為「齊次座標」。
齊次座標 「齊次座標」具有四個不同的元素,簡稱「四元素」,其表示法為(x,y,z,w),如果將齊次座標表示成3D座標的話,其表示法則為(x/w,y/w,z/w)。通常w元素都會被設成「1」 。
矩陣平移(Translation) 即是物體在3D世界裡向著某一個向量方向移動,如下圖
矩陣平移運算的表示法如下列所示:
矩陣旋轉(Rotation) 定義是3D世界裡的某一個物體繞著一個特定的座標軸旋轉,如下圖所示:
繞著x軸旋轉
繞著y軸旋轉
繞著z軸旋轉
矩陣縮放(Scaling) 即是物體沿著某一個軸進行一定比例縮放的運算。如下圖所示: 物體向著X軸放大
矩陣的表示法如下列所示:
矩陣的結合律 平移矩陣為A、旋轉矩陣為B、縮放矩陣為C,而原來的頂點座標為K、最後得到的頂點座標為K’,其矩陣相乘的公式如下列所示: K’=CBAK
其實我們可以將這種特定的矩陣相乘過程簡化,因為矩陣相乘的運算是可以符合數學上所說的「結合律」,也就是將A、B、C三個矩陣先結合成另一個矩陣,如下: μ=CBA K’=μK
Direct3D矩陣 在Direct3D定義裡,矩陣被宣告成一個名為「D3DMATRIX」的資料結構,如下: typedef struct _D3DMATRIX { union { struct { float _11, _12, _13, _14; float _21, _22, _23, _24; float _31, _32, _33, _34; float _41, _42, _43, _44; }; float m[4][4]; }; } D3DMATRIX;
#define D3D_OVERLOADS #include <d3d.h> D3DMATRIX mat; //下面三種表示方式的意思都是一樣的 mat._13 = 0.8f; mat[1][3] = 0.8f; mat(1,3) = 0.8f;
如果我們要建立一個平移的矩陣,其表示法如下圖所示:
在程式碼裡,我們就可以將它撰寫成如下列所示: D3DMATRIX mat = { 1, 0, 0, D3DVAL(4.0) 0, 1, 0, D3DVAL(8.0) 0, 0, 1, D3DVAL(16.0) 0, 0, 0, 1 };
向量表示法 在Direct3D定義裡,向量被宣告成一個名為「D3DVECTOR」的資料結構,如下列所示: typedef struct _D3DVECTOR { float x; float y; float z; } D3DVECTOR;
矩陣相乘 //將矩陣pM1與矩陣pM2相乘之後的結果傳給矩陣pOut D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX* pOut, CONST D3DXMATRIX* pM1, CONST D3DXMATRIX* pM2 );
向量相乘 //將向量pV1與向量pV2相乘之後的結果傳給向量pOut D3DXVECTOR3* D3DXVec3Cross( D3DXVECTOR3* pOut, CONST D3DXVECTOR3* pV1, CONST D3DXVECTOR3* pV2 );
兩個向量進行dot product的運算 FLOAT D3DXVec3Dot( CONST D3DXVECTOR3* pV1, );
計算向量的長度 FLOAT D3DXVec3Length( CONST D3DXVECTOR3* pV );
計算向量的單位向量 D3DXVECTOR3* D3DXVec3Normalize( D3DXVECTOR3* pOut, CONST D3DXVECTOR3* pV );
向量相加 D3DXVECTOR3* D3DXVec3Add( D3DXVECTOR3* pOut, CONST D3DXVECTOR3* pV1, CONST D3DXVECTOR3* pV2 );
9-3 投影轉換 將三維的座標系統轉換成二維的座標,並將3D世界裡的座標單位映射到2D螢幕的座標單位上,才能在電腦螢幕上看到所謂的3D世界,而這整個轉換的過程我們稱之為「投影」 。
平行投影 當我們省略掉三維空間裡的一維元素之後,我們就可以得到了一個平行投影的圖形座標,在這個時候,三維空間中的所有頂點都會從三維空間映射到2D平面的平行線上,因此我們就稱這種方式為「平行投影」。
平行投影
我們可以在投影線與投影面交叉角度的基礎上更進一步地細分平行投影。如果交叉的角度是直角的話,我們則稱之爲「正交投影」(orthographic);不是直角的話,我們則稱為「傾斜投影」(oblique)。
透視投影 透視投影所建立出來的物件投影圖像之大小必須依賴物件與觀察者的距離。
原點與圖像上的頂點相聯繫之關係。如下圖所示:
無深度投影 具深度投影
焦點距離越小則視角寬度越廣,而焦點距離越大則視角寬度越窄 。
9-4 裁剪 2D裁剪 裁剪是對於某種圖形做出修剪的動作,其目的是為了讓看不見的頂點不加以描繪,以提升執行的速度。
第三種剪裁法 第一種剪裁法 第二種剪裁法
線段的裁剪 線段裁剪的方法可以分析圖形的相對約束位置,並且找出符合這一點的圖形部分。在線段裁剪的情況下,它需要找出其交叉點或線段與裁剪邊界的交叉點,通常不是直接就能夠把這種交叉發生的地方看得一清二楚的。如下圖所示:
剪裁線 剪裁線
剪裁線 剪裁線
剪裁線
第三次運算的終點 第一次運算的終點 第二次運算的終點
多邊形的裁剪
在矩形螢幕情形下,我們將每一個裁剪邊緣計算裁剪常式一次,最後獲得符合所有強制標準的多邊形。如下圖所示:
剪裁後線段 原來線段
3D裁剪
9-5 隱藏面消除 背面剔除(back culling)演算法 9-5 隱藏面消除 背面剔除(back culling)演算法 許多三維物體中,它們所佔據的空間都被一些連續的表面所包圍著。當我們觀察這些物體的時候,只能看到這些包圍表面中的正面部分,背面則無法看到。「背面剔除演算法」就是將這些我們看不到的背面多邊形去除掉。如下圖所示:
我們只能看見三為物體中的其中一面而已
凸面體 凹面體
這個面被其他面擋住了
對於透視投影而言,投影線會相交在觀察者的眼中,它們的方向是不同的。我們可以在世界或觀察空間中的任意一點上構造一個指向觀察者眼睛的向量,並且使它指向該點的方向,如此一來,我們就得到了這一點的觀察方向了。如下圖所示:
排序 另一種方法也可以用來剔除這些看不到的頂點,其方法可以充分的利用圖形硬體的緩衝儲存結構來加速其運算。不管場景中的多邊形有沒有擋住其他的多邊形,只要按照從後面到前面的順序光柵化圖形就可以正確的顯示所有可見的圖形了,也就是將離觀察者最近的一個多邊形最後進行光柵化處理。這種方法就是我們稱它為「畫家演算法」。
八叉樹 當觀察者在一些單元邊界內位於虛擬地形表面上或表面的上方。我們能夠把整個的地形分割爲四個規則的子地形,如下圖。
我們可以將地形單元的光柵處理順序編列成如下所示: 第一次:1、2、3、4。 第二次:5、6、7、8、9、10。 第三次:11、12、13、14、15、16; 第四次:17、18、19、20、21、22、23、24、25。
光柵處理的順序將會依據觀察者在場景中角度的不同而有所改變。如下圖所示:
「八叉樹」的處理規則就是利用遞迴結構的方式來進行的,在每個細分的層次上有著同樣規則的屬性。因此,在每個層次上我們可以利用同樣的編列順序,以獲得整個結構元素由後到前的順序依據。
二元空間分割樹 二元空間分割樹, Binary Space Partitioning Tre是一種空間分割的方法,簡稱「BSP Tree」。
A區域顯示在X多邊形上 B區域顯示在Y多邊形上
此圖的現象在現實中視不可能存在的
詳細的二元素
再利用D平面為主Node來做分割的動作。在分類和切割後的結果如下圖所示:
現在的二元空間分割樹看起來就如下圖:
再繼續分割上述二元樹結構的話,二元樹結構就會變成如下圖所示:
細節層次 細節層次繪製簡化的技術是在不影響畫面視覺效果的條件下,逐步簡化景物的表面細節來減少場景的幾何圖形所產生之複雜性,並且它又可以提高繪製演算法的效率 。
頂點刪除 刪除網格中的一個頂點,然後再對它的相鄰三角形做出一個空洞,這個空洞就當作是三角的剖分,以保持網格的一致性。
邊界壓縮 將網格上的一條邊壓縮成一個頂點,這個頂點與該邊相鄰的兩個三角形一起退化掉,而再把它的兩個頂點融合成一個新的頂點。
面的收縮 將網格上的一個面收縮成一個頂點,讓該三角形本身的和與其相鄰的三個三角形一起退化掉,而它的三個頂點則收縮成另一個新的頂點。