99国产精品欲av蜜臀,可以直接免费观看的AV网站,gogogo高清免费完整版,啊灬啊灬啊灬免费毛片

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

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

0
分享至

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

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


我來(lái)自完美世界《誅仙手游》項(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)行過(guò)技術(shù)嘗試。這其中包括對(duì) Unity 和其他 H5 引擎的探索,但由于未能達(dá)到預(yù)期的綜合目標(biāo),這些嘗試最終未能繼續(xù)推進(jìn)。

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

經(jīng)過(guò)約半年的調(diào)研和分析,發(fā)現(xiàn)無(wú)論是市場(chǎng)前景還是技術(shù)承載能力來(lái)看,都存在機(jī)會(huì)。因此,我們?cè)?2023 年 6 月正式啟動(dòng)小游戲的項(xiàng)目。經(jīng)過(guò)約半年時(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 來(lái)加速計(jì)算。然而,在小游戲平臺(tái)上,這些功能都會(huì)轉(zhuǎn)為主線程上的線性計(jì)算,不僅無(wú)法利用多線程優(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),而是通過(guò)擴(kuò)展 Web 的能力提升其性能上限,從而更好地支持 3D 游戲、vr/ar 圖像/視頻編輯等類似的需要高性能計(jì)算要求的任務(wù),其主要作用在于彌補(bǔ) JS 在算力方面的不足。JS 作為解釋性語(yǔ)言,運(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ì)算的問題,但也帶來(lái)了內(nèi)存挑戰(zhàn)。 在小游戲中,編譯后的 C++ 代碼會(huì)再次通過(guò) emscripten 編譯成 WASM。 在運(yùn)行時(shí),WASM 代碼會(huì)被再次編譯并實(shí)例化,而編譯+實(shí)例化的過(guò)程將會(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)行過(guò)詳細(xì)測(cè)試,結(jié)果顯示,盡管內(nèi)存大小存在一定浮動(dòng),但最終結(jié)論都接近于 10 倍。 因此,對(duì) WASM 進(jìn)行縮減是必要的。


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

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

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

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

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

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


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

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


再說(shuō)回到編譯的問題,編譯時(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)過(guò)上述處理,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ù)值。


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

首次進(jìn)行代碼分包是一個(gè)相對(duì)耗時(shí)的過(guò)程,需要進(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 基本一致,兩者均通過(guò)貝母 GC 進(jìn)行管理,但在細(xì)節(jié)上存在差異。


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


在初始化階段,需要為 UnityHeap 設(shè)定并設(shè)置一個(gè)大小,即預(yù)留內(nèi)存。 當(dāng)內(nèi)存不足的時(shí)候,系統(tǒng)會(huì)通過(guò) CopyArray 的方式進(jìn)行擴(kuò)容,此過(guò)程會(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)存峰值不超過(guò)預(yù)留內(nèi)存即可,即使略大于 768MB 也無(wú)妨。 同理,如若游戲內(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)來(lái)自于 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ù),來(lái)提前預(yù)留托管內(nèi)存,微小抖小平臺(tái)也沒有提供相關(guān)的接口進(jìn)行設(shè)置,但可以利用托管堆只增不降的機(jī)制,提前開辟一大塊托管堆內(nèi)存進(jìn)行復(fù)用,以減小內(nèi)存碎片,提高內(nèi)存的整體使用率。 通過(guò)對(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ì)象池來(lái)有效預(yù)防。

三是避免幀內(nèi)內(nèi)存峰值:在移植過(guò)程中,曾出現(xiàn)過(guò)單幀內(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)化來(lái)說(shuō),可以把小游戲視為對(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)生較大的位移。 通過(guò)對(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)過(guò)組合壓縮的站立動(dòng)作,腿部與地面的相對(duì)位移幾乎很小。


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


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


通過(guò)下圖可以看出,組合壓縮會(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)景中,目前通常通過(guò)光照貼圖(Lightmap)和光照探針(Light Probe)的方式實(shí)現(xiàn)效果。光照探針作為一種實(shí)現(xiàn) GI 的方式,相比 Lightmap,它更容易規(guī)避單幀內(nèi)申請(qǐng)過(guò)多內(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)越多,效果自然越好。 但是,過(guò)多的光照探針相比 Lightmap 內(nèi)存勢(shì)必也會(huì)翻倍。

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

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


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


上圖左側(cè)的圖像展示了三階球諧函數(shù)的原始效果。中間的四幅圖是經(jīng)過(guò)降維并還原后的結(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í)候, 與三階球諧相比,無(wú)論從色調(diào)還是明度,幾乎感受不出差距。


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

通過(guò)左上的兩個(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ì)在于可以通過(guò)全局劃分顯著減少 Draw Call 和面數(shù)。但值得注意的是,單場(chǎng)景、單幀內(nèi)對(duì)內(nèi)存的申請(qǐng)也會(huì)隨之增大。


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


值得注意的是,由于 web 環(huán)境下不支持多線程,所以 Unity 自帶的的流式紋理也是無(wú)法正常工作。所有資源的流式加載都需要手動(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 無(wú)法達(dá)到理想效果。LODGroup 主要表達(dá)的是單個(gè)物體隨距離遠(yuǎn)近的變化,而植被群落則表達(dá)為一個(gè)面。因此,我們通過(guò) CullingGroup 的方式,基于距離實(shí)現(xiàn)不同密度的實(shí)例化繪制。使用 CullingGroup 的主要目的是彌補(bǔ)實(shí)例化合批無(wú)法被剔除的問題。后面我也會(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)行合批的角色通過(guò)“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)能夠通過(guò) GPU skinning 在 GPU 端實(shí)現(xiàn)蒙皮計(jì)算,同樣可以減輕 CPU 壓力,并達(dá)到理想的性能標(biāo)準(zhǔn)。 因此,我們已經(jīng)用 GPU skinning 替代了原有的 VAT 方案,也節(jié)省了額外的工作量。

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


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


在團(tuán)結(jié)引擎下,可以對(duì) Shader 進(jìn)行優(yōu)化,包括直接通過(guò)引擎層面減少對(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 能夠通過(guò)排序,將使用相同 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)過(guò)大量測(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,主要通過(guò) 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)推薦
廣東:深化整治圈子文化、碼頭文化、拉幫結(jié)派、團(tuán)團(tuán)伙伙等問題

廣東:深化整治圈子文化、碼頭文化、拉幫結(jié)派、團(tuán)團(tuán)伙伙等問題

新京報(bào)
2025-07-23 21:26:38
太炸裂!地下捐精有多亂?捐精者:體內(nèi)交易僅 800元,包“售后”

太炸裂!地下捐精有多亂?捐精者:體內(nèi)交易僅 800元,包“售后”

柳絮憶史
2025-07-09 11:25:17
陳佩斯《戲臺(tái)》票房井噴,讓多少資方臉紅,黃渤這次又賭對(duì)了?

陳佩斯《戲臺(tái)》票房井噴,讓多少資方臉紅,黃渤這次又賭對(duì)了?

東方不敗然多多
2025-07-22 17:27:31
俄羅斯寧愿投降,也不敢先用核武器?一旦用了,最后誰(shuí)都跑不了!

俄羅斯寧愿投降,也不敢先用核武器?一旦用了,最后誰(shuí)都跑不了!

墨印齋
2025-07-16 22:10:10
全新謳歌Integra官圖發(fā)布,可選6MT,動(dòng)感溜背顏值高 | 酷樂汽車

全新謳歌Integra官圖發(fā)布,可選6MT,動(dòng)感溜背顏值高 | 酷樂汽車

CLauto酷樂汽車
2025-07-24 00:03:33
男籃亞洲杯中國(guó)隊(duì)可能取得名次前瞻:已有基本可能消息

男籃亞洲杯中國(guó)隊(duì)可能取得名次前瞻:已有基本可能消息

大眼瞄世界
2025-07-23 16:32:28
贏麻了,陳佩斯哭了,票房300倍逆襲,朱時(shí)茂百萬(wàn)投資可掙了不少

贏麻了,陳佩斯哭了,票房300倍逆襲,朱時(shí)茂百萬(wàn)投資可掙了不少

草莓解說(shuō)體育
2025-07-21 17:59:38
伊朗,集體逼宮開始了,內(nèi)奸要開始原形畢露了?

伊朗,集體逼宮開始了,內(nèi)奸要開始原形畢露了?

科技虎虎
2025-07-23 23:31:20
A股:不用等周四開盤,盤面非常明顯了,明天行情會(huì)這樣走!

A股:不用等周四開盤,盤面非常明顯了,明天行情會(huì)這樣走!

財(cái)經(jīng)大拿
2025-07-23 14:52:28
23個(gè)交易日后!西部實(shí)力更新:T0檔1隊(duì)、T1檔4隊(duì)、T2檔4隊(duì)!

23個(gè)交易日后!西部實(shí)力更新:T0檔1隊(duì)、T1檔4隊(duì)、T2檔4隊(duì)!

運(yùn)籌帷幄的籃球
2025-07-23 11:49:07
美媒曝光絕密錄音,特朗普罕見默認(rèn)、中國(guó)敢動(dòng)手,北京寸土不留?

美媒曝光絕密錄音,特朗普罕見默認(rèn)、中國(guó)敢動(dòng)手,北京寸土不留?

小青年淥淥
2025-07-22 17:58:43
奧運(yùn)體操冠軍楊威:如今終身需呼吸機(jī)維持生命,他到底經(jīng)歷了什么

奧運(yùn)體操冠軍楊威:如今終身需呼吸機(jī)維持生命,他到底經(jīng)歷了什么

優(yōu)趣紀(jì)史記
2025-07-19 14:43:19
藍(lán)叛將爆沖罷免傅崐萁,兩岸著名企業(yè)家支持罷免,白營(yíng)進(jìn)入花蓮!

藍(lán)叛將爆沖罷免傅崐萁,兩岸著名企業(yè)家支持罷免,白營(yíng)進(jìn)入花蓮!

正經(jīng)的燒杯1
2025-07-22 19:29:30
中國(guó)陸軍新型主戰(zhàn)坦克亮相國(guó)際軍事論壇:領(lǐng)先美俄一代

中國(guó)陸軍新型主戰(zhàn)坦克亮相國(guó)際軍事論壇:領(lǐng)先美俄一代

健身狂人
2025-07-23 08:50:40
女生男相!李湘母女在日本逛奢侈品店,王詩(shī)齡正面滿臉胡子好嚇人

女生男相!李湘母女在日本逛奢侈品店,王詩(shī)齡正面滿臉胡子好嚇人

娛樂小丸子
2025-07-22 20:50:25
Pura80起價(jià)4199元起,華為繼續(xù)以價(jià)換量

Pura80起價(jià)4199元起,華為繼續(xù)以價(jià)換量

時(shí)代周報(bào)
2025-07-23 20:50:39
李湘懶理二胎傳聞,日本度假回國(guó),穿裙子又白又壯,網(wǎng)友:像蟒蛇

李湘懶理二胎傳聞,日本度假回國(guó),穿裙子又白又壯,網(wǎng)友:像蟒蛇

冷紫葉
2025-07-23 23:35:02
公務(wù)員私人開銷也要嚴(yán)查了?這7類行為將被全流程監(jiān)督!

公務(wù)員私人開銷也要嚴(yán)查了?這7類行為將被全流程監(jiān)督!

鬼菜生活
2025-07-17 10:52:11
魔獸:最新刷坐騎BUG被發(fā)現(xiàn)!暴雪若沒修復(fù)明天國(guó)服也能用上!

魔獸:最新刷坐騎BUG被發(fā)現(xiàn)!暴雪若沒修復(fù)明天國(guó)服也能用上!

魔獸世界研究所
2025-07-23 20:04:30
美國(guó)猶太人資本巨頭貝萊德,已經(jīng)全面滲透中國(guó)市場(chǎng)!

美國(guó)猶太人資本巨頭貝萊德,已經(jīng)全面滲透中國(guó)市場(chǎng)!

華人星光
2025-07-20 14:19:00
2025-07-24 00:59:00
Unity incentive-icons
Unity
Unity中國(guó)官方帳戶
2331文章數(shù) 6722關(guān)注度
往期回顧 全部

游戲要聞

夢(mèng)幻西游【如夢(mèng)似幻】25日開服,這三個(gè)福利信息你了解了么?

頭條要聞

印度、孟加拉關(guān)切雅魯藏布江下游水電站工程 中方回應(yīng)

頭條要聞

印度、孟加拉關(guān)切雅魯藏布江下游水電站工程 中方回應(yīng)

體育要聞

英格蘭最紅球星 也是加勒比島國(guó)驕傲

娛樂要聞

汪峰森林北同游日本 各帶各娃互不耽誤

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

律師解析娃哈哈遺產(chǎn)案:遺囑是最大變數(shù)

科技要聞

別自嗨了!XREAL徐馳:AI眼鏡只有5歲智商

汽車要聞

德系大招放盡 場(chǎng)地極限測(cè)試全新奧迪A5L

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

教育
親子
本地
藝術(shù)
公開課

教育要聞

撿漏王誕生!黑龍江一考生389分上211鄭州大學(xué),讓人羨慕

親子要聞

醫(yī)學(xué)科普中醫(yī)脾胃育兒

本地新聞

這雙丑鞋“泰”辣眼,跪求內(nèi)娛不要抄作業(yè)

藝術(shù)要聞

故宮珍藏的墨跡《十七帖》,比拓本更精良,這才是地道的魏晉寫法

公開課

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

無(wú)障礙瀏覽 進(jìn)入關(guān)懷版 主站蜘蛛池模板: 民县| 天门市| 七台河市| 额尔古纳市| 望奎县| 宁德市| 罗甸县| 乌海市| 建平县| 张家界市| 岳池县| 攀枝花市| 沙雅县| 黄浦区| 浠水县| 谢通门县| 柞水县| 安塞县| 巩留县| 湄潭县| 台江县| 土默特右旗| 吉安县| 上虞市| 闻喜县| 铜川市| 鹤山市| 保康县| 中牟县| 黄陵县| 乐平市| 金平| 桑日县| 河南省| 康马县| 桂平市| 兰西县| 南岸区| 黄浦区| 沙洋县| 格尔木市|