游戲引擎分層架構(自上而下)
工具層(Tool Layer)
在一個現代游戲引擎中,我們最先看到的可能不是復雜的代碼,而是各種各樣的編輯器,利用這些編輯器,我們可以制作設計關卡、角色、動畫等游戲內容,這一系列編輯器就構成了引擎最上面的一層——工具層。
功能層(Function Layer)
- 將一個三維虛擬世界轉換為一幀一幀的二維圖像的過程,我們需要用到渲染系統(Rendering);
- 讓一個個靜止的模型運動起來,做出惟妙惟肖的動作,形成連續的畫面,我們需要用到動畫系統(Animation);
- 物理的碰撞,各種力的作用,讓物體的運動更貼近真實世界,我們需要用到物理系統(Physics);
- 每一個游戲世界都有著自己的規則,還要有NPC來豐富游戲可玩性,這就需要用到腳本(Script)、狀態機(FSM)和AI;
任何一個游戲的操作都離不開人機交互,這其中又涉及一系列功能。以上的種種功能組合在一起便構成了游戲引擎的功能層。
資源層(Resource Layer)
游戲中有的不只是一行行的源代碼,還有各種格式的多媒體文件,如PhotoShop的PSD文件、3DSMAX的MAX文件,加載管理這一系列的圖形、圖像、音頻、視頻文件以及其他數據,就是資源層的任務了。資源層位于功能層之下,不斷為功能層提供數據,這就好像上面是一個畫家在畫畫,而資源層在下面不斷為其提供顏料。
核心層(Core Layer)
游戲引擎中最核心,最重要的一層就是核心層。核心層負責響應上面層次頻繁的調用,提供各種基礎功能,如內存管理、容器的分配、數據的運算、多線程的創建等等。
平臺層(Platform Layer)
平臺層是最容易被忽略的一層,一款游戲或者引擎可能被發布在不同的平臺上,會有不同的圖形接口;并且不同的用戶可能使用不同的硬件設備,如鍵鼠和手柄。適應不同的平臺,就是平臺層的任務。
第三方庫(Third Party Libraries)
中間件和第三方庫通過SDK(Software Development Kit)的形式或文件格式進行轉化。
為什么要分層架構?
為了使游戲引擎解耦并降低復雜度,每一層都將獨立完成自己的任務,底層為上層提供基礎服務,上層調用底層的工具。這樣的分層架構使得上層靈活,底層穩定,更有利于功能的更新和開發。
資源層
Photohop中的PSD文件、3DSMAX中的MAX文件等一般包含工具自帶信息,大量與引擎無關的數據,數據格式比較復雜, 直接使用會很大程度上降低效率。為了提高調度資源的效率,需要引擎在導入時將不同資源都轉換為資產(assets)文件。例如引擎中使用貼圖文件時,我們可能導入JPG、PNG格式的文件,但這兩種文件的壓縮算法對于GPU來說并不高效,直接在GPU中使用會浪費性能,所以其通常被轉換成dds格式再存入顯存中。
對于任意一個游戲人物,例如上圖的小機器人,可能需要綁定對應的材質、貼圖、網格、動畫等資源,定義一個Composite asset文件關聯這些資源,比如XML文件,并使用GUID(全局唯一標識符)進行標識管理。
實際運行時,游戲還需要用到資產管理器(Runtime Asset Manager),其根據資產的生命周期(Asset Life Cycle)對資產進行管理操作,資產的實時加載卸載、資源的分配、垃圾回收(GC)、延時加載等都包括在其中。
功能層
功能層的使用,使得每過一個tick時間,游戲中的虛擬世界就會前進一步。一個tick時間內,分別執行tickLogic()和tickRender()函數,其中邏輯方面的tickLogic()一般先執行,主要用于模擬游戲世界,包括輸入輸出的處理、相機視角位置的變換、碰撞的檢測等操作;用于繪制世界的tickRender()則依據tickLogic()計算出的各資產的位置情況進行渲染繪制。
功能層非常的復雜龐大,特別是涉及到網絡編程時,所以通常需要借助多線程計算。當前主流的多線程是將可以并行計算的任務拆分開來,分別放到多個線程運算,但若有不適用于并行計算的任務,其缺陷便顯露出了。在未來,引擎會將每個任務劃分為極小的可執行單元,將這一個個原子般的任務分配到多個線程中執行,更加高效的利用資源。
核心層
核心層為上層的所有邏輯提供一個基礎,它提供數學庫(如矩陣運算)、數據結構和容器(如二叉樹)、內存管理等工具。因為引擎的一切都是以效率為核心的,所以在進行數學運算時,可以使用近似運算或者SIMD(單指令多數據流,以同步方式,在同一時間內執行同一條指令)提高運算效率;至于數據結構和容器,編程語言中自帶的數據結構可能會出現一些問題,比如C++中的Vector在添加對象時開辟的儲存空間會成倍增長,在添加大量對象后,使用的儲存空間我們將無法得知,可能會產生內存空洞,而引擎中的數據結構更加方便內存的管理,提高訪問效率;引擎的內存管理和操作系統很相似,核心原理可以概括為:盡可能把數據儲存在一起,訪問時按順序訪問,處理時批量處理
平臺層
平臺層使得游戲能夠兼容如Xbox、Mac、Windows等不同平臺,手柄、鍵鼠等不同設備。平臺層通過使用Render Hardware Interface(RHI)來去除不同Graphics API(如DirectX11、DirectX12、OpenGL)之間的差異,使上層無需關心使用不同API可能會帶來的問題。
工具層
工具層一般以編輯器的形式(藍圖編輯器、材質編輯器等)呈現,可以使用不同編程語言開發(C++、C#、Html5等),以開發效率優先,它需要使不同使用者能夠創造游戲內容。因為很多游戲的數字資產是在不同DCC(Blender、MAYA等)中創建的,所以工具層一般包含導入、導出工具用于導入、導出游戲資源。