3D遊戲引擎原理簡介

作者:Luke Hodorowicz

  翻譯:樂晨光 (2001/9/28)

  本人對3D也不甚瞭解,譯文動機一則是內容所致興致昂然,二則鍛鍊英譯中技能。由本人水平及經驗有限,文中絕對不乏大量誤解與誤譯,亦懇請讀者指出,得以一同提高。

  佳文須共賞,也歡迎大家自由轉載 :)

  Introduction (簡介)

  讓咱們談談你如何撰寫一份提供優雅性能的3D引擎。你的引擎需要提供的包括:曲面(curved surfaces)、動態光線(dynamic lighting)、體霧(volumetric fog)、鏡面(mirrors)、入口(portals)、天空體(skyboxes)、節點陰影(vertex shaders)、粒子系統(particle systems)、靜態網格模型(static mesh models)、網格模型動畫(animated mesh models)。假如你已經知道如何以上所述的所有功能順利工作,你也許便能將那些東東一起置入到一個引擎當中。

  等等!在你開始撰寫代碼前你必須先構思一下如何去架構你的引擎。多數來講,你一定是迫切地渴望去製作一個遊戲,但如果你立即投入便開始爲你的引擎撰寫代碼後,你一定會覺得非常難受,開發後期你可能會爲置入新的特效與控制而不得不多次重寫大量的局部代碼,甚至以失敗而放棄告終。花一點時間好好地爲你引擎深謀遠慮一番,這將會爲你節省大量時間,也少一點頭痛。你一定不會急切地去架構一個巨型的工程;或許你也會在引擎未完成時而乾脆放棄它,然後去幹的別的什麼事兒。好了,當你掌握學習你所需知識的方式之前,也許你還不能完成那些事兒。將設計真正地完成確實是件美事,爲之你會感覺更好,你將爲之而耀眼!

  讓我們分析一下具備完整功能的3D遊戲引擎的需要哪些基本部件。首先,這爲具有相應3D經驗但且還需一些指引的開發者提供了一些信息。這是一些並不難且能快速掌握但是你必須應用的內容條目。爲將你的工作更好地進行下去,這裏將對關於“把多大的工作量”與“多少部分”置入一個遊戲引擎給出一個總概。我把這些成分稱爲 系統(System)、控制檯(Console)、支持(Support),渲染/引擎 內核(Renderer/Engine Core)、遊戲介質層(Game Interface)、以及工具/數據(Tools/Data)。

  Tools/Data (工具/數據)

  在開發過程中,你總是需要一些數據,但不幸的是這並不象寫文本文件或是定義一個立方體那麼簡單。至少,你得需要3d模型編輯器,關卡編輯器,以及圖形程序。你可以通過購買,也可以在網上找一些免費的程序滿足你的開發要求。不幸的是你可能還需要一些更多的工具可你卻根本無法獲得(還不存在呢),這時你只得自己動手去寫。最終你很可能要自行設計編寫一個關卡編輯器,因爲你更本不可能獲得你所需。你可能也會編寫一些代碼來爲大量的文件打個包,整天面對應付成百上千個文件倒是非常痛苦的。你還必須寫一些轉換器或是插件將3d模型編輯器的模型格式轉換成你自己的格式。你也需要一些加工遊戲數據的工具,譬如可見度估算或是光線貼圖。

  一個基本的準則是,你可能要爲設計工具而置入比遊戲本身等量甚至更多的代碼。開始你總能找到現成的格式和工具,但是經過一段時間以後你就能認識到你需要你的引擎有很大的特性,然後你就會放棄以前的撰寫方式。

  也許目前非常流行利用的第3方工具輔助開發,所以你必須時刻注意你的設計。因爲一旦當你將你的引擎發佈爲opensouce或是允許修改,那也許在某天中會有某些人來應用你的開發成果,他們將其擴展或者做某些修改。

  或許你也應該花大量時間去設計美術,關卡,音效,音樂和實體模型,這就和你設計撰寫遊戲,工具以及引擎一樣。

  System (系統)

  系統(system)是引擎與機器本身做通信交互的部件。一個優秀的引擎在待平臺移植時,它的系統則是唯一需要做主要更改(擴加代碼)的地方。我們把一個系統分爲若干個子系統,其中包括:圖形(Graphics)、輸入(Input)、聲音(Sound)、記時器(Timer)、配置(Configuration)。主系統負責初始化、更新、以及關閉所有的子系統。

  圖形子系統(Graphics Sub-System)在遊戲裏表現得非常直觀,如果想在屏幕上畫點什麼的話,它(圖形子系統)便幹這事兒。大多數來講,圖形子系統都是利用OpenGL、Direct3D, Glide或是軟件渲染(software rendering)實現。如果能更理想一些,你甚至可以把這些API都給支持了,然後抽象出一個“圖形層”並將它置與實現API之上,這將給了客戶開發人員或是玩家更多的選擇,以獲取最好的兼容性、最佳的表現效果。

  輸入子系統(Input Sub-System)需要把各種不同輸入裝置(鍵盤、鼠標、遊戲板[Gamepad],遊戲手柄[Joystick])的輸入觸發做統一的控制接收處理。(透明處理) 比方說,在遊戲中,系統要檢測玩家的位置是否在向前移動,與其直接地分別檢測每一種輸入裝置,不如通過向輸入子系統發送請求以獲取輸入信息,而輸入子系統纔在幕後真正地幹活(分別檢測每一種輸入裝置),這一切對於客戶開發人員都是透明的。用戶與玩家可以非常自由地切換輸入裝置,通過不同的輸入裝置來獲取統一的行爲將變的很容易。

  聲音子系統(sound system)負責載入、播放聲音。該子系統功能非常簡潔明瞭,但當前很多遊戲都支持3D聲音,實現起來會稍許複雜一些。

  3D遊戲引擎中很多出色的表現都是基於“時間系統”(time)的。因此你需要一段時間來爲時間子系統(Timer sub-system)好好構思一番。即使它非常的簡單,(遊戲裏)任何東西都是通過時間觸發來做移動變化,但一份合理的設計將會讓你避免爲實現而一遍又一遍地撰寫大量雷同的控制代碼……

  配置系統(Configuration)位於所有子系統的頂端。它負責讀取配置記錄文件,命令行參數,或是實現修改設置(setup)。在系統初始化以及運行期間,所有子系統都將一直與它保持通訊。切換圖象解析度(resolution),色深(color depth),定義按鈕(key bindings),聲音支持選項(sound support options),甚至包括載入遊戲,該系統將這些實現顯得格外的簡單與方便。把你引擎設計得更爲可設置化一些,這將爲調試與測試帶來更大的方便;玩家與用戶也能很方便地選擇他(她)們喜歡的運行方式。

  Console (控制檯)

  哈!我知道所有人都樂意去更風做一個象Quake那樣的控制檯(console)系統。但這的確是一個非常好的想法。通過命令行變量與函數,你就能夠在運行時改變你的遊戲或是引擎的設置,而不需要重啓。開發期間輸出調試信息它將顯得非常的有效。很多時間你都需要測試一系列變量的值,將這些值輸出到控制檯上要比運行一個debugger速度顯然要快得多。你的引擎在運行期間,一旦發現了一個錯誤,你不必立即退出程序;通過控制檯,你可以做些非常輕便的控制,並將這個錯誤信息打印出來。假如你不希望你的最終用戶看見或是使用該控制檯,你可以非常方便地將其disable,我想沒人能看得見它。

  Support (支持)

  支持系統(Support)在你引擎中任何地方都將被使用到。該系統包含了你引擎中所有的數學成分(點,面,矩陣等),(內)存儲管理器,文件載入器,數據容器(假如你不願自己寫,也可以使用STL)。該模塊任務顯得非常基礎與底層,或許你會將它複用到更多別的相關項目中去。

  Renderer/Engine Core (渲染/引擎 內核)

  哈~是呀,所有的人都熱愛3D圖象渲染!因爲這邊有着非常多的不同種類的3D世界渲染方式,可要爲各類擁有不同工作方式的3D圖形管道做出一個概要描述也是幾乎不可能的。

  不管你的渲染器如何工作,最重要的是將你的渲染器組件製作得基化(based)與乾淨(clean)。

  首先可以確定的是你將擁有不同的模塊來完成不同的任務,我將渲染器拆分爲以下幾個部份:可見裁減(Visibility)、碰撞檢測與反饋(Collision Detection and Response)、攝像器(Camera)、靜態幾何體(Static Geometry)、動態幾何體(Dynamic Geometry)、粒子系統(Particle Systems)、佈告板(Billboarding)、網格(Meshes)、天空體(Skybox)、光線(Lighting)、霧(Fogging)、節點陰影(Vertex Shading)和輸出(Output)。

  其中每一個部分都得需要一個接口來方便地實現改變設置(settings)、位置(position)、方向(orientation)、以及其他可能與系統相關的屬性配置。

  即將顯露出來的一個主要缺陷便是“特性臃腫”,這將取決於設計期間你想實現什麼樣的特性。但如不把新特色置入引擎的話,你就會發覺一切都將變的很困難,解決問題的方式也顯得特別遜色。

  還有一件有意義的事便是讓所有的三角形[triangles](或是面[faces])最終在渲染管道里經過同一點。(並非每次的每個三角形,這裏討論的是三角形列表[triangle lists]、扇形[fans]、帶形[strips]、等) 多花一些工作讓所有物體的格式都能經過相同的光線、霧、以及陰影代碼,這樣就能非常便利地僅通過切換材質與紋理id就使任何多邊形具有不同的渲染效果。

  這不會傷及到被大量被渲染繪出的點,但是一旦你不當心,它可能會導致大量的冗餘代碼。

  你也許最終便能發現,實現所有這些你所需的極酷效果可能只佔了所有的15%左右的代碼量甚至更少。這是當然的,因爲大多數遊戲引擎並不只是圖形表現。

  Game Interface (遊戲介質)

  一個3D(遊戲)引擎很重要的部分便是------它是一個遊戲引擎。但這並不是一個遊戲。一個真正的遊戲所需的一些組件永遠不要將它包含到遊戲引擎裏。引擎與遊戲製作之間的控制介質能使代碼設計變得更清晰,應用起來也會更舒服。這雖是一些額外的代碼,但它能使遊戲引擎具有非常好重用性,通過設計架夠遊戲邏輯(game logic)的腳本語言(scripting language)也能使開發變的更方便,也可以將遊戲代碼置入庫中。如果你想在引擎本身中嵌入你的遊戲邏輯系統設計的話,大量的問題與大量修改一定會讓你打消複用這個引擎的念頭。

  因此,此時你很可能在思考這個問題:聯繫引擎與遊戲的介質層到底提供了什麼。答案就是控制(control)。幾乎引擎的每一個部分都有動態的屬性,而該引擎/遊戲介質層(engine/game layer)提供了一個接口去修改這些動態屬性。它們包括了攝像器(camera)、模型屬性(model properties)、光線(lights)、粒子系統物理(particle system physics)、聲效播放(playing sounds)、音樂播放(playing music)、輸入操作(handling input)、切換等級(changing levels)、碰撞檢測以及反饋(collision detection and response)、以及2D圖形界面的頂端顯示、標題畫面等相關的東西。基本上來講如果你想讓你的遊戲能優雅的實現這些元素,在引擎中置入這個介質層(interface)是必不可少的。

  The Game (遊戲)

  在這裏,我無法告訴你如何去寫你的遊戲。這該輪到你發揮啦。如果你已經爲你那令人贊異的引擎設計出了一套出色的介質層的話,我想在設計撰寫遊戲過程中一定會輕鬆許多。

  3D遊戲引擎設計是一項巨大的軟件工程。一個人獨立完成設計並撰寫也並非不可能,但這不只是熬一兩個晚上便能搞定的,你很可能會出寫出幾兆的源代碼量。如果你沒有持久的信念與激情,你很可能無法完成它。

  當然,別指望你的第一次嘗試就能寫出完整的引擎,挑一個比較小的項目所需的小規模引擎去實現。按你的方式去努力工作,你就能到達成功。

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