騰訊天美GDC分享:千人同屏戰鬥,Unity DOTS在《重返帝國》中的應用
騰訊天美工作室群,在今年全球遊戲開發者大會(GDC) 上共做了4場分享。本演講為天美團隊於 2023 年 GDC 進行的非贊助核心演講(Core Concept)“千人同屏戰鬥:Unity DOTS在《重返帝國》中的應用“分享。
演講者簡介
肖健於 2014 年加入騰訊天美工作室群,目前擔任《重返帝國》客戶端組主程式。肖健在遊戲框架、Gameplay 和效能最佳化等方面都有著豐富的研發經驗。
侯倉健於 2014 年加入騰訊遊戲,曾參與多款手遊的研究與開發工作。侯倉健於 2019 年加入騰訊天美工作室群《重返帝國》團隊,目前主要負責遊戲引擎和工具鏈的開發工作。
以下是演講正文:
《重返帝國》是一款高品質全 3D SLG 手機遊戲,遊戲場景規模宏大,玩家操作自由多變,畫面上經常會出現超過1000個士兵一起戰鬥的場景。在有限的移動裝置效能上,需要同時兼顧效能與品質,團隊在嘗試過C#、C++以及DOTS等多種技術方案的選型與研究後,最終選擇了Unity DOTS。
Unity DOTS對於團隊可以說是一次敢為人先的選擇,當時市面上並沒有比較知名的使用這項技術的遊戲專案,所以這項技術最後呈現出來的效果其實是沒有太多參考的。其次,當時DOTS是處於一個比較初期的版本,Unity官方還在不停的修改和完善,這意味著團隊享受不到新的features,甚至可能需要處理一些潛在的隱患,這對團隊來說是不小的挑戰。
實戰分享
團隊一方面與Unity官方保持密切的合作與交流,另一方面經過多次的技術迭代與最佳化,最終在《重返帝國》專案上取得了很好的實踐效果,在移動裝置上為玩家呈現了極高品質的視覺效果。同時團隊也積累了一套行之有效的方法論,以下總結了幾點分享給大家。
當我們完成了整體的框架設計和核心的實現後,在進行效能分析的時候發現Job的併發性並不高,且worker存在大量的idle狀態,導致系統的整體耗時偏高。為此,我們專門開發了靜態分析工具輔助我們找出System之間的讀寫衝突與依賴,透過資料拆分、資料備份來解決衝突,讓耗時較高的Job能夠並行。
基於工具的分析,我們不斷的細化和調整,解決了資料的衝突依賴,顯著提高了Job的併發性,最終達到了我們相對滿意的並行效果。
之後,我們還將System按照功能進一步的細化拆分,把一部分Job的執行提前到與非ECS程式碼邏輯並行,進一步從整體上提高了我們的遊戲幀率。
在進行了Job並行性最佳化之後,我們發現在大地圖上拖動時存在由於Entity資源同步載入導致的一些耗時峰刺,這對玩家來說是體驗上的損失。所以我們針對Entity,使用邏輯與顯示分離,一方面讓資源可以非同步載入減少卡頓,另一方面也提升了單個chunk的記憶體利用率減少CPU的cache missing。
最後,我們在不影響效果的前提下,針對部分System進行邏輯降頻與錯幀(如移動邏輯計算相關的System降到12幀、耗時較高的MoveJob與AnimatorJob錯幀執行),讓整體的耗時更加平滑,並且有效的降低了遊戲的功耗。
效能最佳化
當時我們使用的是 Unity2019版本,Hybrid Render V1 版本,為了能更順利的將DOTS適配到我們的專案中,我們也在原始框架的基礎上,在資產與渲染方面也進行了大量的按需開發。
我們在接入 DOTS 技術棧時,主要面臨了以下3個問題:
1、資源相容性:因為在接入時已經處於專案中期,很多遊戲資產及對應的生產流水線已經成型,所以如何將已有遊戲資產轉變成可在 DOTS 技術棧中執行的資產,是我們需要解決的問題。
2、邏輯階段的基礎開銷過大:可能會導致千人同屏場景出現時出現卡頓。
3、渲染階段無法修改自定義的材質屬性:因為我們對於戰鬥場景的還原重度依賴 GPU Instancing 技術,所以需要很多自定義的材質屬性可以在執行時被複寫。
於是,我們針對以上問題逐個研究核心痛點,找到了適合我們專案的解決方案。
在資源相容性方面,在綜合評估了各種方案之後,我們決定實現一套自己的序列化和反序列化流程。我們的方案分為離線和執行時兩個階段:離線時,我們將遊戲中各類資產對應的prefab拆分成二進位制檔案和引用到的資原始檔;執行時,我們建立了一個“deserialize world”,用來把離線時生成的二進位制檔案和資原始檔反序列化,生成entity。當entity生成好後,我們再把它們移入default world進行執行。這樣我們既可以在資產製作階段使用我們熟悉的prefab,也可以減少執行時的轉換時間。
對於HybridRenderV1在邏輯階段的開銷過大,我們定位到了核心的瓶頸是主執行緒阻塞。比如整個生成合批資訊的過程都是放在主執行緒中進行的,這個過程有很大的最佳化空間。
我們的最佳化方向就是多執行緒化,充分利用移動端的多核優勢。其實在生成合批資訊時,不同的RenderMesh一定對應不同的batch,任務本身具有可多執行緒化的特性。所以如下圖所示,我們分配了一個較大的快取陣列,陣列的大小與執行緒數量和RenderMesh數量相關。多個執行緒並行完成對含有RenderMesh的Chunk進行篩選,並填入快取陣列的指定位置。因為在快取陣列中,每個執行緒都有自己的寫入空間,所以多執行緒並行時,不會產生資料寫入衝突。
我們還對遊戲中LOD的結構進行了最佳化。我們遊戲中的模型一般有4層LOD,在轉換成entity後,將會有6個相關的entities生成。
過多的entity不僅浪費記憶體,同時也會導致很多冗餘計算(比如同步位置資訊),而根據LOD的特點,我們可以只記錄單個LOD的資訊,在渲染時按需替換成應當顯示的LOD Mesh即可,這樣我們就可以把原本的4個LOD網格當做一個單獨的網格來對待。同時,我們也將LOD Group節點和Root節點進行了合併,Entity的數量也從原來的6個下降到2個,效能也有了提升。
這種方式帶來的一個額外好處是當我們更高層級的LOD還未載入完成或渲染壓力過大時,我們可以只載入低層級的LOD模型來顯示。
為了在C#中更改材質的Instance屬性,我們定義一個和Instance屬性完全匹配的IComponentData Struct,在資料對齊方面,我們遵循std140記憶體資料對齊原則。如下圖所示
在渲染執行時,我們根據entities的數量預先分配一塊大的快取,之後利用多執行緒把各個可見的entity的InstanceParam資料複製到Buffer中的指定位置。最後將整個快取直接提交至GPU,我們就可以按照傳統的GPU Instance方式來使用快取中的資料了。
在有了RenderMesh上的材質資訊和mesh資料之後,我們的InstanceBuffer也組織好了,這樣透過呼叫Unity的DrawMeshInstanced介面就可以進行渲染了。
以上都是團隊在實踐中不斷迭代總結出來的寶貴經驗,希望能對那些同樣想使用Unity DOTS技術的團隊能有所啟發。
演講者簡介
肖健(騰訊天美 T2 工作室客戶端組主程式)
肖健於 2014 年加入騰訊天美工作室群,目前擔任《重返帝國》客戶端組主程式。肖健在遊戲框架、Gameplay 和效能最佳化等方面都有著豐富的研發經驗。
侯倉健(騰訊天美 T2 工作室引擎負責人)
侯倉健於 2014 年加入騰訊遊戲,曾參與多款手遊的研究與開發工作。侯倉健於 2019 年加入騰訊天美工作室群《重返帝國》團隊,目前主要負責遊戲引擎和工具鏈的開發工作。
以下是演講正文:
《重返帝國》是一款高品質全 3D SLG 手機遊戲,遊戲場景規模宏大,玩家操作自由多變,畫面上經常會出現超過1000個士兵一起戰鬥的場景。在有限的移動裝置效能上,需要同時兼顧效能與品質,團隊在嘗試過C#、C++以及DOTS等多種技術方案的選型與研究後,最終選擇了Unity DOTS。
Unity DOTS對於團隊可以說是一次敢為人先的選擇,當時市面上並沒有比較知名的使用這項技術的遊戲專案,所以這項技術最後呈現出來的效果其實是沒有太多參考的。其次,當時DOTS是處於一個比較初期的版本,Unity官方還在不停的修改和完善,這意味著團隊享受不到新的features,甚至可能需要處理一些潛在的隱患,這對團隊來說是不小的挑戰。
實戰分享
團隊一方面與Unity官方保持密切的合作與交流,另一方面經過多次的技術迭代與最佳化,最終在《重返帝國》專案上取得了很好的實踐效果,在移動裝置上為玩家呈現了極高品質的視覺效果。同時團隊也積累了一套行之有效的方法論,以下總結了幾點分享給大家。
- Job資料依賴分析與最佳化,提升整個系統的併發性;
- 將部分ECS System的Job與非ECS邏輯並行,充分發揮多核;
- 邏輯資料顯示分離,提升chunk記憶體利用率,減少資源載入帶來的卡頓;
- 針對System進行邏輯降頻,保證效果同時也提升效能。
當我們完成了整體的框架設計和核心的實現後,在進行效能分析的時候發現Job的併發性並不高,且worker存在大量的idle狀態,導致系統的整體耗時偏高。為此,我們專門開發了靜態分析工具輔助我們找出System之間的讀寫衝突與依賴,透過資料拆分、資料備份來解決衝突,讓耗時較高的Job能夠並行。
資料依賴靜態分析工具
資料拆分解決寫入衝突
資料備份解決讀寫衝突
基於工具的分析,我們不斷的細化和調整,解決了資料的衝突依賴,顯著提高了Job的併發性,最終達到了我們相對滿意的並行效果。
資料依賴最佳化後Job的併發執行
之後,我們還將System按照功能進一步的細化拆分,把一部分Job的執行提前到與非ECS程式碼邏輯並行,進一步從整體上提高了我們的遊戲幀率。
ECS Job與非ECS邏輯並行
在進行了Job並行性最佳化之後,我們發現在大地圖上拖動時存在由於Entity資源同步載入導致的一些耗時峰刺,這對玩家來說是體驗上的損失。所以我們針對Entity,使用邏輯與顯示分離,一方面讓資源可以非同步載入減少卡頓,另一方面也提升了單個chunk的記憶體利用率減少CPU的cache missing。
邏輯顯示分離-資源非同步載入
最後,我們在不影響效果的前提下,針對部分System進行邏輯降頻與錯幀(如移動邏輯計算相關的System降到12幀、耗時較高的MoveJob與AnimatorJob錯幀執行),讓整體的耗時更加平滑,並且有效的降低了遊戲的功耗。
效能最佳化
當時我們使用的是 Unity2019版本,Hybrid Render V1 版本,為了能更順利的將DOTS適配到我們的專案中,我們也在原始框架的基礎上,在資產與渲染方面也進行了大量的按需開發。
我們在接入 DOTS 技術棧時,主要面臨了以下3個問題:
1、資源相容性:因為在接入時已經處於專案中期,很多遊戲資產及對應的生產流水線已經成型,所以如何將已有遊戲資產轉變成可在 DOTS 技術棧中執行的資產,是我們需要解決的問題。
2、邏輯階段的基礎開銷過大:可能會導致千人同屏場景出現時出現卡頓。
3、渲染階段無法修改自定義的材質屬性:因為我們對於戰鬥場景的還原重度依賴 GPU Instancing 技術,所以需要很多自定義的材質屬性可以在執行時被複寫。
於是,我們針對以上問題逐個研究核心痛點,找到了適合我們專案的解決方案。
在資源相容性方面,在綜合評估了各種方案之後,我們決定實現一套自己的序列化和反序列化流程。我們的方案分為離線和執行時兩個階段:離線時,我們將遊戲中各類資產對應的prefab拆分成二進位制檔案和引用到的資原始檔;執行時,我們建立了一個“deserialize world”,用來把離線時生成的二進位制檔案和資原始檔反序列化,生成entity。當entity生成好後,我們再把它們移入default world進行執行。這樣我們既可以在資產製作階段使用我們熟悉的prefab,也可以減少執行時的轉換時間。
資產Entity例項化
對於HybridRenderV1在邏輯階段的開銷過大,我們定位到了核心的瓶頸是主執行緒阻塞。比如整個生成合批資訊的過程都是放在主執行緒中進行的,這個過程有很大的最佳化空間。
我們的最佳化方向就是多執行緒化,充分利用移動端的多核優勢。其實在生成合批資訊時,不同的RenderMesh一定對應不同的batch,任務本身具有可多執行緒化的特性。所以如下圖所示,我們分配了一個較大的快取陣列,陣列的大小與執行緒數量和RenderMesh數量相關。多個執行緒並行完成對含有RenderMesh的Chunk進行篩選,並填入快取陣列的指定位置。因為在快取陣列中,每個執行緒都有自己的寫入空間,所以多執行緒並行時,不會產生資料寫入衝突。
多執行緒RenderMesh Batch
我們還對遊戲中LOD的結構進行了最佳化。我們遊戲中的模型一般有4層LOD,在轉換成entity後,將會有6個相關的entities生成。
過多的entity不僅浪費記憶體,同時也會導致很多冗餘計算(比如同步位置資訊),而根據LOD的特點,我們可以只記錄單個LOD的資訊,在渲染時按需替換成應當顯示的LOD Mesh即可,這樣我們就可以把原本的4個LOD網格當做一個單獨的網格來對待。同時,我們也將LOD Group節點和Root節點進行了合併,Entity的數量也從原來的6個下降到2個,效能也有了提升。
這種方式帶來的一個額外好處是當我們更高層級的LOD還未載入完成或渲染壓力過大時,我們可以只載入低層級的LOD模型來顯示。
LOD結構最佳化
為了在C#中更改材質的Instance屬性,我們定義一個和Instance屬性完全匹配的IComponentData Struct,在資料對齊方面,我們遵循std140記憶體資料對齊原則。如下圖所示
Instance屬性對齊
在渲染執行時,我們根據entities的數量預先分配一塊大的快取,之後利用多執行緒把各個可見的entity的InstanceParam資料複製到Buffer中的指定位置。最後將整個快取直接提交至GPU,我們就可以按照傳統的GPU Instance方式來使用快取中的資料了。
在有了RenderMesh上的材質資訊和mesh資料之後,我們的InstanceBuffer也組織好了,這樣透過呼叫Unity的DrawMeshInstanced介面就可以進行渲染了。
Instance Data Buffer
以上都是團隊在實踐中不斷迭代總結出來的寶貴經驗,希望能對那些同樣想使用Unity DOTS技術的團隊能有所啟發。
相關文章
- 騰訊天美大世界新作《重返帝國》曝光,加速SLG手遊紅海競爭
- 騰訊天美GDC分享:《王者榮耀》8年音訊設計回顧音訊
- 騰訊天美國際頂級IP遊戲招募:資深關卡策劃、戰鬥策劃遊戲
- 動畫利器-lottie在懂表帝App中的實戰應用動畫APP
- 因果推斷在騰訊遊戲中的應用遊戲
- 與阿里、網易、騰訊合作,正版《精靈寶可夢》在中國戰鬥力幾何?阿里
- 單元測試在Unity中的應用Unity
- 實戰分享,教你藍芽在小程式中的應用藍芽
- Unity GDC 2019 Keynote精彩要點:次時代圖形、實時光線追蹤、DOTSUnity
- 千人同屏即時戰爭策略手遊《萬國覺醒》國服定檔9月23日
- 網易伏羲GDC分享:在回合製紙牌遊戲中應用 AlphaZero 開發 AI遊戲AI
- Unity DOTS 走馬觀花Unity
- 頂級玩法設計師GDC分享:《戰神》如何做出最優秀的戰鬥系統
- 骨架屏(Skeleton Screen)在Android中的應用Android
- 張騰:騰訊雲融合通訊應用場景及案例分享
- 行業案例| MongoDB在騰訊零售優碼中的應用行業MongoDB
- Embedding在騰訊應用寶的推薦實踐
- 騰訊天美擬在美組建工作室 目標擴充全球市場
- 【GDC 21】《對馬島之魂》戰鬥系統講解
- GlusterFS在Kubernetes中的應用實戰(一)
- SQL解析在美團點評中的應用SQL
- 協同過濾在推薦系統中的應用
- win10玩帝國時代3老閃屏如何解決_帝國時代之3在win10中總是閃屏的解決步驟Win10
- 深度UPLIFT模型在騰訊金融使用者增長場景中的應用模型
- 談談戰雙的戰鬥機制設計趨同
- Apache Flink 在鬥魚的應用與實踐Apache
- AI在視訊遊戲中的應用AI遊戲
- 啟明雲端分享│2.1寸串列埠屏在拖地機上的應用串列埠
- 【AI in 美團】深度學習在OCR中的應用AI深度學習
- 帝國時代正版合作!新一代策略手遊《重返帝國》今日全平臺公測
- 騰訊在美直播平臺Trovo曝光
- 調研 4000+ 美國消費者,Unity Grow 帶來 2024 假日季應用營銷實戰指南Unity
- SQL解析在美團點評中是如何應用的?SQL
- LruCache在美團DSP系統中的應用演進
- TiDB Online DDL 在 TiCDC 中的應用丨TiDB 工具分享TiDB
- 戰鬥解析完成!「#COMPASS戰鬥天賦解析系統」公測開啟
- 講堂丨人工智慧在天體物理中的應用人工智慧
- 【GDC2023乾貨分享】開源軟體在引擎開發中的幫助