国产av一二三区|日本不卡动作网站|黄色天天久久影片|99草成人免费在线视频|AV三级片成人电影在线|成年人aV不卡免费播放|日韩无码成人一级片视频|人人看人人玩开心色AV|人妻系列在线观看|亚洲av无码一区二区三区在线播放

網(wǎng)易首頁 > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

《誅仙手游》小游戲:重度游戲在小游戲平臺(tái)下的探索與實(shí)踐

0
分享至

在 2025 年 5 月 24 日的 Unity User Group 北京站活動(dòng)中,完美世界《誅仙手游》客戶端負(fù)責(zé)人劉彥麟帶來分享《重度游戲在小游戲平臺(tái)下的探索與實(shí)踐》。本文為演講全文實(shí)錄,點(diǎn)擊閱讀原文,可下載演講 PPT 資料。演講視頻可通過下方鏈接地址觀看。

https://www.bilibili.com/video/BV1rzj9zVEGd/?spm_id_from=333.788.videopod.sections&vd_source=6ad5666ecbc7fe0e80d963da7e237d92

我來自完美世界《誅仙手游》項(xiàng)目組。本次分享的內(nèi)容聚焦于完美世界小游戲開發(fā)的經(jīng)驗(yàn),特別是小游戲下 WASM 和堆內(nèi)存的優(yōu)化方案,以及團(tuán)結(jié)引擎對(duì)于小游戲的技術(shù)支持。

我們的小游戲移植工作啟動(dòng)于 2023 年中旬。然而,早在幾年前,嘗試小游戲的想法就已經(jīng)萌生,并且進(jìn)行過技術(shù)嘗試。這其中包括對(duì) Unity 和其他 H5 引擎的探索,但由于未能達(dá)到預(yù)期的綜合目標(biāo),這些嘗試最終未能繼續(xù)推進(jìn)。

隨著 2022 年和 2023 年小游戲市場(chǎng)快速發(fā)展,以及大量“爆款”涌現(xiàn),其中不乏 MMO(大型多人在線)、SLG 等中重度游戲也表現(xiàn)出色。無論從產(chǎn)品、運(yùn)營(yíng),還是從技術(shù)角度來看,都促使我們決定再次嘗試小游戲平臺(tái)。

經(jīng)過約半年的調(diào)研和分析,發(fā)現(xiàn)無論是市場(chǎng)前景還是技術(shù)承載能力來看,都存在機(jī)會(huì)。因此,我們?cè)?2023 年 6 月正式啟動(dòng)小游戲的項(xiàng)目。經(jīng)過約半年時(shí)間的移植工作和產(chǎn)品調(diào)優(yōu),項(xiàng)目從 2024 年的 1 月開始對(duì)外進(jìn)行多輪 CCB 測(cè)試,今年 1 月,在微信小游戲平臺(tái)開啟正式 OB。目前,開發(fā)團(tuán)隊(duì)也正在進(jìn)行抖音平臺(tái)的性能調(diào)優(yōu),后續(xù)還會(huì)發(fā)行到更多小游戲平臺(tái)。

MMO 類游戲因其固有的特性,即使在硬件資源豐富的端游或手游平臺(tái)上,如果技術(shù)方案欠妥,亦可能產(chǎn)生相當(dāng)大的性能問題。這因?yàn)榇祟愑螒蛐枰髢?nèi)存,更大的計(jì)算承壓(包括 CPU 與 GPU),且部分功能需要多線程支持,而這些問題在小游戲平臺(tái)上將進(jìn)一步放大。這其中,內(nèi)存和 CPU 是相對(duì)關(guān)鍵的要素,亦是攻克小游戲平臺(tái)性能瓶頸的關(guān)鍵點(diǎn)。

在小游戲平臺(tái)上,iOS 設(shè)備的內(nèi)存普遍限制在 1.4G。然而,在手游平臺(tái)上,1.4G 僅是部分低端機(jī)型的內(nèi)存閾值,且此類機(jī)型在 APP 平臺(tái)上的占比極小。此外,小游戲平臺(tái)的 CPU 性能大約僅為手游的 1/3,并且不支持多線程,這使得小游戲平臺(tái)對(duì)密集性運(yùn)算更為敏感。然而,重度游戲恰恰需要大量計(jì)算,以及運(yùn)行時(shí)的內(nèi)存支持。同時(shí),Unity 中的許多功能也依賴多線程支持,例如動(dòng)畫、蒙皮、粒子系統(tǒng)和物理系統(tǒng)。一些功能甚至?xí)柚?Job System 來加速計(jì)算。然而,在小游戲平臺(tái)上,這些功能都會(huì)轉(zhuǎn)為主線程上的線性計(jì)算,不僅無法利用多線程優(yōu)勢(shì),還會(huì)搶占主線程資源,進(jìn)一步加重運(yùn)算壓力。

小游戲內(nèi)存主要分為幾個(gè)方面,其中影響最大是 UnityHeap、WASM 以及 GPU 顯存,這三者是移植后造成小游戲平臺(tái)內(nèi)存暴增的主要因素,只要妥善處理這三方面,整體內(nèi)存使用基本就能達(dá)標(biāo)。

WebAssembly性能優(yōu)化與內(nèi)存挑戰(zhàn)

WebAssembly 并非旨在替代 JavaScript(JS),而是通過擴(kuò)展 Web 的能力提升其性能上限,從而更好地支持 3D 游戲、vr/ar 圖像/視頻編輯等類似的需要高性能計(jì)算要求的任務(wù),其主要作用在于彌補(bǔ) JS 在算力方面的不足。JS 作為解釋性語言,運(yùn)行效率相對(duì)較低;而 WASM 則是編譯型的字節(jié)碼,性能更接近原生。

在一篇關(guān)于 WASM 與 JS 能耗對(duì)比的論文中,對(duì)比了在安卓平臺(tái)下,不同的手機(jī)瀏覽器中 WASM 與 JS 的能耗表現(xiàn),可以清楚地看到,JS 的能耗遠(yuǎn)遠(yuǎn)大于 WASM,最大能耗差異接近三倍。這意味著將 WebAssembly 用于 Web 應(yīng)用能顯著降低對(duì)移動(dòng)設(shè)備的能耗,最直接的影響就是降低發(fā)熱。

盡管 WASM 的性能接近原生,但兩者之間仍存在一定差距。下面這篇論文對(duì)多種 WASM 獨(dú)立運(yùn)行時(shí)的程序進(jìn)行了表征性研究,并從內(nèi)存、機(jī)器指令、緩存命中等方面與原生程序進(jìn)行了性能對(duì)比。最終的結(jié)論就是在獨(dú)立運(yùn)行時(shí)下,wasm 就會(huì)比原生程序降低 1.5~9.5 倍的性能。以上兩篇論文發(fā)表于 2022 年,具有很高的參考價(jià)值。

WASM 調(diào)用 WebGL API 時(shí),同樣也需要遵守瀏覽器的安全模型和策略。 WebGL 中每次調(diào)用 API 都會(huì)伴隨著一定開銷,這主要是由于安全驗(yàn)證所引入的。 在重度游戲中,WebGL API 調(diào)用極為頻繁,這意味著在 Web 平臺(tái)下,狀態(tài)切換的代價(jià)會(huì)更高。 因此,有必要盡可能減少 SetPass 調(diào)用以及與 WebAPI 的交互。

WASM 雖然解決了 JavaScript 在高性能計(jì)算的問題,但也帶來了內(nèi)存挑戰(zhàn)。 在小游戲中,編譯后的 C++ 代碼會(huì)再次通過 emscripten 編譯成 WASM。 在運(yùn)行時(shí),WASM 代碼會(huì)被再次編譯并實(shí)例化,而編譯+實(shí)例化的過程將會(huì)產(chǎn)生近 10 倍 wasm 文件大小的內(nèi)存占用。

例如,在誅仙第一個(gè) Chrome 版本中,WASM 文件大小為 90M,這意味著在運(yùn)行時(shí)產(chǎn)生了 900M 的內(nèi)存。 鑒于 iOS 小游戲內(nèi)存限制為 1.4GB,WASM 占據(jù)了 900MB,僅剩 500MB 可用空間,這對(duì)于 MMO 游戲而言是遠(yuǎn)遠(yuǎn)不夠的。 這部分內(nèi)存的實(shí)際最終大小與平臺(tái)、內(nèi)核版本也有關(guān)系。 我們?cè)诓煌氖謾C(jī)及不同瀏覽器上進(jìn)行過詳細(xì)測(cè)試,結(jié)果顯示,盡管內(nèi)存大小存在一定浮動(dòng),但最終結(jié)論都接近于 10 倍。 因此,對(duì) WASM 進(jìn)行縮減是必要的。

WASM 是代碼編譯的結(jié)果,因此,縮減 WASM 的本質(zhì)就是縮減代碼的使用。 Unity 項(xiàng)目的代碼主要由引擎代碼、package、第三方庫,以及游戲邏輯代碼組成。 可以通過 Player settings 對(duì)引擎代碼和托管代碼進(jìn)行剔除,但這種剔除并不徹底,部分代碼可能被引擎誤判為已使用,或因錯(cuò)誤操作產(chǎn)生引用,此時(shí)便需要進(jìn)行手動(dòng)剝離。 其中,最常見的就是 package 和第三方庫,特別是對(duì)于僅在 editor 下使用的代碼庫,要正確設(shè)置其程序集平臺(tái),保證其只在 editor 環(huán)境下使用。

除此之外,還有一些需要注意的方面。例如命名空間,小游戲中無法使用多線程,盡管使用多線程的代碼編譯無誤且運(yùn)行結(jié)果正確,但最終還會(huì)以單線程方式執(zhí)行,這會(huì)導(dǎo)致性能差異。因此,需要剔除線程類的命名空間。

對(duì)于 Job、Task 等與線程相關(guān)的,由于無法發(fā)揮其多線程優(yōu)勢(shì),也應(yīng)該直接代碼中剔除,并相應(yīng)的將功能改為單線程實(shí)現(xiàn),同時(shí)基于單線程優(yōu)化代碼算法。

另外,關(guān)于共享庫的使用,例如 json,在微信和抖音小游戲 SDK 當(dāng)中都包含一份 json,而一些第三方庫或 package 也可能包含或引用一份 json。對(duì)于此類問題,需要進(jìn)行手動(dòng)修改,確保項(xiàng)目存在一份 json。

關(guān)于代碼設(shè)計(jì)模式,優(yōu)秀的設(shè)計(jì)模式固然能提高項(xiàng)目的可擴(kuò)展性和可維護(hù)性,但是過度設(shè)計(jì)則會(huì)影響開發(fā)效率,尤其在小游戲環(huán)境中,過度的設(shè)計(jì)模式會(huì)使 WASM 變得更加臃腫。

WASM 作為相對(duì)低級(jí)的編譯目標(biāo),不支持泛型或模板等高級(jí)語言特性,生成的 wasm 代碼是針對(duì)具體類型的具體實(shí)現(xiàn)。雖然在編譯時(shí),可以設(shè)置編譯參數(shù),進(jìn)行編譯優(yōu)化,但對(duì)于過度復(fù)雜的設(shè)計(jì)模式,編譯優(yōu)化也無能為力。

舉例來說,將屬性寫為訪問器形式,編譯后會(huì)額外產(chǎn)生 2 個(gè)函數(shù)。 此外,foreach 循環(huán)還會(huì)額外產(chǎn)生包含 try-catch 的語句,這些都會(huì)增大 WASM 的體積。

除編譯問題,代碼方面還有許多值得注意的地方。比如,對(duì)于 string,運(yùn)行中產(chǎn)生的并且頻繁使用的 string,最好使用 intern 把它強(qiáng)制放到常量池。能使用常量就使用常量,比如 vector.one,沒必要再 new vector(0,0,0)。類似的問題還有很多。因此,需開發(fā)人員更加了解 IL2CPP,和 WASM 的機(jī)制,以便編寫出更高質(zhì)量的代碼。

再說回到編譯的問題,編譯時(shí)可以導(dǎo)出一張符號(hào)表,如右上這張圖 symbols.json 就是導(dǎo)出的明文符號(hào)表,左下就是該符號(hào)表的內(nèi)容。利用這張符號(hào)表就可以對(duì)其文件進(jìn)行解析,從而統(tǒng)計(jì)代碼中每個(gè)類的占比。圖右下,顯示了對(duì)符號(hào)表處理的結(jié)果,例如 uilabel 約占整個(gè) WASM 的 0.1%。開發(fā)團(tuán)隊(duì)會(huì)根據(jù)解析結(jié)果,從占比最高的類入手,逐步進(jìn)行分析和優(yōu)化,進(jìn)而實(shí)現(xiàn)代碼的剝離。圖右下的是我們最開始生成的 wasm 分析文本。

目前,此功能在團(tuán)結(jié)下已經(jīng)得到了非常大的改進(jìn),能夠可視化查看和對(duì)比兩版本的差別,極大地提高了研發(fā)效率。

經(jīng)過上述處理,WASM 文件已從最初的 90MB 精簡(jiǎn)至目前的 51MB,相當(dāng)于節(jié)省了 400MB 的內(nèi)存空間。

從圖右側(cè)可以看出,前述的每一步 WASM 精簡(jiǎn)方法,都對(duì) WASM 內(nèi)存產(chǎn)生了顯著的影響,然而,目前仍有 500 兆的 WASM 編譯內(nèi)存,這仍然是一個(gè)相當(dāng)大的數(shù)值。

即使通過代碼剔除,在游戲的實(shí)際運(yùn)行中,仍會(huì)存在一部分使用不到的函數(shù)。 事實(shí)上,每個(gè)小游戲平臺(tái)目前都提供了代碼分包的能力,可以將運(yùn)行時(shí)使用的函數(shù)收集到主包,未收集到的函數(shù)劃分到子包。 主包中所包含的函數(shù),才是整個(gè)游戲生命周期所使用的函數(shù)。 通常情況下,大部分游戲的主包代碼占比不會(huì)超過 50%,這意味著在最差的情況下,可以通過代碼分包將 WASM 的編譯內(nèi)存再次減半。

首次進(jìn)行代碼分包是一個(gè)相對(duì)耗時(shí)的過程,需要進(jìn)行充分的函數(shù)收集,以避免因收集不全導(dǎo)致函數(shù)被劃分到子包。頻繁地遠(yuǎn)程拉取子包函數(shù),會(huì)使游戲運(yùn)行變得異常卡頓。以上便是我們針對(duì) WASM 文件的所有優(yōu)化方法。

小游戲中的Unity堆內(nèi)存

小游戲中的堆內(nèi)存結(jié)構(gòu)與 APP 基本一致,兩者均通過貝母 GC 進(jìn)行管理,但在細(xì)節(jié)上存在差異。

在 web 平臺(tái),UnityHeap 被實(shí)現(xiàn)為一個(gè)連續(xù)的線性內(nèi)存空間數(shù)組,這部分內(nèi)存是通過瀏覽器分配的,并且在生命周期內(nèi)不會(huì)返還給瀏覽器。

在初始化階段,需要為 UnityHeap 設(shè)定并設(shè)置一個(gè)大小,即預(yù)留內(nèi)存。 當(dāng)內(nèi)存不足的時(shí)候,系統(tǒng)會(huì)通過 CopyArray 的方式進(jìn)行擴(kuò)容,此過程會(huì)產(chǎn)生一個(gè)內(nèi)存峰值,極有可能導(dǎo)致內(nèi)存崩潰。 例如,若預(yù)留內(nèi)存設(shè)置為 600 兆,由于內(nèi)存對(duì)齊,實(shí)際可能匹配到 608 兆,當(dāng)內(nèi)存不足進(jìn)行擴(kuò)容時(shí),該幀的內(nèi)存峰值可能達(dá)到 1.4GB,此時(shí)極易發(fā)生崩潰。 多數(shù)中重度游戲崩潰的原因,都是未能設(shè)置合理的預(yù)留內(nèi)存,從而在內(nèi)存擴(kuò)容時(shí)發(fā)生崩潰。

通常對(duì)于重度游戲,推薦的預(yù)留內(nèi)存值為 768 兆。 然而,并非必須嚴(yán)格遵循此值,只要確保內(nèi)存峰值不超過預(yù)留內(nèi)存即可,即使略大于 768MB 也無妨。 同理,如若游戲內(nèi)存峰值肯定達(dá)不到 768 兆,也可設(shè)置得更小,將內(nèi)存讓給其他空間,比如 js。 因此,設(shè)置預(yù)留內(nèi)存的目的是在合理的范圍內(nèi)使用內(nèi)存,避免觸發(fā)內(nèi)存擴(kuò)容和內(nèi)存浪費(fèi)。

托管內(nèi)存方面,與 APP 不同,托管堆(Managed Heap)來自于 Unity 堆,釋放后也只會(huì)返回給 Unity 堆,而不會(huì)返回給系統(tǒng)。 尤其在 Web 平臺(tái)下,托管堆具有只增不降的特性,這是一個(gè)顯著的差異。

托管堆不只一塊,會(huì)根據(jù)實(shí)際的內(nèi)存使用,在 Unity 堆中開辟多塊,那么就會(huì)產(chǎn)生托管堆的碎片。 盡管 Unity 沒有提供相關(guān)的設(shè)置或者相關(guān)的編譯參數(shù),來提前預(yù)留托管內(nèi)存,微小抖小平臺(tái)也沒有提供相關(guān)的接口進(jìn)行設(shè)置,但可以利用托管堆只增不降的機(jī)制,提前開辟一大塊托管堆內(nèi)存進(jìn)行復(fù)用,以減小內(nèi)存碎片,提高內(nèi)存的整體使用率。 通過對(duì)比圖示可以看出,上圖未進(jìn)行托管內(nèi)存預(yù)留時(shí),內(nèi)存分布較為分散; 而下圖進(jìn)行預(yù)留后,內(nèi)存碎片明顯減少,整體內(nèi)存消耗也隨之降低。

在內(nèi)存管理方面,GC(垃圾回收)在移動(dòng)平臺(tái)和 Web 平臺(tái)也存在顯著差異。 移動(dòng)平臺(tái)上,GC 在觸發(fā)后會(huì)立即執(zhí)行,而在 Web 平臺(tái),GC 僅在兩個(gè)特定時(shí)機(jī)觸發(fā): 每幀結(jié)束時(shí)會(huì)執(zhí)行少量 GC,以及切換場(chǎng)景時(shí)會(huì)執(zhí)行一次完整的 GC。 因此,在 Web 平臺(tái)的單場(chǎng)景尤其是單幀內(nèi),對(duì)內(nèi)存的使用要注意以下幾個(gè)方面:

一是設(shè)置合理的預(yù)留內(nèi)存: 避免因?yàn)轭A(yù)留內(nèi)存不足而造成 Copyarray。

二是避免內(nèi)存碎片:特別針對(duì)托管內(nèi)存,可以提前申請(qǐng)合理的使用空間并善用對(duì)象池來有效預(yù)防。

三是避免幀內(nèi)內(nèi)存峰值:在移植過程中,曾出現(xiàn)過單幀內(nèi)加載多張配置文件導(dǎo)致托管內(nèi)存暴增的情況。對(duì)于 native 內(nèi)存的暴增,最常見的原因是對(duì) AssetBundle 的加載。避免單幀內(nèi)存峰值的最佳方法是拆分?jǐn)?shù)據(jù),分幀加載。

尤其值得注意的是,強(qiáng)烈推薦使用小游戲平臺(tái)提供的 AssetBundle 接口,例如微信的 WXAssetBundle 和抖音的 TTAssetBundle。盡管早期項(xiàng)目曾嘗試不依賴小游戲平臺(tái)接口,但效果不佳。實(shí)踐證明,WXAssetBundle 或 TTAssetBundle 能真正利用文件系統(tǒng),從而顯著減少內(nèi)存占用。

四是,避免不當(dāng)使用像代理、匿名 lambda、閉包等,這些不規(guī)范的使用方式會(huì)頻繁產(chǎn)生堆內(nèi)存,進(jìn)而造成內(nèi)存碎片,降低堆的利用率。

基于Unity的優(yōu)化策略

許多常用的 Unity 優(yōu)化方法在小游戲和手游上同樣適用,對(duì)于優(yōu)化來說,可以把小游戲視為對(duì)性能要求更為嚴(yán)苛的手游,以下是一些手游和小游戲開發(fā)中被驗(yàn)證實(shí)用的優(yōu)化方法。

首先,針對(duì) Unity 資源件,可根據(jù)項(xiàng)目的實(shí)際需求進(jìn)行進(jìn)一步精簡(jiǎn)。 比如 anim,Unity 下,anim 可以針對(duì)不同文件,設(shè)置不同的誤差,采用不同的壓縮率。 但在相同的骨骼點(diǎn)下,它們所需的精度有所差異; 這意味著相同的誤差對(duì)于不同的骨骼點(diǎn)會(huì)產(chǎn)生不同的影響。

對(duì)于站立動(dòng)作,其通常是新玩家進(jìn)入游戲創(chuàng)角場(chǎng)景后看到的第一個(gè)動(dòng)作。 較大的壓縮誤差會(huì)使腳步與地面產(chǎn)生較大的位移。 通過對(duì)比 error 1.0 和 0.5 的設(shè)置,可以觀察到模型腳步與地面之間存在顯著差異。 盡管有些項(xiàng)目為了給新玩家提供更好的體驗(yàn),會(huì)在創(chuàng)角場(chǎng)景采用獨(dú)立的資源以保證更優(yōu)質(zhì)的效果,但這會(huì)額外增加包體大小,并可能導(dǎo)致頻繁的下載。

在《誅仙》項(xiàng)目中,我們采用了程序化方法對(duì)動(dòng)畫文件進(jìn)行組合性壓縮,針對(duì)不同動(dòng)作、不同肢體部位采用不同的壓縮誤差,以此實(shí)現(xiàn)效果與性能的平衡??梢钥吹浇?jīng)過組合壓縮的站立動(dòng)作,腿部與地面的相對(duì)位移幾乎很小。

具體來說,對(duì)于于站立動(dòng)作,在腿部會(huì)采用更低的誤差以減少滑步現(xiàn)象,而其他部位則會(huì)采用高誤差低精度的方式進(jìn)行處理,從而平衡整個(gè)動(dòng)作文件的大小并保障局部動(dòng)作效果。 經(jīng)過這種處理,動(dòng)作文件在腿部組合壓縮后會(huì)擁有更多的采樣點(diǎn),確保了腿部的精度。

同時(shí),在不影響手臂效果的前提下,組合壓縮會(huì)盡可能減少手臂的采樣點(diǎn),從而平衡了整體文件的內(nèi)存占用。

通過下圖可以看出,組合壓縮會(huì)更加擬合原始動(dòng)作文件,而 Error 1.0 和 Error 0.5 的文件則與原始動(dòng)作文件存在明顯的曲線偏差。

這種組合壓縮方法不僅能達(dá)到預(yù)期的效果,而且壓縮后的文件大小也非常理想,甚至在某些情況下會(huì)比 Error 1.0 的文件更小。

除了 AssetBundle,全局光照(GI)數(shù)據(jù)也是重度游戲,尤其是 MMO 類游戲消耗內(nèi)存的重要部分。在大場(chǎng)景中,目前通常通過光照貼圖(Lightmap)和光照探針(Light Probe)的方式實(shí)現(xiàn)效果。光照探針作為一種實(shí)現(xiàn) GI 的方式,相比 Lightmap,它更容易規(guī)避單幀內(nèi)申請(qǐng)過多內(nèi)存,也更便于實(shí)現(xiàn)離散的分幀加載,并且在制作 TOD 時(shí)更為便捷,顯著增加了靈活性。

然而,光照探針的靈活性也伴隨著內(nèi)存的問題。 一個(gè) Lightmap 中的采樣點(diǎn)可視為一個(gè) RGB 值(即 3 個(gè) float),而 Unity 中的光照探針使用的是三階球諧函數(shù)(3rd order Spherical Harmonics),這需要 9 個(gè)系數(shù),共計(jì) 27 個(gè) float。 對(duì)于 GI 而言,采樣點(diǎn)越多,效果自然越好。 但是,過多的光照探針相比 Lightmap 內(nèi)存勢(shì)必也會(huì)翻倍。

鑒于球諧函數(shù)用作 GI 通常是低頻信號(hào),其在空間中的變化是平滑且連續(xù)的,因此相鄰球諧函數(shù)的系數(shù)也極為相似?;谶@一特性,可以對(duì)場(chǎng)景中的探針進(jìn)行基于特征空間的降維壓縮,從而有效優(yōu)化內(nèi)存占用。

在二維空間中,可以通過找到一個(gè)特征軸來表達(dá)平面內(nèi)點(diǎn)的特征。同理,在三維空間中,也可以通過多個(gè)特征軸來表達(dá)三維空間的特征。因此,可以提取所有球諧函數(shù)的特征數(shù)據(jù),并將其映射到特征空間,再根據(jù)前 n 個(gè)特征來重構(gòu)原始數(shù)據(jù),從而實(shí)現(xiàn)高保真度的壓縮與還原。

從上圖右側(cè)可以看出,在不同特征數(shù)量下所表達(dá)的平面結(jié)果:特征數(shù)越多,越接近原始效果。在三維空間中,對(duì)于光照探針、環(huán)境光遮蔽(AO)等具有方向性的數(shù)據(jù),均可通過這種方法進(jìn)行降維壓縮。

上圖左側(cè)的圖像展示了三階球諧函數(shù)的原始效果。中間的四幅圖是經(jīng)過降維并還原后的結(jié)果,其中特征是疊加的。當(dāng)特征數(shù)量為一時(shí),它表達(dá)的是最主要的特征。隨著特征數(shù)的增加,細(xì)節(jié)也隨之增多。在中間的四張圖中也可以觀察到,隨著特征數(shù)量的增加,綠色部分變得更加明顯。當(dāng)特征數(shù)達(dá)到 13 時(shí),整體效果與原始球諧采樣幾乎一致。

當(dāng)然,也可以直接使用二階球諧函數(shù),但它會(huì)產(chǎn)生明顯的差異。從上圖左側(cè)的兩張圖可以看出,盡管二階球諧函數(shù)的色調(diào)與三階一致,但在明度上存在較大差異,并且這種差異會(huì)隨著建筑結(jié)構(gòu)、光源等空間復(fù)雜度的增加而愈發(fā)明顯。但是當(dāng)特征 =13 的時(shí)候, 與三階球諧相比,無論從色調(diào)還是明度,幾乎感受不出差距。

利用特征空間進(jìn)行降維的目的不僅是為了實(shí)現(xiàn)高還原度,更在于其在內(nèi)存方面具備顯著優(yōu)勢(shì)。

通過左上的兩個(gè)公式可以更直觀地看出,在大量探針的應(yīng)用場(chǎng)景下,基于特征空間的降維顯著降低了球諧階數(shù)對(duì)內(nèi)存的影響。具體而言,三階球諧函數(shù)每增加一個(gè)探針將穩(wěn)定增加 108 字節(jié)。而基于特征空間的壓縮方法,每次增加的字節(jié)數(shù)是特征數(shù)乘以 4。當(dāng)特征數(shù)等于 13 時(shí),每個(gè)探針僅增加 52 字節(jié)。并且此時(shí)幾乎可以還原原始探針的全部效果。

鑒于球諧函數(shù)主要用于表達(dá) GI 的低頻信號(hào),在實(shí)際應(yīng)用中可以適度縮小特征數(shù)。這樣做既能有效減少內(nèi)存占用,又能確保 GI 效果的質(zhì)量。

以上闡述了針對(duì)數(shù)據(jù)壓縮的方法。如前所述,小游戲?qū)?Draw Call 和 SetPass 更為敏感。在保證效果的前提下,LOD 是降低 Draw Call 和面數(shù)的最佳方法。

LOD 的優(yōu)勢(shì)在于可以通過全局劃分顯著減少 Draw Call 和面數(shù)。但值得注意的是,單場(chǎng)景、單幀內(nèi)對(duì)內(nèi)存的申請(qǐng)也會(huì)隨之增大。

我們重寫了 LODGroup 組件,在切換不同物體的同時(shí),能夠使其以流式的方法逐步加載卸載對(duì)應(yīng)的資源,這意味著僅加載當(dāng)前可見的資源,而非一次性加載所有資源。這種做法能夠平衡 LOD 帶來的內(nèi)存增加,有效管理和利用模型資源,從而達(dá)到平衡內(nèi)存、Draw Call 和面數(shù)的目的。

值得注意的是,由于 web 環(huán)境下不支持多線程,所以 Unity 自帶的的流式紋理也是無法正常工作。所有資源的流式加載都需要手動(dòng)重新實(shí)現(xiàn)。

除了實(shí)體,我們也對(duì)粒子做 LOD。 如上圖,隨著 LOD 等級(jí)變化,部分粒子發(fā)射器會(huì)被直接剔除,而另一些粒子并不會(huì)被剔除,但其粒子的產(chǎn)生速率與生命周期會(huì)明顯的縮短。 這種優(yōu)化方式在團(tuán)戰(zhàn)等特效密集的的場(chǎng)景中效果明顯,能在保證整體視覺效果的同時(shí),進(jìn)一步降低粒子消耗,優(yōu)化場(chǎng)景性能。

對(duì)于草地特效這類同質(zhì)物體群落,使用 LODGroup 無法達(dá)到理想效果。LODGroup 主要表達(dá)的是單個(gè)物體隨距離遠(yuǎn)近的變化,而植被群落則表達(dá)為一個(gè)面。因此,我們通過 CullingGroup 的方式,基于距離實(shí)現(xiàn)不同密度的實(shí)例化繪制。使用 CullingGroup 的主要目的是彌補(bǔ)實(shí)例化合批無法被剔除的問題。后面我也會(huì)介紹一種在團(tuán)結(jié)引擎下能夠進(jìn)行剔除的實(shí)例化合批的方法。

對(duì)于大型場(chǎng)景,還可以根據(jù)地塊和距離調(diào)整特征數(shù),讓不同的地塊使用不同的特征數(shù),可以進(jìn)一步降低探針內(nèi)存。比如近處使用 13 特征的 GI,盡可能還原效果,而中距離、遠(yuǎn)距離逐步降低特征數(shù),減少內(nèi)存消耗。

團(tuán)結(jié)引擎支持下的優(yōu)化與實(shí)踐

團(tuán)結(jié)引擎對(duì)小游戲的支持是開發(fā)團(tuán)隊(duì)當(dāng)前正在利用的重要引擎功能之一。借助團(tuán)結(jié)引擎,我們能夠進(jìn)一步降低內(nèi)存消耗。在將項(xiàng)目從 Unity 切換至團(tuán)結(jié)引擎后,開發(fā)團(tuán)隊(duì)在所有配置(包括 projectsetting,playersetting 等引擎層面的參數(shù)設(shè)置)均保持相同的前提下進(jìn)行了內(nèi)存對(duì)比。結(jié)果顯示,直接使用團(tuán)結(jié)引擎能夠?yàn)轫?xiàng)目額外節(jié)省約 60 兆的內(nèi)存,這一優(yōu)化效果非??捎^。

在團(tuán)結(jié)引擎中,托管代碼精簡(jiǎn)新增了“extreme”模式。相較于“high”模式,“extreme”模式在代碼剔除方面更為激進(jìn)。對(duì)于 MonoBehaviour 和 ScriptableObject,該模式僅保留項(xiàng)目中實(shí)際使用的類及函數(shù)。在我們的項(xiàng)目中啟用此選項(xiàng),能夠?qū)⒆罱K的 WASM 文件大小進(jìn)一步縮小約 10 兆字節(jié),這相應(yīng)地意味著可以節(jié)省約 100 兆字節(jié)的內(nèi)存。

Unity 中 Skinned Mesh Renderer 是一個(gè)性能消耗較高的組件,但在 MMO 類游戲中又必不可少。小游戲平臺(tái) CPU 性能大約只有 APP 的三分之一,因此需要盡可能減輕 CPU 的壓力。為應(yīng)對(duì)此挑戰(zhàn),我們將場(chǎng)景中可進(jìn)行合批的角色通過“Instancing + VAT”的方式進(jìn)行繪制,取得了較為理想的效果。

在驍龍 660 設(shè)備上,開發(fā)團(tuán)隊(duì)分別使用 GPU 和 CPU 兩種方法為 140 個(gè)角色進(jìn)行隨機(jī)動(dòng)畫播放測(cè)試。結(jié)果顯示,完全依賴 CPU 播放的幀率僅能達(dá)到 21 幀,而采用 GPU 播放動(dòng)畫則能穩(wěn)定保持在 30 幀。

在 2023 年中旬開始小游戲移植時(shí),缺少團(tuán)結(jié)引擎和 gpu skinning,因此 VAT(vertex animation texture)是一個(gè)相對(duì)性價(jià)比很高的解決方案。 目前,團(tuán)結(jié)引擎已經(jīng)能夠通過 GPU skinning 在 GPU 端實(shí)現(xiàn)蒙皮計(jì)算,同樣可以減輕 CPU 壓力,并達(dá)到理想的性能標(biāo)準(zhǔn)。 因此,我們已經(jīng)用 GPU skinning 替代了原有的 VAT 方案,也節(jié)省了額外的工作量。

從上圖中可以看出,在 108 個(gè)角色同屏的情況下,通過 GPU skinning 能夠穩(wěn)定達(dá)到 30 幀。而在相同場(chǎng)景下,使用 CPU skinning 的幀率只能維持在 10 幀以下。

WASM 調(diào)用 WebGL API 需遵循瀏覽器的安全模型和策略,每次調(diào)用 API 都會(huì)產(chǎn)生一定的開銷。這部分對(duì)開發(fā)者來說是黑盒的,我們唯一的辦法就是降低 dc 和 setpass,也就是降低游戲的復(fù)雜度。

在團(tuán)結(jié)引擎下,可以對(duì) Shader 進(jìn)行優(yōu)化,包括直接通過引擎層面減少對(duì) WebGL API 的調(diào)用。這種方法對(duì)于某些低系統(tǒng)設(shè)備效果非常顯著。我們?cè)?iOS 16.4 系統(tǒng)上進(jìn)行了不限幀測(cè)試,包括野外團(tuán)戰(zhàn)和副本。開啟上圖所示選項(xiàng)后,幀率能夠提升大約 8 到 10 幀。

在合批方面,SRP Batcher 能夠通過排序,將使用相同 Shader 的物體放到一起去繪制,從而使每個(gè)批次僅調(diào)用一次 ApplyShaderPass,減少了重復(fù)設(shè)置 Shader 的時(shí)間消耗。

目前,項(xiàng)目主要采用的合批方式仍是 SRP Batcher。運(yùn)行時(shí)相比 StaticBatch 會(huì)有一定的消耗,因?yàn)橐婷繋瑫?huì)根據(jù)可見的 renderers 生成 render nodes。然而經(jīng)過大量測(cè)試發(fā)現(xiàn),在我們項(xiàng)目中,SRP Batcher 和 static batch 對(duì)于幀率的影響是相近的。鑒于靜態(tài)合批會(huì)額外增加內(nèi)存或包體大小,因此我們?nèi)詫?SRP Batcher 作為主要的合批方式。

后續(xù)團(tuán)結(jié)引擎將推出一種更高效的合批方式,即 GPU Resident Drawer。目前團(tuán)隊(duì)正配合團(tuán)結(jié)的同學(xué)進(jìn)行性能測(cè)試。理論上 GPU Resident Drawer 的執(zhí)行效率將高于 SRP Batcher,主要通過 BRG(Batch Renderer Group)進(jìn)一步提高渲染效率,并且根據(jù)小游戲的特性,在單線程上做了特定的優(yōu)化。只要場(chǎng)景中的物體是靜態(tài)的,它的 buffer 就不需要更新,會(huì)長(zhǎng)期駐留在 GPU 上。因此,與 SRP Batcher 相比,GPU Resident Drawer 在運(yùn)行時(shí)也能減少一定的計(jì)算消耗。

GPU Resident Drawer 的主要目的是對(duì)于復(fù)雜場(chǎng)景的優(yōu)化,尤其適用于場(chǎng)景中存在大量可以實(shí)例化合批的分散物體的情況。如果直接使用實(shí)例化進(jìn)行合批,由于缺乏剔除,反而可能導(dǎo)致負(fù)優(yōu)化。同樣,若在 CPU 端自己實(shí)現(xiàn)剔除后再調(diào)用 Graphic DrawInstance 進(jìn)行繪制,也會(huì)加重 CPU 端的計(jì)算壓力,同樣可能造成負(fù)優(yōu)化。

而 GPU Resident Drawer 的一個(gè)重要特性就是解決了剔除問題。上方的表格是主城的測(cè)試結(jié)果,在 Drawcall、Setpass 以及功耗方面都有了非常明顯的降低。

以上就是我今天的分享 謝謝大家。

Unity 官方微信

第一時(shí)間了解Unity引擎動(dòng)向,學(xué)習(xí)進(jìn)階開發(fā)技能

每一個(gè)“點(diǎn)贊”、“在看”,都是我們前進(jìn)的動(dòng)力

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點(diǎn)推薦
房地產(chǎn)即將會(huì)下猛藥,你準(zhǔn)備好了嗎?

房地產(chǎn)即將會(huì)下猛藥,你準(zhǔn)備好了嗎?

恪守原則和底線
2026-01-04 05:40:03
員工節(jié)假日嫖娼遭行政拘留,隱瞞7年后被銀行發(fā)現(xiàn)并辭退!男子不服官司一路打到高院,法院:辭退決定合法有效

員工節(jié)假日嫖娼遭行政拘留,隱瞞7年后被銀行發(fā)現(xiàn)并辭退!男子不服官司一路打到高院,法院:辭退決定合法有效

揚(yáng)子晚報(bào)
2026-01-04 17:30:03
小區(qū)大媽擾民2年,直到她孫女考編政審,他帶著80份證據(jù)找考官

小區(qū)大媽擾民2年,直到她孫女考編政審,他帶著80份證據(jù)找考官

黑貓故事所
2025-12-23 22:22:19
著名脊柱外科專家、院士候選人,被官宣雙開!

著名脊柱外科專家、院士候選人,被官宣雙開!

梅斯醫(yī)學(xué)
2026-01-05 07:54:59
“上午小寒,凍死牛,下午小寒,穿單衣”,2026年小寒在哪?

“上午小寒,凍死牛,下午小寒,穿單衣”,2026年小寒在哪?

小談食刻美食
2026-01-04 10:36:26
好孩子!維爾茨賽后誠(chéng)實(shí)表態(tài)引發(fā)熱議,球迷:要臉,好感陡增

好孩子!維爾茨賽后誠(chéng)實(shí)表態(tài)引發(fā)熱議,球迷:要臉,好感陡增

凌空倒鉤
2026-01-05 14:46:27
斯托克頓不攔著 歷史助攻王也是詹姆斯的

斯托克頓不攔著 歷史助攻王也是詹姆斯的

北青網(wǎng)-北京青年報(bào)
2026-01-05 12:06:14
金價(jià):今日金價(jià)990/克!不出意外的話,明天或迎來更大級(jí)別行情

金價(jià):今日金價(jià)990/克!不出意外的話,明天或迎來更大級(jí)別行情

今日美食分享
2026-01-05 14:15:20
老人離世切記:別先聯(lián)系殯儀館,第一步錯(cuò)了,子女白忙活還多花

老人離世切記:別先聯(lián)系殯儀館,第一步錯(cuò)了,子女白忙活還多花

好笑娛樂君每一天
2026-01-05 12:15:02
董潔在商場(chǎng)被偶遇,夸贊她氣質(zhì)極好,親和力十足,穿搭時(shí)尚又減齡

董潔在商場(chǎng)被偶遇,夸贊她氣質(zhì)極好,親和力十足,穿搭時(shí)尚又減齡

影視口碑榜
2026-01-05 10:33:19
最高9.8分,美劇史上的入門級(jí)Top.10,建議收藏

最高9.8分,美劇史上的入門級(jí)Top.10,建議收藏

i書與房
2026-01-05 11:10:29
45歲富哥“北京肖哥”去世,前一天還曬老婆,死因曝光仇人都惋惜

45歲富哥“北京肖哥”去世,前一天還曬老婆,死因曝光仇人都惋惜

嫹筆牂牂
2025-12-31 07:07:52
工齡退休確實(shí)火了!按工齡退休,觸動(dòng)億萬普通人的心聲

工齡退休確實(shí)火了!按工齡退休,觸動(dòng)億萬普通人的心聲

另子維愛讀史
2026-01-04 22:07:42
趙露思不尷尬嗎?寶格麗900萬珠寶給她戴了,卻一身廉價(jià)味顯難堪

趙露思不尷尬嗎?寶格麗900萬珠寶給她戴了,卻一身廉價(jià)味顯難堪

嫹筆牂牂
2025-12-23 07:09:08
馬琳王皓職位曝光,王勵(lì)勤妥協(xié)了,教練組將官宣,秦志戩總教練

馬琳王皓職位曝光,王勵(lì)勤妥協(xié)了,教練組將官宣,秦志戩總教練

卿子書
2026-01-05 08:43:41
曝:成龍與女兒吳卓林關(guān)系破冰,給女兒介紹業(yè)務(wù),吳卓林回應(yīng)了!

曝:成龍與女兒吳卓林關(guān)系破冰,給女兒介紹業(yè)務(wù),吳卓林回應(yīng)了!

娛圈小愚
2026-01-05 09:10:08
黃東璧同志逝世

黃東璧同志逝世

新京報(bào)政事兒
2026-01-05 13:57:53
哥倫比亞加強(qiáng)總統(tǒng)佩特羅安全保護(hù)

哥倫比亞加強(qiáng)總統(tǒng)佩特羅安全保護(hù)

國(guó)際在線
2026-01-04 16:31:11
紀(jì)委強(qiáng)調(diào):公務(wù)員醉駕不再一律“雙開”,這3類情節(jié)可不追刑責(zé)

紀(jì)委強(qiáng)調(diào):公務(wù)員醉駕不再一律“雙開”,這3類情節(jié)可不追刑責(zé)

細(xì)說職場(chǎng)
2025-07-10 06:55:06
洪都拉斯總統(tǒng)放狠話!中方若不給足夠利益,一個(gè)月后考慮斷交!

洪都拉斯總統(tǒng)放狠話!中方若不給足夠利益,一個(gè)月后考慮斷交!

達(dá)文西看世界
2026-01-04 16:40:40
2026-01-05 15:24:49
Unity incentive-icons
Unity
Unity中國(guó)官方帳戶
2413文章數(shù) 6729關(guān)注度
往期回顧 全部

游戲要聞

《ARC Raiders》公開匹配機(jī)制:按玩家"好戰(zhàn)"程度分區(qū)

頭條要聞

媒體:美國(guó)捉拿馬杜羅后 多位專家示警賴清德

頭條要聞

媒體:美國(guó)捉拿馬杜羅后 多位專家示警賴清德

體育要聞

女子世界第一,9年前在咖啡店洗碗

娛樂要聞

黃宗澤奪雙料視帝,淚灑頒獎(jiǎng)臺(tái)憶往昔

財(cái)經(jīng)要聞

李迅雷:擴(kuò)內(nèi)需要把重心從"投"轉(zhuǎn)向"消"

科技要聞

雷軍新年首播:確認(rèn)汽車業(yè)務(wù)降速

汽車要聞

不是9S是8X!極氪全新高性能旗艦SUV命名官宣

態(tài)度原創(chuàng)

家居
藝術(shù)
教育
房產(chǎn)
公開課

家居要聞

白色大理石 奢華現(xiàn)代

藝術(shù)要聞

19幅 列賓美院學(xué)生優(yōu)秀畢業(yè)作品

教育要聞

收藏:山東2026高中綜評(píng)操作教程(教師端)

房產(chǎn)要聞

再次登頂海南樓市!超越阿那亞的,只有阿那亞!

公開課

李玫瑾:為什么性格比能力更重要?

無障礙瀏覽 進(jìn)入關(guān)懷版