軒轅傳奇引擎架構設計
Mackhan 2013/1/8
1、 產品的特徵說明和機器配置確定
2. 系統架構設計
2.1 進程線程結構
2.1.1 進程/線程的職責分配
2.1.2 進程/線程間通訊方式
2.2 整體框架
2.3 遊戲邏輯流程
3、渲染框架
3.1 引擎的選擇
3.2 軒轅傳奇的渲染
4、性能優化
5、內部工具
6、第三方組件和工具
7、重難點問題以及解決方案
8、兼容性問題
9、防作弊
10、穩定性和測試
1.產品的特徵說明和機器配置確定
《軒轅傳奇》是騰訊遊戲首款3D淺規則戰鬥網遊。遊戲是以上古戰爭為核心的中式玄幻網遊,Gamebryo引擎,輔以豐富的動態效果和光影效果,帶來出色的畫面層次感。根據我們遊戲需要達到的性能目標,以及對玩家硬體配置的調研我們制訂了軒轅傳奇的最低配置和推薦配置。《軒轅傳奇》配置需求如下:
最低配置
【CPU】 單核1G
【內存】 1GB
【顯卡】 Geforce5200系列或相同檔次顯卡 64M顯存
【音效卡】 支持Direct Sound的音效卡
【操作系統】WINDOWSXP/2000/7
【DirectX】 9.0C以上
推薦配置
【CPU】 雙核 Intel P4 2.8/Intel PE2140/AMD Athlon64x2 3600+
【內存】 2GB
【顯卡】 GeForce7600GS/GT ATI
X1600pro/XT或同檔次顯卡 256M 顯存【音效卡】 支持Direct Sound的音效卡
【DirectX】 9.0C以上
【操作系統】WINDOWSXP/2000/7
屏幕解析度:
1024*768及以上2. 系統架構設計
2.1 進程線程結構
客戶端有五個進程:自動更新、統一登陸、客戶端、Cross、IIPS進程。
客戶端有六類線程:主線程、網路線程、非同步更新線程、資源載入線程、聲音線程若干、IIPS微端下載線程若干。
2.1.1 進程/線程的職責分配
進程職責分配:
自動更新:完成客戶端發布版本補丁的下載和更新。
統一登陸:完成客戶端帳號登錄、伺服器選擇的登錄過程。
客戶端:遊戲主進程。
IIPS進程:微端資源後台下載。
線程職責分配:
主線程:遊戲主邏輯執行。
網路線程:接收遊戲伺服器發來的網路包,發送網路包到遊戲伺服器。
非同步更新線程:利用多核的特性,把主邏輯中的一部分運算量放到另外線程中。
資源載入線程:對於非同步載入的資源在此線程里排隊載入。
聲音線程:由fmod底層產生的聲音數據載入和播放線程。
IIPS微端下載線程:在軒轅客戶端中請求資源,由IIPSHost進程下載資源並和客戶端中IIPS線程通信。
2.1.2 進程/線程間通訊方式
進程通訊方式:
自動更新:直接創建和調用統一登錄進程,無數據通訊
統一登陸:直接創建和調用客戶端進程,通過共享內存傳遞連接數據
客戶端:接收統一登錄的共享內存的連接數據,登錄zone svr
線程通訊方式:
網路線程:通過Ring Buffer發送接收到的網路包到主線程,主線程發送網路包直接通過Windows消息發給網路線程隱藏窗口。
聊天網路線程:通過Ring Buffer發送接收到的網路包到主線程,主線程發送網路包直接通過Windows消息發給聊天線程隱藏窗口。
顯示線程:主線程通過Ring Buffer傳遞顯示命令 到顯示線程。
資源載入線程:主線程和資源載入線程通過事件和互斥量的方式同步載入列表。
聲音線程:由fmod內部管理聲音線程間的數據同步。
IPS微端下載線程:IIPS和軒轅客戶端通過Windows消息互相同步信息。
2.2 整體框架
相關模塊說明:
- Application: 應用程序介面,遊戲程序的入口,主要功能是用來運行框架和管理模塊.在這個模塊里完成windows主遊戲窗口的創建, 提供主循環入口,以EXE的方式實現;
- Game.LIB: 邏輯模塊,遊戲邏輯部分,包括遊戲地圖,角色,技能,網路消息處理,UI操作等;
- GraphicsModule: 圖形模塊,重寫了GB的渲染部分;
- SceneModule: 場景和模型模塊,包括載入/卸載地圖場景,創建/刪除Actor, 創建/刪除特效.模塊本身不提供管理的功能,對象的釋放和管理交給外部的調用邏輯模塊.
- NetModule: 網路模塊,通過分裝Tenio的網路組件,實現網路消息的收發功能;
- UIModule: UI控制項模塊,提供基本的UI控制項,供遊戲調用;
- ScriptBindingModule: 腳本模塊,提供腳本訪問功能;
- BaseModule:基本模塊,提供諸如向量,矩陣等基本的數據結構和定義;
- ScreenModule: 屏幕空間渲染模塊,為UI和屏幕空間的文本圖片渲染提供支持;
- InputModule: 提供鍵盤和滑鼠輸入的模塊;
- FileModule: 虛擬文件系統模塊,提供虛擬文件支持;
- AudioModule: 音效模塊,為邏輯模塊提供音樂音效播放的功能;
- FCFModule: 提供FCF配置文件解釋模塊,FCF是自定義的配置文件系統;
2.3 遊戲邏輯流程
a) 概述:
b) 流程
遊戲流程分為Login,SelectCharacter/CreateCharacter,MainProcedure幾個流程。流程劃分的原則,是指該流程具備全窗口獨佔顯示和獨立的邏輯控制流程,通過狀態機實現。
c) 其他核心模塊的介面
GameProcedure類通過提供一系列的靜態成員變數作為核心模塊和邏輯模塊的介面,管理和維護各個模塊。
d) 遊戲對象結構
遊戲中的對象變化通過狀態機來驅動,通過繼承和組合實現不同的對象。
e) 邏輯地圖和邏輯對象和渲染模塊的組織關係
所有的邏輯對象派生自Man,組合了一個Actor的渲染對象。
LogicMap(邏輯地圖),組合了一個Map的渲染對象
所有的Actor對象通過添加到SceneModule模塊的Actor管理器中管理,交給場景模塊管理和地形一起統一渲染。
f) UI模塊結構:
g) 數據模塊設計
提供一個數據中心的概念,將主要的數據管理器由一個數據中心作為統一的介面進行訪問和刷新.將數據分塊,而不是按照邏輯結構劃分,這樣具備更好的擴展特性。數據來源從本地的數據或網路消息獲得。
h) 網路模塊
所有的接收到的消息會壓到一個隊列里,消息輪詢的時候,交給相應的註冊處理函數來處理.所有的處理函數指針保存在一個map里.
3. 渲染框架
3.1 引擎的選擇
《軒轅傳奇》使用Gamebryo引擎的2.3版本。Gamebryo是一款主流的跨平台遊戲引擎,該引擎使用簡單比較成熟,有上百款商業遊戲使用Gamebryo開發。軒轅選用Gamebryo主要考慮了以下幾點:
1)穩定性:國內外有眾多遊戲都使用Gamebryo開發,包括許多MMORPG,在技術上是一款成熟穩定的遊戲引擎。其中Gamebryo2.3是比較經典的一個版本,也是使用最多的一個版本。
2)靈活性。Gamebryo提供完善的數據管理框架。相對Unreal,CryEngine等引擎雖然沒有統一的開發流水線但是可以很方便的擴展和修改,進行深度定製。例如軒轅傳奇的就使用了自己開發的渲染渲染系統,此外還開發了場景編輯器,技能編輯器,UI編輯器等多套定製的工具並完美和Gamebryo進行了集成,極大的提高了遊戲開發效率和實現了與眾不同的遊戲效果。
3)便捷性。Gamebryo在中國有著較完善的技術支持,此外Gamebryo有非常詳細的文檔,教程和社區,同時因為使用者眾多可以方便快速的獲得各種問題的解決方案。Gamebryo提供便捷的導出插件,美術可以快速預覽和導出美術資源。
3.2 軒轅傳奇的渲染
《軒轅傳奇》渲染框架如下:
Gamebryo開發流水線:
GameBryo的基本構成(其中軒轅傳奇主要使用GameBryo的RunTime,並做出了一些修改和添加了一些定製組件,此外在RunTime的基礎上又開發了大量編輯工具):
地形渲染:
軒轅的地形渲染以Chunk為單位渲染,每個Chunk有16x16x2個三角形,17x17個頂點。為了共享頂點索引數據,地形數據使用了多流。地形渲染使用紋理混合,支持高光,支持動態和靜態陰影,支持AO,支持Reflect,支持靜態點光效果,支持霧效,支持半透明漸變。因為針對軒轅俯視角為主的遊戲,同屏地形面數不會很高並且在目前顯卡上渲染瓶頸也主要在DP數而非面數上了,同時軒轅的地形數據使用多流在GPU中解壓生成顯卡匯流排也不是瓶頸所在,所以地形的渲染只使用了材質LOD而沒有使用面數的LOD,此外地形的渲染還使用了LightMap合併,材質排序等多種優化方式。具體結構圖如下:
地形的材質和材質LOD:
軒轅的地形採用五層紋理混合,最多可以設置五張地形紋理。此外五層地形紋理中的四層還可以設置高光貼圖(每個Chunk的高光貼圖只有一張RGBA分別對應四層的高光)。五層紋理之間的混合係數又有單獨的一張貼圖保存(也是使用貼圖的RGBA分別做每層紋理之間的半透明係數)。最後每個Chunk有兩張DXT1的LightMap,一張LightMap的R通道保存編輯器烘焙的陰影,G通道保存編輯器烘焙AO,一張LightMap保存點光光照和點光陰影。
軒轅地形效果如下:為了提高渲染效率,軒轅傳奇對較遠的地形(距離根據用戶配置調整)做了材質LOD優化。軒轅傳奇的LOD方式類似於CryEngine的材質LOD,每個地形在編輯器編輯好後會烘焙一張俯視角的全局地形效果圖(每個網格使用4個像素,每個chunk對應32x32的貼圖,再以256x256為單位合併成dxt1的貼圖,最大1024x1024的場景也不會超過2.6M),需要LOD的地形Chunk將使用這張全局地形貼圖做基本紋理,這樣一個Chunk只需要採樣一張紋理就可以渲染完,而渲染的實際效果肉眼很難區分。LOD效果如下圖,因為實際效果較難區分這裡是故意設置很近距離的地形就開始LOD起到對比作用:
角色和場景物件的渲染:
軒轅的角色和場景物件渲染使用了多種材質,Shader有UberShader自動編譯生成。Shader支持Glow,Reflect,高光,陰影,霧效,半透明漸變,三種頂點光照以及同時最多54盞點光。角色和場景物件的材質由角色本身的配置,遊戲當前圖形配置共同決定動態改變。角色一個DP最多支持40根骨骼硬體渲染。
各種特效渲染:
軒轅的特效包括使用自定義Shader的天空球,水,草,天氣,貼花(後期處理投影貼花和幾何體貼花),各種後期處理(例如景深,全屏泛光,Bump,,後期處理描邊等等)已經使用GameBryo的標準材質渲染管線的特效,支持粒子,Glow,Glass,Bump,Dark,Decal,Shadow,Fog等等。
4. 性能優化
軒轅傳奇在性能優化上做了大量工作也是軒轅傳奇相對同類型遊戲比較有優勢的地方。軒轅傳奇的優化主要在幀數、內存和容量方面。
幀數方面,在推薦配置上軒轅傳奇實現了最高400人同屏放技能也能保證遊戲流暢運行。在最低配置上軒轅傳奇也保證50人同屏放技能能流暢運行。
內存方面,軒轅傳奇實現了啟動時內存只佔用300M左右,任何極限環境(最高配置400人同屏放技能)下內存峰值在1G內存以內,長時間(1天以上)掛機內存無膨脹無泄漏。
容量方面,軒轅傳奇經過多次優化在有120張完全不同的地圖,2000件Avatar,上萬種怪物物件,高質量靜態陰影光照貼圖等前提下完整客戶端安裝控制在1.6G,微端安裝包更是只需要270M左右(極限微端只需要30M)。
幀數方面的優化(使用VTurn,Pix,GPA等工具分析和找出CPU、GPU的熱點和瓶頸進行優化):
1.動態調節配置和Shader分級:在遊戲中我們針對不同的硬體實現了三套Shader,其中超低配置的Shader對渲染進行了大幅優化(地形一層紋理,角色一層紋理等)主要用來滿足最低配置的電腦,中等配置和高等配置分別支持Shader2.0和3.0,此外同套Shader還有多種圖形配置參數默認的動態配置調節功能可以根據當前幀數動態優化圖形配置。玩家當前硬體對應哪套Shader和何種圖形配置基本在遊戲開始時由配置文件設定。
2.UI方面的優化:UI一直占渲染的很大比重,軒轅使用自主開發的UI框架,UI的渲染使用GB NiScreenElement渲染。在實際使用過程中我們發現GB的UI渲染存在Lock次數過多,DP過多問題。最終我們實現了自己的UI渲染,一方面通過畫布和程序優化將UI儘可能合併到一個批次渲染,另一方面所有UI使用一個不變的IB,而VB也只有一個在需要改動時Lock一次進行設置,從而避免了Lock
VB IB的等待和頻繁設置,極大程度的提高了UI的渲染效率有30%以上的性能提升。3.Shader的優化:在渲染效果的相關Shader開發完畢之後,我們會再次逐行分析和優化Shader,每次優化完後將編譯成彙編指令和優化前進行對比,檢查指令優化的個數和是否存在冗餘指令,如果還有優化空間會再次反覆迭代,在保證效果的前提下儘可能減少Shader指令。
4.角色優化:角色渲染幾乎所有的角色都由多個 Avatar 部件組成,而多個蒙皮會形成多個批次,同時多張貼圖也會形成多個批次,例如每個玩家m個部件,每個部件k個材質,同屏有n個玩家,渲染批次 = n*m*k。DP數是現代的顯卡的瓶頸,當同屏顯示大量玩家時高DP數會導致幀數大幅下降。針對角色的優化我們一方面合併蒙皮將模型數據合併成一個VBIB,另一方面合併材質,將各個部件的貼圖合併成一張。最終渲染一個角色只需要一個DP就可以完成,也保證了在400人同屏的情況下推薦配置也可以較流暢的運行遊戲。
5.LOD優化:軒轅LOD優化方面採用了非常多的方式,例如場景中區分主次物件,不同大小重要程度的物件(自動設置結合美術編輯器中手工指定)載入顯示的範圍不同半透明漸顯漸隱;骨骼更新LOD降頻,較遠的角色怪物等會降低骨骼更新的頻率;粒子LOD,粒子顯示的數量效果由和攝像機的距離覺得;材質LOD,地形,水,場景物件,角色的材質也加入LOD,距離較遠的角色,地形等使用單一DP的材質。例如下圖粒子LOD效果。
6. 減少渲染狀態切換次數:一方面對渲染列表進行了材質排序和Shader排序,減少渲染狀態切換次數。
另一方合併光照貼圖,地形按Chunk為單位通過一套較複雜的規則對該Chunk上的場景物件貼圖使用推箱演算法合併光照貼圖。每個物件只設置一次光照貼圖,多個相鄰的物件由於共享了LightMap紋理,大大減少了紋理切換率和顯存碎片,提高了顯存利用率。
最終平均減少了10%的狀態切換次數。
7.其他一些邏輯CPU方面的優化:此外軒轅傳奇還通過VTurn分析了CPU的各種熱點,對一些演算法進行了優化,例如拾取演算法,碰撞檢測等。
內存方面的優化(通過自主開發的Hook方式的內存工具找到內存的瓶頸進行優化):
1.動態載入Shader:軒轅傳奇一套配置的Shader最多可使用高達1200個Shader,在遊戲初始化時載入如此多的Shader是非常占內存的,針對這個問題軒轅採用了動態載入Shader的方式,在每個Shader真正使用時才載入,可以減少大約120M左右的內存空間。
2.動態載入UI的Nif特效:UI的Nif特效比較多,優化後只有該特效渲染時才載入並加入Cache中,當超過一段時間不使用則釋放;
3.字體優化:將字體作為緩存優化,不直接載入所有字體文件,減少了30M左右的內存空間。
4.網路包緩存優化:修改網路包緩存機制,平均減少30M左右內存空間,最大可減少120M左右內存空間。
5.ICON優化:因為ICON比較小,對ICON資源進行適當的壓縮和縮小,減少13M左右內存空間。
6.DX內存釋放:定期進行DX的內存回收。
7.bin表優化:修改了tagpathlist結構體,spelldata的載入方式,propertsets的map類型為NiTMap等,減少60M左右內存空間。
8.UI貼圖優化:所有的UI貼圖只在渲染的時候載入並加入緩存,一段時間不使用自動釋放。
9.其他一些優化:例如技能的USpellProperty優化,組件的Log.dll優化去掉後減少10M左右內存空間,美術資源的清理和合併,修改一些導致內存膨脹和冗餘的bug,對比Google,Windows和GB內存管理修改內存管理策略等等。
容量優化:
1.微端:集成IIPS實現數據動態下載後台載入,動態Lod逐級漸變等,最終實現了微端270M安裝包(最小可達30M)。對場景中各種資源指定智能的優先順序列表,完善的殘缺體驗,保證30K的下載速度玩家也可正常遊戲,100K的下載速度和完整包一樣體驗。遊戲中加入大量殘缺體驗和lod低精度資源保證即使本地資源不存在或者在下載過程中也不影響遊戲體驗。
2.地形挖空數據不導出:美術在編輯地形時會有很大的挖空面積,這部分數據可以不導出。
3.地形使用多流和壓縮優化:地形每個Chunk頂點索引是相同的,只需要全局一份使用多流共享;每個Chunk中頂點只有z不同,在Shader中只需要頂點的z和網格索引就可以計算出頂點的xyz;地形的兩套UV(基礎紋理和LightMap)也可以是用索引計算出來,每個頂點可以節省16個byte;地形頂點法線和頂點色可以各使用一個DWORD壓縮,在傳輸到顯卡的時候利用D3D自動轉成float,每個頂點共節省20個byte。最終地形容量節省了大約10%。
4.地形紋理優化:地形數據中容量最大就是地形的光照貼圖。軒轅的地形的光照貼圖總共有三張,一張是陰影貼圖,一張是AO貼圖還有一張是點光顏色和陰影貼圖。優化光照貼圖採用了三個方法,一個是編輯器導出時判斷Chunk的光照貼圖是否有效,如果一個Chunk沒有AO效果或者不受點光影響,那麼則不導出該Chunk的光照貼圖。第二個方法是合併光照貼圖,將陰影貼圖和AO貼圖分別存入一張DXT1的R和G通道,將點光貼圖存入另一樣DXT1中,這樣只需要兩張1/8壓縮比的貼圖就可以保存三張光照貼圖了。最後一個方法是調整光照貼圖的解析度,我們測試發現佔4%的512x512解析度的大光照貼圖容量佔用所用光照貼圖的50%,我們通過降低512x512貼圖的解析度保持或者提升小解析度光照貼圖的解析度,最終實現了在保證了顯示效果的前提下大幅降低了地形數據的容量。此外對地形的高光貼圖也進行了優化,地形的高光貼圖一開始是在編輯器導出時合併生成的,一個32x32的地圖高光貼圖就會佔用256M,優化後在客戶端載入地形時通過編輯器導出的高光貼圖混合係數後台動態合併,大幅減少了高光貼圖的容量。此外還進行了其他一些優化,最終優化後地形數據減少了80%的容量。
5. 內部工具
GameBryo引擎本身的編輯工具並不完善和易用,而使用Unreal等有強大編輯器的引擎開發又會面臨效果單一,很難擴展的問題。軒轅傳奇在既保證靈活性擴展性,又保證高效性和穩定性的前提下開發大量編輯工具,極大程度的提高了開發流水線的效率。其中主要的幾個工具如下:
- 場景編輯器:場景編輯器是整個流水線中最重要的工具,主要由美術和策劃使用,軒轅的場景編輯器實現了地形編輯(包括地形,水,草等),場景物件編輯,NPC和怪物放置,物件運行編輯,行走層編輯,天氣霧效編輯,天空球編輯,靜態陰影烘焙,AO效果烘焙,點光效果和點光陰影烘焙等等,使美術能在所見即所得的情況下快速高效的開發和修改場景。
- Shader編輯生成器:通過ubershader,利用腳本配置按照指定命名規則自動生成軒轅傳奇所用的Shader,總計自動生成大約2700個左右的Shader在遊戲中動態載入使用。
- 技能編輯器:主要由策劃和美術使用,軒轅的技能編輯器主要提供各種技能的編輯,每個技能對應一個CMT,每個CMT可以包括聲音層,特效層,動畫層,邏輯層等,而CMT也不僅僅應用於技能,包括角色動畫,換裝等多種效果也都可以實現,使用者可以快速所見即所得的編輯出所需要的效果,而導出數據也可以動態在遊戲中預覽。
- UI編輯器:主要由策劃和美術使用,使用簡單易上手,可以脫離遊戲編輯UI,同時支持編輯UINif特效,可以實現各種動態效果。
- AI編輯器:主要給策劃使用,軒轅傳奇中各種怪物,NPC,Boss的AI都通過AI編輯器以表格和圖標的形式編輯。
- 內存分析器:主要由程序使用,通過Hook的方式在遊戲運行時收集和分析內存信息,主要用於分析和解決內存泄漏和內存膨脹的問題以及內存優化。
6. 第三方組件和工具
軒轅傳奇主要使用的一些第三方組件和工具如下:
Fmod:聲音組件。
Bink:視頻組件。
DirectX SDK Pix For Window:微軟的渲染分析工具,主要分析渲染流程,找出瓶頸熱點和調試渲染錯誤。
Intel GPA:渲染優化分析功能,用於定位渲染瓶頸和解決渲染問題。
IntelParallelStudio:是Vtune(有獨立界面)和ThreadProfiler功能的合集,內嵌如VC中無獨立界面。其中包括Composer,Inspector(線程錯誤等),Amplifier三個工具。主要用於CPU相關優化。
7.重難點問題以及解決方案
在軒轅傳奇開發的過程中遇到很多難點問題,最終通過各種方法解決了這些問題,也實現了軒轅傳奇在各種配置各種環境下,基本都沒有卡頓現象保持較穩定的幀數。以下列出了一些比較重要和比較難解決的問題和解決方案:
- 資源載入優化的問題。軒轅傳奇的地形和資源數據採用後台載入的方式實現,根據用戶的硬體和配置載入主角周圍一定範圍的地形和資源。在開發過程中因為地形圖資源的分布不均,玩家硬體配置的不同和一些邏輯方面的原因(某個區域集中大量玩家或者會觸發劇情等),在玩家高速移動(坐騎,加速藥水)的情況,在場景中跑動可能會遇到卡頓的現象影響用戶體驗,這是不能接受的。通過使用測試工具例如VTurn,分析代碼,大量測試我們最終定位了很多影響載入的一些問題,其中比較主要的有線程的阻塞和空閑問題,載入任務分布和優先順序,緩存和緩存命中問題以及一些邏輯演算法上等。
- 針對線程問題,為了保證線程沒有空閑和Lock問題提高多線程載入效率,我們將原有多個IO線程讀取改為單一IO線程,串列讀取磁碟數據。此外重新檢查了多線程的線程鎖儘可能減少鎖的使用,多線程的任務投遞改為ringbuf不使用鎖提高多線程讀取的性能。
- 為了防止載入任務分布不均的問題,我們修改了後台線程載入任務隊列,限制每幀載入任務的吞吐量。同時又為了防止載入順序不當影響玩家體驗(例如玩家跑動地形沒載入沒顯示出來),我們將載入隊列改為LIFO方式,優先載入最近請求,對後台載入的資源劃分優先順序,例如地形和NPC優先載入,保證用戶的視覺體驗。
- 針對緩存問題,我們對遊戲資源進行區分,實現了統一的Cache機制,每種類型的資源都有不同的Cache策略,並進行了大量測試,設置了比較合適的緩存策略(緩存資源數量、時間等)提高緩存命中率和效率,此外還對一些數據利用系統緩存進行了優化,通過預載入的方式讓常用資源保持熱度。
- 在邏輯演算法上我們使用 Map 和 list 雙緩衝檢索資源,即具有列表的快速插入和刪除的性能,又具有 Map 的快速查找性能。此外有修改了大量影響載入的代碼和邏輯。
- Gamebryo多線程問題。軒轅傳奇是一個多線程遊戲,在遊戲過程中有海量數據要通過後台載入和後台處理,但是Gamebyro2.3雖然是線程安全的,但是引擎內部存在很多致命的多線程bug,因此軒轅傳奇一開始遇到很多很詭異的渲染錯誤和崩潰。通過大量測試和分析源碼,我們發現並解決了Gamebryo2.3版本中的很多多線程bug,對引擎的源代碼做出了一定修改後最終實現了軒轅傳奇高效穩定運行。
- 地形優化中遇到一些難點。例如前面地形優化中描述的為了最大程度減少地形容量,壓縮法線和頂點色每個頂點共節省20個byte同時又不降低效率,我們希望利用DX格式轉化自動將DWORD轉成float解壓,但是GameBryo的常規格式不能指定DWORD作為頂點色(必須是float,GB最終會遍歷每個頂點轉換成DWORD),所以我們使用了多流的方式,將一個Chunk的頂點坐標放在一個流,頂點色和法線放在另一個流傳入GPU,實現了優化。還有就是在地形合併LightMap時,我們合併時遇到了綠邊黑邊的問題,這是因為光照貼圖採樣方式都是線性採樣,將光照貼圖合成一張後,內部就會互相採樣過界。比較明顯的綠邊是因為點光貼圖採樣到了陰影AO貼圖,陰影AO貼圖的R通道是陰影G通道是AO,大部分陰影AO貼圖都是綠色。黑邊則是因為陰影AO貼圖採樣到其他貼圖。針對這個問題,我們在編輯器中烘焙每張光照貼圖時縮小一個像素縮一圈(多餘的一圈填充原始貼圖的顏色),在客戶端將UV縮小偏移的做法,這樣每張光照貼圖之間都有兩個像素的空間,解決了邊界的問題。
- 烘焙AO的問題。軒轅場景是有AO效果的,為了保證遊戲效率沒有使用實時SSAO而是在編輯器中烘焙靜態AO效果。一開始我們在編輯器中集成了Beast引擎烘焙,測試後發現速度實在太慢一個比較大的場景可能需要多台電腦烘焙幾天幾夜無法滿足快速開發的需要。因為我們在編輯器中開始自主開發烘焙AO系統,首先我們嘗試了射線法烘焙AO,開發完畢後發現效率還是比較低。然後我們又實現里利用GPU使用SSAO的方式烘焙靜態SSAO,實現後發現速度還可以但是精度效果無法滿足。最後我們發明了一種了球形光照分布的方式來烘焙AO,通過計算大量球形分布的光源,利用疊加ShadowMap的方式烘焙AO。最終測試發現這種方式烘焙速度極快,一個物件烘焙使用不到1秒一個比較大的場景也只需要幾分鐘就可以烘焙完畢,同時AO的效果也比較好,最終我們採用了這種烘焙方式並加入了一些後期的實時Gamma修正以供美術修改,並申請了專利。
- Cuda加速的問題。在軒轅開發的過程中我們發現軒轅的場景編輯器導出數據的速度非常慢,分析後發現瓶頸主要在貼圖格式的變換和DDS壓縮上,為了提高效率我們使用了Nvidia公司的Cuda庫利用GPU加速場景導出。加入後速度提高了幾十倍非常滿意,但是後續使用時發現在不同機器上導出的場景經常會有黑色塊出現,而是是低概率隨機出現。一開始測試發現如果導出時鎖屏,設備丟失就會出現這種現象,我們又加入保證編輯器導出時無法鎖屏的機制,但是最後使用時發現黑色塊的現象只是有所減少但是還是出現,最終通過測試確定是Cuda庫導致的,和Nvidia同事溝通後發現Cuda庫還不穩定,在不同配置的機器特別是較老的顯卡或者ATI的顯卡上還有很多bug。最終我們放棄了使用Cuda庫,而是通過烘焙時直接烘焙出需要格式以及修改一些導出演算法的方式提高編輯器導出效率。
- 後期處理描邊,投影貼花在個別電腦上出現斑點的問題。這個問題最終定位是因為在不同顯卡上深度buf精度不同導致,我們通過修改後期處理流程不直接使用浮點深度的方式解決。
8. 兼容性問題
軒轅傳奇軟體方面兼容win98,win2000,xp,win7等主流windows操作系統,同時兼容各種語言版本,主要在開發過程中對遊戲文字、編碼方式等做出了兼容。硬體方面軒轅傳奇兼容支持shader model 2.0及以上的顯卡,兼容早期的使用CPU計算VS的集成顯卡。因為陰影等效果的不同需求,軒轅傳奇針對Shader2.0和3.0分別編譯了兩套Shader,此外針對早期的集成顯卡例如G41,性能很低的獨立顯卡5200等又單獨實現了一套極致優化的Shader,並將市面上各種顯卡配置信息生成了配置文件,在遊戲啟動時會自動選取相應的Shader和配置。此外軒轅還實現了特有的動態自動配置調節系統,在遊戲中可以根據玩家的硬體配置和遊戲環境無縫動態調整遊戲配置,例如玩家在空曠的野外系統配置可能會很高,但是當玩家在百人千人城戰時系統又會動態調整到比較低的配置,始終保證玩家遊戲流程和幀數穩定。
9. 防作弊
在防作弊方面一方面依賴研發中心的反外掛系統方案保護,採用安全組提供Antibot系統,增強程序的防調試能力。另一方面軒轅還在遊戲內集成了自主研發的反外掛插件,在玩家遊戲時可以動態檢測和收集玩家是否作弊的信息並發送到伺服器上並自動分析出外掛和作弊情況。
10. 穩定性和測試
軒轅傳奇在遊戲穩定性上花了很多功夫。在代碼層面定期重構,每日構建,每日review(保證每行提交的代碼都經過檢查)。此外在遊戲內加入了大量的自動化測試、報警、日誌和上報功能,爭取在開發階段儘可能減少問題。在測試方面根據開發任務指定測試用例和測試環境,和測試同事制定各種測試用例。此外軒轅傳奇也開發了一些自動測試和數據代碼檢查的功能,最大程度保證客戶端的穩定性。
推薦閱讀:
※《Exploring in UE4》Session與Onlinesubsystem[概念理解]
※[翻譯]DOOM(2016) - Graphic Study
※Matrix and Transform Conversion 1/3
※[CppCon14] How Ubisoft Montreal develops games formulticore – before and after C++11
※[GDC16] Optimizing the Graphics Pipeline with Compute