課程概述
如果您已經通過前兩課教程進展至斯,您現在可以開始了寫3D程序了。 然而,3D編程不是像土匪斗惡霸那么簡單。它是嚴格的數學,你必須了解三維數學概念,才能寫好3D程序。 不要擔心這沒什么復雜的。 我保證您不會在數學上花費比學C + +更多的時間。
這一課是純理論課。 我們將在下一課中實踐我們的理論。 在這一課中我們將介紹坐標系統和它們如何適用于Direct3D以及創造一個3D場景。
三維坐標系
如果沒有基本的3D數學的理解,三維編程是不可能的。 而且我不是指大學數學都做一遍,我們只要理解三維坐標的概念,它們是如何工作,以及你可能用到的和各種東西。
當然,在你了解3D坐標系統之前,您需要先理解笛卡爾坐標。
直角坐標系
笛卡爾坐標系統會使你更好的認識二維坐標系統。 換句話說,它是一個在平面上確定一個點的位置的系統。
一個點是指沿軸的準確位置。 如果我們想知道有多遠的東西走了,我們通常給一個確切的數字,如“范跑跑跑了12米。” 12米,是沿著一個軸的距離。 我們說,0是這個的起點,作為范跑跑,他的位置越來越遠沿著這條軸線。 這是一個一維的坐標系。
圖片3.1 - 一維坐標系
當我們看這情景,從側面圖片中,我們可以看到,作為范跑跑,他繼續朝著屏幕右側跑啊跑,他和那個'0'點的距離越來越遠。 而這個'0'的由來,是因為范跑跑從這里開始跑(那間教室)。 在在向左的方向上,他的距離是一個負值。
但是,如果他此時轉90度,往不同的方向走會怎樣? 我們考慮一下實際情況,當他向右跑了12米,沖出了教室,這時他來到了走廊,再往前就要跳下樓了,于是他只好左轉向著樓抵口跑。
圖片3.2 - 直角坐標系
現在增加了一個軸,垂直軸,我們稱其為Y軸。 首先在水平軸X軸上,沿此軸范跑跑跑了12米,然后他又沿著Y軸的方向跑起來。
當然,這種新的軸,跟水平軸一樣,也有一個起源。 他是范跑跑在X軸上跑路的終點,因為他開始沿著Y軸跑了。 請注意,在Y軸原點也給出了0值,并隨范跑跑在Y軸上的跑路Y軸愈來愈長。
所以,現在我們有兩個軸(X軸和Y軸),每個有其起點。 嗯,這就是笛卡爾形式的直角坐標系。 現在,我們可以找到任何在這個面上的點。 我們可以他離各軸原點的距離確定他的精確位置,所以我們可以說他是在(x,y)或(12,4),12是他在X軸上跑的距離,4是他在Y軸上跑的距離。這兩個數字稱為坐標,一個點離坐標原點((),0)有多遠。
三維坐標系
其實,三維坐標系,只不過是我們剛剛討論的情況的拓展。 假如我們把直角坐標系,并添加了第三軸(Z軸)上運行垂直于X和Y軸,我們將有三維坐標。 這里說明了這一點。

圖片3.3 - 三維坐標系
像笛卡爾坐標一樣,三維坐標既可以是正值也可以是負值,這取決于點處在改軸的哪個方向上。 然而和直角坐標不一樣的是,三維坐標是三個數字,例如:(的x,y,z)或(12,4,15)。 這表明在范跑跑老師在十五米的高空(6樓)。 它也可以寫成(12,4,-15)。 也許這意味著他被埋在了煤窯。
三角幾何
現在讓我們討論三維坐標如何應用到游戲和游戲編程。 如果三維點坐標系統中的一個點代表一個在空間中的點,那么我們可以通過一組這樣的點最終生成一個三維模型。 當然,這么多點的設置將在內存中占用的空間很大,于是一種更方便,更快捷的方式就出現了,那就是設置使用三角形。
在任何跟數學相關的領域三角形都是一個非常有用的形狀,它們可以用于測量圓,他們可以用來加強建筑物,它們也可以被用來創建3D圖像。 究其原因,我們將要使用三角形是因為三角形可以組成幾乎任何形狀,比如下圖的正方體和球就是由一個個三角形構成:

圖片3.4 - 從三角形制作出來的模型
由于三角形在創建三維模型方面的各種優越性,Direct3D被設計為完全圍繞三角形并通過三角形組成各種形狀。為了要建立一個三角形,我們需要使用一種叫做頂點集的東西。
頂點集是由頂點組成的。一個頂點被定義為一個在三維空間中的確切的點。 它包括三個值x,y和z。 在Direct3D中,我們還有包含這一點的各種屬性。 因此,我們擴展的定義是指“在三維空間中的精確點的屬性和位置”。
三角形是由三個順時針地在您的程序中定義頂點。 當編碼完成后,這三個頂點形成一個平坦的可以自由旋轉,添加質感,定位和修改的表面。

圖片3.5 - 通過頂點集創建的三角形
在圖像顯示的三角形3.5有三個頂點:
X = 0,Y = 5,Z = 1
X= 5,Ÿ = -5,Z = 1
X = 5,Ÿ = -5,Z = 1
你會發現,上述所有頂點的Z都等于-1。 這是因為我們不是在談論一個3D對象,而是在談論一個三角形,這是一個二維物體。 我們當然可以改變這個Z值,但這并不會產生什么實質的影響。
為了創建一個3D對象,我們將需要組合多個三角形。 在上面的圖3.4你可以看到如何用三角形組合出其他形狀。 比如說這在個3-4里,立方體德一個邊就是由兩個簡單的三角形組成。 這個立方體的每個面都是這樣組成的。
然而,定義三維坐標游戲中的每個三角形多次不僅僅是愚蠢,這簡直就是愚蠢!。 這里還有沒有必要為涉及(你會看到我在下一課的意思)。
而不是定義每一個游戲中的每一個三角形的角落,你需要做的就是創建一個頂點,包含每一個頂點的坐標和信息,以及他們進去的順序
基元
基元(primitives,又稱為圖元或者原語) ,是3D環境中的一個單一的元素,可以是一個三角形,一條線,一個點,或其他隨便什么。 以下是基元可以被合并以創建三維對象的方法列表:
1. 點列表 Point Lists
2. 線列表 Line Lists
3. 線帶 Line Strips
4. 三角形列表 Triangle Lists
5. 三角形帶Triangle Strips
6. 三角扇形 Triangle Fans
1. 點列表
一個點列表是一組為在屏幕上顯示的頂點的列表。 它們可用于渲染3D星空,創建虛線,顯示在小地圖上的位置等。 圖片3.6說明了點列是如何顯示在屏幕上。

圖片3.6 - 一個點列(6基元)
2. 線列表
線列表是一組頂點的列表,其中奇數的頂點和其下一個頂點會連成線段。 這些可用于各種效果,包括三維網格,暴雨,航點線,等等。 圖片3.7說明了線列如何在屏幕上顯示(這是和以前相同的一組頂點)。

圖片3.7 - A線一覽(3基元)
3. 線帶
線帶是類似于線列表,不同之處在于它所有的頂點(不分奇數還是偶數)都和下一個頂點用線段連起來。 這對創建線框模型非常有用,如線框地形,草葉片,以及其他不是基于模型的對象。 這對于調試程序也是非常有用的。 圖片3.8說明了如何線帶是在屏幕上顯示。

圖片3.8 - A線地帶(5基元)
4.三角形列表
一個三角形列表是把每三個頂點組成一個單一的獨立的三角形的頂點列表。 這可以在諸如力場,爆炸效果,以及把對象拼湊在一起,圖3.9說明了三角形列表如何在屏幕上顯示。

圖片3.9 - A線列表(2基元)
5.三角形帶
一個三角形地帶是一個頂創建一系列互相連接的三角形的頂點列表,。 這是三維圖形處理最常用的方法。 這些大多是用于創建你的游戲的3D模型。 圖片3.10三角形帶說明了是如何顯示在屏幕上。請注意,前三個頂點創建一個三角形,然后下個頂點和它的前兩個頂點構成一個三角形。

圖像3.10 - 一個三角地帶(4圖元)
6。 三角扇形
三角扇形類似于三角形帶,不同的是所有三角形共用一個頂點。 見圖3.11:

圖像3.11 - 三角形扇(4圖元)
一個基元的問題
繪制基元的時候有一個小問題出現了,那就是你的三角形只有一面要顯示,但是系統畫了兩面。 沒錯它的確可以顯示兩面,但通常一個模型是完全封閉的,你看不到它的內部。 如果模型是完全封閉的,每個三角形只有一面需要繪制。 畢竟,繪制兩面要多花費一倍的時間。 下面你會看到這個繪制兩面和一面的區別。
一個三角形基元只有當其頂點是順時針順序給出時才能繪制。 如果您翻轉它周圍,它成為逆時針,因此不會顯示。

圖像3.12 - 基元只有順時針時可見
有一個簡單的方法(雖然當你進入較大得游戲時這會很繁瑣,),那就是兩面都繪制,令人原始順時針和其他反時針方向。

圖像3.13 - 兩面都繪制時兩種方式都可見
顏色
色彩是3D編程中一個相當簡單的部分。 然而,即使你對彩色光譜和光物理學非常熟悉,這只是讓你更容易地知道Direct3D不完全遵循這個宇宙的規律。 那樣做只能是圖形硬件和CPU的噩夢。那太多了,所以我們只給圖形這樣的矩陣,并創建我們自己的規則以便能夠對它進行處理。
光,當然是粒子的波,使您可以看到身邊各種對象之間的區別。 Direct3D運用圖形硬件進行各種數學算法虛擬出這一點。 然后,圖像就會顯示在屏幕上。 在這一節我們將介紹如何用Direct3D 虛擬我們在自然看到的光。
減法色 VS加法色
在您受教育的早些時期,你可以學到的原色是紅色,藍色和黃色。 這不是真正的情況。 顏色實際上是洋紅,青色和黃色。 以及為什么沒用的技術細節? 要理解這一點,你必須了解減法色和加法色的概念。
這兩種顏色之間的區別在于是否顏色是指光的顏色或一個物體的顏色。 減色是一個對象的顏色,并有原色洋紅,青色和黃色。 加法色是光的顏色,有紅,綠,藍三原光。
在光束中,越多顏色添加進來就越接近白色。 所有的顏色加在一起就成了白色,因此它被稱為加色。

圖像3.14 - 加法色顏色越多越白
上面你可以看到三原光疊加起來就成了白色。 不過,如果你仔細看,你還會看到當你把兩種原光疊加起來你會得到一個減法色的原色(洋紅,青色或者黃色)。 如果我們仔細看看這些減法色,我們將看到這是為什么。
減法色基本上是和加法色相反的。 它們并不是由一個表面反射的光疊加構成。 例如,一個紅色物體,被白色的光照亮會反映紅光是因為它吸收了綠色和藍色光。 如果你看上面的圖3.14,你會看到綠色和藍色的結合-----青色,所以青色被從白光中減去,結果就顯示紅色。

圖3.15 - 減法色減到最后就成了黑色
在圖形編程中,您將始終使用(紅,綠,藍)三元光的添加色,因為顯示器是自發光的。 而親手建立一個3D引擎會有助于你理解是什么使物體的顏色看起來這樣或者那樣。
順便說一下,這就是為什么你會發現在屏幕上紅色,綠色和藍色而打印出來就成了洋紅,青色和黃色,
如果你想深入地研究顏色,下面是一個網站對色彩和光物理學有比較徹底的研究。 如果你想到了未來DirectX 10的次世代游戲,我會認真地建議你學好顏色。 這里還有更多呢意想不到的東西,這會使得在一個大的游戲引擎有很大的改觀。
總之,請猛擊這個鏈接: http://www.byronc.com/art_color.shtml
Alpha通道
Alpha通道是在紅綠藍三原光之外一個額外的通道,透明通道。 當你將透明通道引入你的顏色設置,圖形會顯示半透明,讓您通過物體看到其背后的其他物體。 這在游戲中會是一個很有用的功能,比如說美女的紗衣(我邪惡了),以及其他許多有用的東西。 我敢肯定你一定會用到它。
設置32位色彩
Direct3D的色彩由一個32位變量的組成,它存儲所有的信息。 這包括三原光(簡稱RGB)和Alpha的值。 這些每一個被稱為通道 ,每個通道占用8位,如下圖:

圖像3.16 - 顏色bit布局
以下是定義上述的顏色的代碼:
DWORD Color_A = 0xff00ff00;
DWORD Color_B = 0x88ff00cc;


還有兩種方法來創建這些顏色,我們需要插入每個通道的值。
DWORD Color_A = D3DCOLOR_XRGB(0,255,0);
DWORD Color_B = D3DCOLOR_ARGB(136,255,0,204);

函數D3DCOLOR_ARGB()返回一個包含紅綠藍以及透明通道的信息的DWORD值。 如果你不想使用透明,那么你可以使用D3DCOLOR_XRGB(),它會用255填充Alpha通道的值。
如果你想看到這樣的一個例子,請從第1課和第2課中找出清除屏幕后使用D3DCOLOR_XRGB()函數的例子。
光與色
我不打算把關于光這的每一點都講到。 我留一些放在以后的課中。 現在,我只是想介紹下基本的光差,因為在添加光線進你的程序之前你必須對它有部分的了解
自然光,是一個非常復雜的數學說法。 當陽光普照,幾乎一切都是由它點亮,即使它沒有照到太多我們能看見的東西。 這是因為光會向周圍地區進行數千次反射,無論是陽光普照或陰天,這就是漫反射。 為了進一步增加色差,由于在陽光穿越的空間中,有一部分是反映灰塵粒子,這樣的漫反射是無法計算了。 即使電腦可以計算出這一切,它葉不能實時運行。
Direct3D使用的系統致力于模擬真實的環境光。 要做到這一點,它把光分解成三個類型----漫射光 ,環境光 與鏡面反射,三者結合在一起使得結果會接近于實際光。
漫射光
漫射光的間接照在物體上的光。 如下圖這個球就是只用漫射光照明的。

圖3.17 - 漫反射
稍后,您將了解光源。 這個球是由來自左邊的一個點光源照亮。 球離光源越遠,得到的光照就越少。
環境光
環境光被認為是無處不在的光。 不同于漫射光的是,它沒有來源,如果單獨使用會出現一個圈(因為所有的部件都被照亮了)。 這個球和上一個完全一樣,但這次添加了環境光照在黑暗部分。

圖像3.18 - 漫和環境照明
鏡面光
這有時也被稱為鏡面高亮,因為它突出反映了一個反光的顏色對象。 這個球極受到漫射光和環境光照明,又具有高光使它看起來更加真實。

圖像3.19 - 漫射,照明光和鏡面光
綜述
現在,你應該已經了解了三維的基本概念,以及它是如何應用到游戲編程。 現在讓我們實踐這一切的理論。 在下一課中,你將建立一個基本的三角形。
下一課:畫一個三角形
Translate By 王大寶(OneDouble.net)
鑒于中英文混排看著累,從這集開始,不再采用中英文對照排版,想看英文原版的朋友請移步至原帖,謝謝