Direct3D學習筆記(五) 初級光照技術

 

We've Got Camera and Action; What About Lights?

現在我們已經讓我們的三角形旋轉起來的,但是我們還想做的更好一些,怎麼辦呢?我們可以給他加上燈光,燈光這個概念我們已經在前面簡短的提過了,在我們那個黑色的三角形中我們爲了看見他本來的顏色已經把燈光關閉了,現在我們首先要做的事情就是把燈開開,先修改下面的語句,設置爲true
device.RenderState.Lighting = true;

其實我們可以不要這個語句,因爲在默認情況下設備的燈是開着的;我們只是爲了大家更好的理解才寫上這個代碼的。好,現在運行我們的程序,會發現那個黑色的三角形又出來了。只是它開始旋轉了而已,我們現在需要做的就是定義一個光的屬性,並且把燈光打開,其實在device類中有個關於光的數組,他的每個成員分別描述着光的不同屬性,現在我們開始定義一個自己的燈吧。好,我們只要在OnPaint方法中在三角形定義後加上下面定義燈光屬性的代碼就可以了。
device.Lights[0].Type = LightType.Point;
device.Lights[0].Position = new Vector3();
device.Lights[0].Diffuse = System.Drawing.Color.White;
device.Lights[0].Attenuation0 = 0.2f;
device.Lights[0].Range = 10000.0f;
device.Lights[0].Commit();
device.Lights[0].Enabled = true;


好,那上面的每一行分別代表什麼意思呢。
首先,我們定義了燈光的類型,是點光源,點光源的意思就是說定義的燈就像一個電燈泡,它的光是像四面八方發射的。這一段說了一些光源的屬性,其實大家應該都知道。有點光源和平行光源等等,我就不多說了。
第二行,我們定義了光源的位置。我們新建了一個Vector3向量,他的默認構造函數的數值就是(0,0,0),也就是說我們的光源位置就在世界座標系的圓點。
接下來我們定義了光的顏色是白色。
下面接着的是光的衰減度,也就是我們所說的光強度。越遠的距離光強度就越弱。這個道理應該大家都明白。他這裏也沒有給我一個強度到底多強的概念,大家可以修改數值自己去體會一下強度的概念。
range參數是光能夠作用的最大範圍,在這些參數中,有些已經不是我們編程要說的了,而是光物理學要理解的概念,所以請大家自己去看看相關的資料。這裏我也不多說了,要是我完全弄明白了我會貼上來的。
接下來device.Lights[0].Commit();是把上面的屬性都提交給設備(device),有些版本不提供這個函數,可以直接把這行刪除掉,設置好屬性後就自動提交了。只是在這個教程裏面建議大家有這個函數的DirectX版本中,在使用燈光前請保證已經提交給設備並且Enabled設置成true。
最後一行比較明顯,就是允許使用上面的屬性來顯示我們定義的光源。


如果你現在運行我們的程序,你會注意到雖然我們已經定義好我們的光源,但是我們的三角形還是黑色的,我們仍然看不到任何的光,Direct3D並沒有使用我們的光源照亮物體。但是實際上不是這樣的,但爲什麼又沒有光呢?因爲照明計算只能在每個有法向量的平面中被計算,而我們前面定義的幾何形狀是沒有定義法向量的,關於什麼是法向量相信學過高中數學的人都清楚,我在這裏就不羅嗦了。


知道了這些,我們來給我們的三角形定義一下法線以便讓光照計算能夠正確計算出顏色來。最簡單的辦法就是改變我們的頂點類型的格式使他包括一個法線的屬性。所以修改你的三角形數據代碼,變成下面的樣子。


CustomVertex.PositionNormalColored[] verts=new CustomVertex.PositionNormalColored[3];
verts[0].SetPosition(new Vector3(0.0f, 1.0f, 1.0f));
verts[0].SetNormal(new Vector3(0.0f, 0.0f, -1.0f));
verts[0].Color = System.Drawing.Color.White.ToArgb();
verts[1].SetPosition(new Vector3(-1.0f, -1.0f, 1.0f));
verts[1].SetNormal(new Vector3(0.0f, 0.0f, -1.0f));
verts[1].Color = System.Drawing.Color. White.ToArgb();
verts[2].SetPosition(new Vector3(1.0f, -1.0f, 1.0f));
verts[2].SetNormal(new Vector3(0.0f, 0.0f, -1.0f));
verts[2].Color = System.Drawing.Color. White.ToArgb();


最後把接下來的代碼修改成下面的樣子

device.BeginScene();
device.VertexFormat = CustomVertex.PositionNormalColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);
device.EndScene();

實際上我們只修改了第二行而已,讓它有一個法線而已。

在這裏,最大的改變是我們定義了一個帶有法向量的三角形平面並且把三個頂點的顏色都設置成白色,光源也是白色,並且法向量都是z軸方向的,我們將看到一個全白色的三角形,大家有興趣的話可以改變上面的頂點顏色和光源顏色得到不同的結果,由於我們的向量是z方向的,所以改變x和y座標向量還是獨立的。並不是完全和平面正方向垂直的,(不知道自己翻譯的對不對。好像是這個意思,等我調試一下代碼再加上正確的理解吧),好,現在三角形的顏色已經不是簡單的顏色了,是通過本身的顏色和光源的顏色計算出來的,由於所有的3d場景中顏色都是這樣計算出來的,而且空間位置也是要計算的,所以運行的時候比普通的2d場景要慢些,這就是爲什麼好的3d遊戲要好得顯卡支持的緣故。
還有一件事情,因爲光源將計算每一個頂點,所以在多邊形比較少的模式中(就像我們的一個三角形環境中),看起來不那麼真實,我們在後面將繼續討論更加高級的照明技術,比如per pixel lighting(每個象素照明技術,不知道怎麼翻譯比較上口,大家看英文還好點),那樣會讓我們的場景看起來更加真實。

發佈了78 篇原創文章 · 獲贊 0 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章