遊戲引擎,3D引擎,物理引擎以及其他

一,遊戲引擎

在遊戲的啟蒙時代,其實是沒有遊戲引擎的,那時候的遊戲足夠簡單,類似於pacman之類的遊戲用頭髮想想也明白它根本用不到引擎這種概念。

隨著遊戲的複雜,對遊戲項目的複雜性和開發週期提出了更高的要求。首先是代碼的重用,為每個遊戲完全重寫一套代碼實在是不划算,而且伴隨代碼的重寫,測試的壓力也很大。其次是開發週期的壓力,商業競爭要求遊戲廠商要足夠快地推出更複雜更好玩的遊戲,把遊戲的內容硬編碼進代碼很快成為了一種很愚蠢的做法,因為這樣的話,簡單的修改就會牽扯很多地方。

於是,遊戲引擎的概念被提出,從遊戲架構上來說,3d的fps和2d rpg/slg可能是最早引入引擎概念的。而隨著技術的進步,引擎也越來越成熟。

那麼,遊戲引擎究竟做了什麼?

1 封裝了硬件平台和操作系統的功能調用。
大多數的通用引擎封裝了硬件平台和操作系統的功能調用,用統一的接口暴露給程序員,這樣便做到了跨平台。舉個例子,絕大多數的pc遊戲引擎都同時支持DirectX和openGL,為Windows編譯好的遊戲可以用DirectX,為Linux編譯的版本則顯然會自動使用openGL,而這些在某種層次上可以做到對程序員透明(當然,3D部分是最麻煩的,稍後說明)。

2 提供基本的功能服務。
遊戲引擎會提供一些基本的功能服務。
比如:
A 對文件系統的抽象,研發的時候直接讀取硬盤上的遊戲資源,發行版本自動改為讀取打包文件中的資源。
B 提供統一的對像管理,大部分是樹裝的層次結構。
C 內存管理,異常處理
D 遊戲腳本支持,把遊戲引擎的功能以腳本函數的方式暴露給腳本,這樣可以在腳本中編寫遊戲邏輯,操作遊戲引擎,大大方便了修改遊戲,舉個例子,WOW的UI部分就暴露了腳本接口,玩家可以自己用LUA編寫UI插件。

3 提供一個易擴充的框架結構
很多遊戲引擎是易擴充的,比如更換渲染模塊,添加物理引擎等,這樣可方便的針對項目量體裁衣。比如我需要DirectX不需要物理引擎,都可以自由定制。

4 提供研髮用的編輯器
很難想像沒有編輯器如何做遊戲。玩家熟悉的編輯器舉幾個例子:星際爭霸,魔獸爭霸3。

二,3D引擎

隨著技術的進步,現在的遊戲基本都使用3D技術來渲染畫面了,很多玩家根本就想不到即便是那些看起來是2D的遊戲,其實也是用3D模式渲染的。舉個例子,PS2的GS硬件上對純2D其實基本可以說沒有支持,PS2的2D遊戲,基本上都是用正交投影的3D模式渲染的,不論是SSF3.3還是GGXX都是這樣,平面的人物也是用三角形構成的。用3D有很多優勢,比如3D硬件速度快,支持alpha十分簡單等等。

如果大家學過D3D或者openGL,就會發現往屏幕上畫一個三角形,貼圖然後讓它轉起來,其實很簡單,關鍵的代碼不超過50行,那為什麼還要搞出3D引擎這種聽起來很華麗的詞彙呢?

工程學上,蓋一個平房和造帝國大廈,其規模和復雜性完全不在一個數量級。同理,往屏幕上畫一個三角形,貼圖然後讓它轉起來和大家玩到的FF12也完全不是一個檔次。現實生活中的遊戲太複雜了,以至於必須要3D引擎來完成很多工作。

1 場景。
遊戲引擎需要管理場景,也就是玩家所在的某個區域,不管是戰場還是道具屋。根據需要剔除不需要顯示的部分(對於FPS來說玩家身後顯然是永遠也看不到的)。

2 對象
遊戲引擎需要管理場景中的對象,比如一個木桶,一棵樹,在需要的時候向硬件提交對它們的渲染。

3 動畫
這裡的動畫指的是3D物體的動作。遊戲中有很多需要動畫的地方,例如草的擺動,開門,乃至於玩家控制人物的走動。很難想像手工寫代碼去計算構成玩家角色的每一個三角形的坐標變換。常見的方法都是在3D創作軟件中設置好動作然後導出,動作用專用的腳本來描述,3D引擎會對它進行解釋。

4 渲染
我這裡只就現在的先進的渲染方法來說。現在的pc和console硬件都具備了可編程的顯示硬件(不論是pc還是ps3,xb,xb360),叫做shader,shader分為兩種:vertex shader和pixel shader,更先進的硬件還會提供一種叫做geometric shader 的可編程硬件。 shader是在顯卡上的,它需要對應的代碼來運行,可以用shader的彙編或者專用的c語言來編寫shader(我有個朋友就喜歡用彙編直接寫shader - -b)。 shader使用起來沒有想像的那麼難,買本nv的CG教程,至多三天就能大概知道怎麼用了。

渲染每一個模型的時候,乃至於渲染模型的不同部分,動作的不同階段,3D引擎會自動選用適當的shader來執行渲染,手工完成這件事情幾乎是不可能的。


三,物理引擎

越來越多的玩家對遊戲的感官真實性提出了要求,他們追求更真實,於是仿真現實世界的物理引擎被提出來,物理引擎把遊戲中的物體的行為進行修飾,讓他們表現得看起來更真實。舉個簡單的物理引擎的例子:直到CS 1.6,遊戲玩起來還是那個樣子,然而CS:Source則不同,儘管只用了簡單的物理效果,我們已經可以用槍擊倒油桶之類的物體了。

那麼物理引擎究竟是怎麼工作的呢?依我看來物理引擎其實有兩個任務:物體之間的物理交互,物體自身的物理交互。

1 物體之間的物理交互。
比如剛才說的子彈擊中油桶,油桶被擊倒。這個比較簡單,CS中子彈是沒有體積概念的,這種碰撞計算很簡單。而其他的類型就不那麼簡單了,比如有立方體的碰撞,球體碰撞,乃至於曲面的互碰撞計算。不要忘了,這可是3D坐標系中的碰撞計算,回想一下你的空間解析幾何知識吧,這種計算對資源的消耗有多麼大。

2 物體自身的物理交互
如果我擊中了一塊玻璃,玻璃碎掉或者掃射旗子,旗子上被打出很多彈孔,這也需要物理引擎來幫忙,當然並不是必須的。但是玻璃的碎裂如果要求很真實,用物理引擎計算碰撞的結果就很必要了,碰撞是僅導致玻璃裂開還是粉碎,取決於碰撞的強度。

題外話:遊戲中的矩形玻璃最簡單的實現就是倆三角形一層材質,但是,計算機很笨,玻璃碎掉它不會自動增加多變形來表達每一個碎片。即便是物理引擎也不會做這件事情。現在都是需要程序員做額外的工作,未來DX10會提供geometric shader,做這個工作就會大大簡化。

四,其他

剛才說了很多理論和原理上的東西,那麼遊戲引擎,3D引擎,物理引擎是怎麼攢到一起的呢?前面說了,遊戲引擎是個框架,3D引擎,物理引擎被裝在裡面。更進一步說,其實物理引擎是受制於3D部分的。物理引擎要計算的物體數據是3D引擎提供的。

下面是一個簡化的frame渲染流程:

調整3D場景狀態(CPU)
處理輸入(CPU)
處理音效(SPU)
處理物理效果(CPU/SPE/PPU/GPU)
渲染3D(GPU)
渲染2D(GPU)

這個流程可以說基本上所有的遊戲都會有,而且我也把主要負責的模塊寫在了後面。從目前的技術來看,程序中能充分發揮多核,也就是多處理器優勢的部分,必定是能夠多線程操作的部分,就遊戲而言,網絡通信和處理音效是最容易多線程化的,因為它們本質上就必定是多線程實現。渲染基本上是單向的,CPU向GPU提出需求,除非CPU需要GPU的運算結果,這種情況不是很多。

好,現在剩下處理物理效果(CPU/SPE/PPU/GPU),對於沒有專用物理硬件的環境來說,目前常見的就是用CPU來算這種對浮點要求極高的任務,當然,PS3可以藉助CPU中的SPE。未來可能會有用GPU來協助的實現。當然最好的就是用專用硬件,傳說中的xx物理加速卡。這裡有個關鍵的問題,這種運算很難多線程,換句話說,渲染之前,必須等待物理計算完成,如果我們採用的是CPU來計算,很可能計算速度不夠,速度不夠的結果我就不用再多描述了,玩過遊戲的人都知道這意味著什麼。

好,基本上我要說的技術上的也就這麼多,現在回頭來看看某xxx老師的言論:“havok是負責物理,和丟幀沒什麼關係。”,希望大家可以笑一笑了。

via 滴水藏海

沒有留言:

張貼留言