2024 抖音歡笑中國(guó)年之AnnieX互動(dòng)容器創(chuàng)新玩法解析
業(yè)務(wù)背景
AnnieX作為字節(jié)一方游戲統(tǒng)一容器,服務(wù)字節(jié)內(nèi)部電商、直播、UG等跨端場(chǎng)景業(yè)務(wù)。在字節(jié)一方游戲互動(dòng)場(chǎng)景,有大量的一方游戲業(yè)務(wù)對(duì)容器有特定的流量、端能力和游戲優(yōu)化的訴求。因此我們不斷深入互動(dòng)游戲業(yè)務(wù)特點(diǎn),為字節(jié)游戲提供完善游戲端能力和流量運(yùn)營(yíng)能力,同時(shí)提供游戲互動(dòng)場(chǎng)景極致優(yōu)化能力,提升游戲業(yè)務(wù)的整體性能。
養(yǎng)羊賺錢(qián)
種樹(shù)賺錢(qián)
萌寵旅行家
新周中/周末
今年是抖音春節(jié)活動(dòng)的第7年,我們跨端容器已經(jīng)具備豐富的端能力的同時(shí),也提供了一些對(duì)于跨端容器常規(guī)的一些優(yōu)化手段,例如:資源預(yù)加載、網(wǎng)絡(luò)預(yù)請(qǐng)求等手段,并且在往年春節(jié)活動(dòng)中取得了不錯(cuò)的優(yōu)化效果。而今年,我們希望能夠基于游戲場(chǎng)景,逐漸深挖游戲互動(dòng)場(chǎng)景的特點(diǎn),為春節(jié)等游戲場(chǎng)景去提供更加豐富和專(zhuān)業(yè)的游戲優(yōu)化能力。
春節(jié)-神龍尋寶
春節(jié)-守衛(wèi)現(xiàn)金
春節(jié)-搖福簽
春節(jié)-神龍?zhí)綄?/span>
互動(dòng)套件介紹
因此我們基于24年抖音春節(jié)活動(dòng),在容器側(cè)提出了互動(dòng)套件的建設(shè),希望為游戲互動(dòng)場(chǎng)景提供優(yōu)化解決方案。24年春節(jié)我們完成游戲引擎預(yù)熱和游戲資產(chǎn)公共離線(xiàn)庫(kù)的相關(guān)優(yōu)化,在24年春節(jié)得到了不錯(cuò)的優(yōu)化效果;同時(shí)我們完成了游戲資源(解)壓縮的探索和更高效的物理引擎探索,希望能夠在25年春節(jié)完成壓縮和物理引擎的落地,從而豐富游戲互動(dòng)玩法的同時(shí),提升游戲的整體性能。
資產(chǎn)離線(xiàn)公共庫(kù)是一個(gè)重要的資源管理工具,管理了游戲互動(dòng)業(yè)務(wù)所需要的游戲引擎資源。通過(guò)對(duì)游戲主包拆包和引擎資源的統(tǒng)一管理,資產(chǎn)離線(xiàn)公共庫(kù)能夠有效地幫助降低游戲包的大小,從而提高游戲的運(yùn)行效率。此外,資產(chǎn)離線(xiàn)公共庫(kù)還能夠通過(guò)復(fù)用本地離線(xiàn)公共庫(kù)的引擎版本,進(jìn)一步降低游戲包下載的整體耗時(shí)和帶寬成本。
引擎預(yù)熱是一種提供了與游戲引擎優(yōu)化相關(guān)的能力的技術(shù)。其原理是在游戲啟動(dòng)過(guò)程中,對(duì)游戲引擎進(jìn)行預(yù)熱,以便游戲邏輯執(zhí)行過(guò)程中更快地加載游戲引擎包,從而提高游戲加載速度。通過(guò)提前準(zhǔn)備游戲引擎,在游戲啟動(dòng)時(shí),就可以更快地進(jìn)入游戲世界,減少等待時(shí)間。這種技術(shù)可以為玩家?guī)?lái)更好的游戲體驗(yàn)。
資源的壓縮與解壓縮可以極大地提高資源利用率,有效降低資源包體積和網(wǎng)絡(luò)加載時(shí)長(zhǎng)。資源的壓縮處理是在引擎編輯器的打包構(gòu)建階段做的資源預(yù)處理,而資源的解壓縮則被放在了互動(dòng)容器中,在游戲載入過(guò)程中實(shí)時(shí)進(jìn)行處理。
物理引擎,目前前端游戲開(kāi)發(fā)者主要依賴(lài)js或者wasm版本的物理引擎,在游戲性能和體驗(yàn)上存在較大的優(yōu)化空間,因此我們探索在容器側(cè)提供更高效的物理引擎方案,從而為游戲開(kāi)發(fā)者和設(shè)計(jì)師提供更好的物理引擎解決方案,豐富游戲互動(dòng)玩法體驗(yàn)。
本文主要介紹24年在春節(jié)場(chǎng)景落地的引擎預(yù)熱和資產(chǎn)公共離線(xiàn)庫(kù)相關(guān)的優(yōu)化手段。同時(shí)介紹、探討我們游戲資源(解)壓縮方案的探索和在探索中遇到的問(wèn)題。
名詞解釋
引擎預(yù)熱&資產(chǎn)離線(xiàn)公共庫(kù)
業(yè)務(wù)痛點(diǎn)
基于游戲業(yè)務(wù)已有的數(shù)據(jù)進(jìn)行分析,我們發(fā)現(xiàn)游戲互動(dòng)場(chǎng)景有以下2個(gè)特點(diǎn):
- 依賴(lài)游戲引擎:在游戲中,游戲互動(dòng)場(chǎng)景的創(chuàng)建和運(yùn)行需要依賴(lài)于游戲引擎的加載和初始化邏輯。這個(gè)過(guò)程會(huì)消耗大約200ms~300ms的時(shí)間,這可能會(huì)對(duì)游戲的性能產(chǎn)生一定的影響。因此,為了提高游戲的響應(yīng)速度和流暢度,游戲開(kāi)發(fā)者需要盡可能地優(yōu)化引擎加載和初始化邏輯的執(zhí)行效率。
- 游戲加載耗時(shí)和用戶(hù)異常流失率呈正比:?jiǎn)?dòng)性能對(duì)于游戲的用戶(hù)體驗(yàn)至關(guān)重要,因?yàn)槿绻螒騿?dòng)沒(méi)有優(yōu)化好,用戶(hù)需要等待很長(zhǎng)時(shí)間才能看到游戲畫(huà)面。這樣很可能會(huì)導(dǎo)致許多用戶(hù)在游戲加載完成之前就退出游戲。根據(jù)已有的游戲數(shù)據(jù)分析,游戲加載時(shí)間在1.5秒后,每0.5秒左右就會(huì)有4%左右的用戶(hù)異常流失。因此,游戲開(kāi)發(fā)者需要高度重視游戲啟動(dòng)性能的優(yōu)化,以確保游戲能夠快速啟動(dòng),讓用戶(hù)盡快進(jìn)入游戲世界。
因此我們針對(duì)游戲互動(dòng)場(chǎng)景完成了引擎預(yù)熱的方案,整體在24年春節(jié)場(chǎng)景落地,雙端取得了不錯(cuò)的加載收益。
整體思路
在優(yōu)化之前,在容器加載游戲主包完成之后,才會(huì)開(kāi)始渲染游戲首屏頁(yè)面和執(zhí)行游戲業(yè)務(wù)邏輯。當(dāng)游戲的業(yè)務(wù)邏輯在執(zhí)行的過(guò)程中,必須等待容器完成游戲引擎資源的加載和初始化,這部分在線(xiàn)上存在一定的耗時(shí)。因此,為了解決這個(gè)問(wèn)題,我們?cè)谌萜鱾?cè)和前端工具鏈完成了一系列改造,以提高游戲頁(yè)面的加載速度。
具體地來(lái)說(shuō)我們?cè)谌萜鞔蜷_(kāi)游戲頁(yè)面路由階段,就完成了游戲引擎的預(yù)加載,并在跨端框架完成初始化之后,充分利用JS線(xiàn)程空閑的時(shí)間,完成游戲引擎的預(yù)熱,并將預(yù)熱好的實(shí)例掛載在全局對(duì)象中,這樣當(dāng)游戲頁(yè)面真正執(zhí)行的時(shí)候,就能直接通過(guò)全局對(duì)象中的獲取到游戲引擎實(shí)例,從而完成后續(xù)的游戲業(yè)務(wù)邏輯。
技術(shù)細(xì)節(jié)
開(kāi)發(fā)工具鏈改造
前端工具鏈方面,在構(gòu)建工具中接入speedy-split-chunks插件,在游戲打包的過(guò)程中,將游戲引擎包從游戲主包中拆分出去,并將引擎庫(kù)發(fā)布到靜態(tài)資源分發(fā)平臺(tái)公共離線(xiàn)庫(kù)下;封裝split-engine-adapter組件,完成引擎預(yù)熱的前端代碼插樁,并在引擎預(yù)熱時(shí),提供兜底邏輯,保障業(yè)務(wù)的穩(wěn)定性。在剔除游戲引擎包同時(shí),并將剔除出來(lái)的引擎包和對(duì)應(yīng)的meta文件部署到靜態(tài)資源分發(fā)平臺(tái)公共離線(xiàn)庫(kù),通過(guò)meta文件來(lái)維護(hù)離線(xiàn)公共庫(kù)的游戲引擎資源版本,供多個(gè)游戲互動(dòng)業(yè)務(wù)使用,從而降低帶寬成本。
另一方面,我們的split-engine-adapter插件可以在請(qǐng)求加載引擎資源文件時(shí),完成對(duì)requireModule函數(shù)的hook。在這個(gè)過(guò)程中,如果發(fā)現(xiàn)全局對(duì)象上不存在的引擎實(shí)例,那么就會(huì)通過(guò)requireModule請(qǐng)求拆包引擎包作為兜底措施。通過(guò)這種方式,可以避免因引擎實(shí)例不存在而導(dǎo)致的錯(cuò)誤,從而提高系統(tǒng)的穩(wěn)定性和可靠性。
預(yù)熱游戲引擎
客戶(hù)端通過(guò)前端拆包的meta文件,進(jìn)行公共庫(kù)離線(xiàn)庫(kù)資源版本管理。當(dāng)客戶(hù)端頁(yè)面schema中打開(kāi)引擎預(yù)熱的能力時(shí),客戶(hù)端會(huì)在頁(yè)面路由時(shí),根據(jù)meta查找對(duì)應(yīng)的引擎版本,提前去預(yù)加載游戲引擎。由于離線(xiàn)公共庫(kù)存在客戶(hù)端本地,為了防止替換客戶(hù)端本地引擎JS文件,整體加載過(guò)程中會(huì)對(duì)游戲引擎資源進(jìn)行驗(yàn)簽,從而達(dá)到避免JS注入攻擊的風(fēng)險(xiǎn)。同時(shí),在跨端容器創(chuàng)建的過(guò)程中,將游戲引擎文件在JS線(xiàn)程進(jìn)行預(yù)熱,最終將游戲引擎實(shí)例掛載到全局對(duì)象上,以確保游戲引擎的正常運(yùn)行。
當(dāng)前端業(yè)務(wù)邏輯執(zhí)行時(shí),可以通過(guò)全局對(duì)象訪問(wèn)游戲引擎實(shí)例。如果引擎預(yù)熱失敗,前端業(yè)務(wù)會(huì)通過(guò)兜底的邏輯,請(qǐng)求游戲引擎資源進(jìn)行使用,從而提升整體方案的穩(wěn)定性和可靠性。
業(yè)務(wù)收益
在游戲互動(dòng)場(chǎng)景中,AnnieX互動(dòng)容器通過(guò)提供引擎預(yù)熱和依賴(lài)資產(chǎn)公共離線(xiàn)庫(kù)托管游戲引擎的方案,實(shí)現(xiàn)了游戲引擎的快速加載和初始化,從而提升了游戲業(yè)務(wù)的整體性能。這一方案成功地幫助完成了24年抖音春節(jié)活動(dòng)的落地,游戲主包大小降低了28.05%。通過(guò)復(fù)用公共離線(xiàn)包引擎資源,節(jié)約了數(shù)萬(wàn)元網(wǎng)絡(luò)帶寬的成本。
在游戲加載耗時(shí)方面,雙端在不同游戲的表現(xiàn)中存在200ms~500ms左右的優(yōu)化幅度。由于iOS整體性能更佳,因此優(yōu)化幅度整體上相較于Android用戶(hù)優(yōu)化幅度更大。在Android端中,PCT90有32.12%的優(yōu)化幅度,PCT50有20.75%的優(yōu)化幅度;在iOS端中,PCT90有47.24%,PCT50有33.89%的優(yōu)化幅度。
資源壓縮
業(yè)務(wù)痛點(diǎn)
3D資源往往文件體積較大,在需要網(wǎng)絡(luò)傳輸?shù)膱?chǎng)景,對(duì)這些資源的壓縮通常能夠有效提升資源的加載速度,節(jié)約網(wǎng)絡(luò)流量傳輸成本。
目前,常用的3D資源文件格式主要有g(shù)lTF、fbx、obj等,這些資源通常包含了3D資源的幾何體、骨骼、動(dòng)畫(huà)、材質(zhì)等等所有數(shù)據(jù),因此圍繞著24年抖音春節(jié)活動(dòng),我們開(kāi)始了基于游戲3D資源的壓縮和解壓縮的探索和調(diào)研。
整體思路
這里主要介紹AnnieX互動(dòng)容器對(duì)于幾何體和動(dòng)畫(huà)數(shù)據(jù)的壓縮算法及其具體實(shí)現(xiàn)方式,分別是:量化(Quantization)、稀疏訪問(wèn)器(Sparse Accessor)和網(wǎng)格優(yōu)化(meshopt)。
技術(shù)細(xì)節(jié)
幾何體的壓縮與解壓縮
在SAR Creator中,幾何體(Geometry)除了包含了頂點(diǎn)的坐標(biāo)(Position)、紋理坐標(biāo)(UV)、法向量(Normal)、切向量(Tangent)、顏色(Color)等數(shù)據(jù)之外,還包含了組成三角形的頂點(diǎn)索引(Index)、骨骼(Skeleton)和混合變形(Blend Shape)等數(shù)據(jù)。
由于這些不同的數(shù)據(jù)有著不同的格式和特性,所以往往需要分別應(yīng)用不同的壓縮格式,用以在盡可能保證數(shù)據(jù)精度的同時(shí)盡量提高壓縮效率。
這里介紹幾種SAR Creator中使用到的壓縮算法:量化、稀疏訪問(wèn)器和meshopt。
量化(Quantization)
量化是一種常用的簡(jiǎn)單且高效的資源壓縮方式,通常用于頂點(diǎn)數(shù)據(jù)的壓縮,是一種有損壓縮。
量化是將32位浮點(diǎn)值轉(zhuǎn)換為16位或8位的整數(shù)進(jìn)行存儲(chǔ)的過(guò)程,可以達(dá)到50%甚至25%的壓縮率。
轉(zhuǎn)換公式
詳情
由上述轉(zhuǎn)換說(shuō)明易知,量化是一個(gè)有損的壓縮,其壓縮和解壓縮均只需要對(duì)所有原始數(shù)據(jù)做當(dāng)且僅當(dāng)一次乘法/除法運(yùn)算,算法復(fù)雜度為O(n),開(kāi)銷(xiāo)較低。
量化對(duì)原始浮點(diǎn)數(shù)的范圍有一個(gè)前提要求,其范圍必須在0到1之間(可轉(zhuǎn)換到無(wú)符號(hào)整數(shù))或-1到1之間(可轉(zhuǎn)換到有符號(hào)整數(shù))。當(dāng)原始浮點(diǎn)數(shù)的值不在這個(gè)范圍內(nèi)的話(huà),需要預(yù)先做一次歸一化處理,使其落在需要的范圍內(nèi),才能繼續(xù)進(jìn)行量化處理。
本質(zhì)上,量化是建立了一個(gè)浮點(diǎn)數(shù)和整數(shù)的對(duì)應(yīng)關(guān)系,整數(shù)的存儲(chǔ)位數(shù)越大,對(duì)應(yīng)的浮點(diǎn)數(shù)精度越高。理論上可以實(shí)現(xiàn)任意位數(shù)的整數(shù)跟浮點(diǎn)數(shù)的轉(zhuǎn)換。
在SAR Creator中,因?yàn)椴煌臄?shù)據(jù)對(duì)于精度的要求不同,故在實(shí)際應(yīng)用時(shí)對(duì)于不同類(lèi)型的數(shù)據(jù)使用了不同位數(shù)的整數(shù)進(jìn)行存儲(chǔ),具體如下:
- position:14
- uv:12
- normal:10
- tangent:12
- color:8
- blend shape:8
以上不同類(lèi)型數(shù)據(jù)的存儲(chǔ)位數(shù)的配置選擇參考自業(yè)界經(jīng)驗(yàn),可以在盡量保證數(shù)據(jù)精度的同時(shí)提高壓縮率。在對(duì)精度要求較高的情況下,可以對(duì)該配置進(jìn)行調(diào)整優(yōu)化,一般最大值不會(huì)超過(guò)16位。
稀疏訪問(wèn)器(Sparse Accessor)
這里的稀疏訪問(wèn)器來(lái)自于glTF規(guī)范中的稀疏訪問(wèn)器(Sparse Accessor),特別適合用來(lái)存儲(chǔ)混合變形(BlendShape,以下簡(jiǎn)稱(chēng)BS)數(shù)據(jù),因?yàn)锽S數(shù)據(jù)中往往存在較多的“0”。
在glTF規(guī)范中,Sparse Accessor會(huì)把一個(gè)較大的vector2/3/4的數(shù)組(Buffer),拆分成3個(gè)部分:非0值數(shù)組(Values Array)、索引下標(biāo)數(shù)組(Indices Array)和原始長(zhǎng)度值(Count)。通過(guò)這樣僅存儲(chǔ)非0值及其下標(biāo)的方式,結(jié)合一個(gè)原始長(zhǎng)度,就可以很方便地還原出原始數(shù)據(jù)。
在SAR Creator中會(huì)基于glTF的Sparse Accessor的格式再進(jìn)一步做優(yōu)化調(diào)整,僅會(huì)存儲(chǔ)非0的vector2/3/4的非0通道的數(shù)據(jù),而不是glTF規(guī)范中必須是Vector2/3/4中所有通道的數(shù)據(jù)均為0才不去存儲(chǔ),這樣可以進(jìn)一步減少序列化后存儲(chǔ)數(shù)據(jù)的文件體積大小。同時(shí),由于SAR的AssetBundle格式對(duì)于數(shù)組存儲(chǔ)采用了特殊的方式,所以這里還可以少存一個(gè)Int32的Count值。
轉(zhuǎn)換格式
轉(zhuǎn)換格式示意圖如下:
由上圖可知,稀疏訪問(wèn)器是無(wú)損壓縮,且其壓縮和解壓縮的流程簡(jiǎn)單,算法復(fù)雜度為O(n),但實(shí)際的解壓縮過(guò)程并不需要對(duì)所有的數(shù)據(jù)進(jìn)行處理,只需要?jiǎng)?chuàng)建跟原先相同大小的buffer,按下標(biāo)將所有的非零值填進(jìn)去即可,故而開(kāi)銷(xiāo)很低。
詳情
另外,由于稀疏訪問(wèn)器僅在當(dāng)BS數(shù)據(jù)的0值較多時(shí),才會(huì)有較高的壓縮效率,否則反而會(huì)降低壓縮效率。SAR Creator默認(rèn)會(huì)自動(dòng)判斷應(yīng)用了稀疏訪問(wèn)器后是否會(huì)減少資源文件體積,來(lái)決定是否采用稀疏訪問(wèn)器,不需要手動(dòng)開(kāi)啟。
附:真實(shí)業(yè)務(wù)(虛擬形象)中的glTF文件為例,僅采用Sparse Accessor能減少53%左右的文件體積,如果采用Sar的Asset Bundle中優(yōu)化后的數(shù)據(jù)格式,可以減少78%左右的文件體積。
值得一提的是,稀疏訪問(wèn)器可以跟量化一起疊加同時(shí)應(yīng)用在幾何體數(shù)據(jù)上,兩者互不影響,互不沖突,最終的精度損失僅為量化的損失。
網(wǎng)格優(yōu)化(meshopt)
meshopt是glTF規(guī)范中的一個(gè)擴(kuò)展:EXT_meshopt_compression,該擴(kuò)展可以對(duì)glTF文件中的幾何體和動(dòng)畫(huà)數(shù)據(jù)進(jìn)行優(yōu)化與壓縮。在SAR Creator中,幾乎全量移植了這個(gè)擴(kuò)展的具體實(shí)現(xiàn),使得SAR Creator的Asset Bundle中的幾何體和動(dòng)畫(huà)數(shù)據(jù)同樣支持了meshopt壓縮。
由于meshopt壓縮和解壓縮的算法較為復(fù)雜,SAR Creator在實(shí)現(xiàn)時(shí)應(yīng)用了wasm的方式(同時(shí)用asm.js做兜底),這里使用了開(kāi)源項(xiàng)目meshoptimizer,它提供了對(duì)Mesh進(jìn)行優(yōu)化、壓縮相關(guān)算法的C/C++接口,也可以編譯為wasm使用。
壓縮流程
meshopt在壓縮前需要先優(yōu)化頂點(diǎn)和索引數(shù)據(jù),用于提高壓縮效率,同時(shí)也可以提高解壓縮后的渲染效率(GPU緩存)。meshopt提出了三種不同的模式(mode:attribute、triangles、indices)的和三種不同的過(guò)濾器(filter:octahedral、quaternion、exponential),針對(duì)不同的數(shù)據(jù)類(lèi)型應(yīng)用不同的模式和過(guò)濾器,可以最大化壓縮率。
對(duì)于幾何體的meshopt壓縮,SAR Creator實(shí)現(xiàn)時(shí)的具體流程如下:
- 優(yōu)化索引順序
- 優(yōu)化索引順序,可以最大限度地利用附近的頂點(diǎn)數(shù)據(jù),從而盡量復(fù)用在GPU硬件中的緩存。
- 優(yōu)化頂點(diǎn)順序
頂點(diǎn)順序應(yīng)按照頂點(diǎn)在索引數(shù)據(jù)中出現(xiàn)的順序進(jìn)行順序排列,以而可以最大化索引數(shù)據(jù)的壓縮率。
需要注意的是:有時(shí)候更高的壓縮率反而會(huì)降低渲染效率,需要取好平衡點(diǎn)。
- 壓縮頂點(diǎn)數(shù)據(jù)
- 頂點(diǎn)數(shù)據(jù)需要先進(jìn)行量化(quantized),才能進(jìn)行后續(xù)的壓縮處理;
- 量化后的頂點(diǎn)數(shù)據(jù)需要用attributes模式來(lái)進(jìn)行二進(jìn)制比特流存儲(chǔ);
- 對(duì)于normal/tangent的數(shù)據(jù),使用octahedral的filter可以進(jìn)一步提高壓縮率,對(duì)于position或其他數(shù)據(jù),可以使用exponential的filter進(jìn)行處理;
- 壓縮索引數(shù)據(jù)
索引數(shù)據(jù)用indices模式進(jìn)行存儲(chǔ),也可以用triangles模式進(jìn)行存儲(chǔ);
其中,triangles模式僅支持三角形列表的存儲(chǔ),indices模式可以支持其他拓?fù)漕?lèi)型的索引數(shù)據(jù)存儲(chǔ);
壓縮BS數(shù)據(jù)
BS數(shù)據(jù)可以完全當(dāng)作頂點(diǎn)數(shù)據(jù)來(lái)進(jìn)行處理,也需要先進(jìn)行量化(quantized),之后再以attributes模式進(jìn)行二進(jìn)制比特流存儲(chǔ);
BS數(shù)據(jù)因?yàn)槭窃隽浚╮elative/delta)的值,故也可以選用比頂點(diǎn)數(shù)據(jù)在量化后更小的比特位來(lái)進(jìn)行存儲(chǔ);
解壓縮流程
對(duì)于幾何體的meshopt解壓縮,則需要反過(guò)來(lái)進(jìn)行,互動(dòng)容器中實(shí)現(xiàn)的具體流程如下
- 解壓縮頂點(diǎn)數(shù)據(jù)
- 按attributes模式進(jìn)行解壓縮;
- 對(duì)于采用了對(duì)應(yīng)filter的數(shù)據(jù),還需要再進(jìn)行filter的解壓縮;
- (可選)如果有必要,在進(jìn)行反量化轉(zhuǎn)換(de-quantized)處理;
- 解壓縮索引數(shù)據(jù)
直接按壓縮時(shí)采用的indices或triangles模式進(jìn)行解壓縮即可;
解壓縮BS數(shù)據(jù)
同頂點(diǎn)數(shù)據(jù)的解壓,不再贅述;
詳情
對(duì)于幾何體數(shù)據(jù)應(yīng)用meshopt壓縮,往往可以帶來(lái)10%-20%的壓縮率,可以極大減少資源體積。但由于其復(fù)雜度較高,需要使用wasm加速壓縮和解壓縮的過(guò)程。
對(duì)于不支持wasm的環(huán)境,SAR Creator使用了asm.js作為兜底方案。實(shí)際測(cè)試結(jié)果顯示,asm.js會(huì)比wasm慢2-4倍。在后續(xù)版本的SAR中,可能會(huì)直接使用C++的方案加速運(yùn)行時(shí)對(duì)meshopt壓縮后的資源進(jìn)行解壓縮,加速資源加載和解析的整個(gè)流程。
另:SAR Creator對(duì)于幾何體數(shù)據(jù)的meshopt壓縮實(shí)現(xiàn),目前仍在feature分支,未經(jīng)過(guò)全面測(cè)試,僅上線(xiàn)了對(duì)于動(dòng)畫(huà)數(shù)據(jù)的meshopt壓縮。
動(dòng)畫(huà)的壓縮與解壓縮
動(dòng)畫(huà)(Animation)數(shù)據(jù)是由一系列的關(guān)鍵幀(keyframe)組成的。所以動(dòng)畫(huà)數(shù)據(jù)是由兩部分組成的:關(guān)鍵幀的時(shí)間數(shù)組(times)和關(guān)鍵幀的值數(shù)組(values)。
網(wǎng)格優(yōu)化(meshopt)
SAR Creator中對(duì)于動(dòng)畫(huà)(Animation)數(shù)據(jù)的壓縮,也是移植自上述meshopt擴(kuò)展。
壓縮流程
對(duì)于動(dòng)畫(huà)數(shù)據(jù)的meshopt壓縮,SAR Creator實(shí)現(xiàn)時(shí)的具體流程如下:
- 對(duì)動(dòng)畫(huà)數(shù)據(jù)進(jìn)行重采樣
- 對(duì)動(dòng)畫(huà)數(shù)據(jù)的壓縮,最有收益的是進(jìn)行重采樣(resample),這樣可以減少存儲(chǔ)的關(guān)鍵幀數(shù)量,進(jìn)而減少動(dòng)畫(huà)數(shù)據(jù)的文件存儲(chǔ)體積;
- 具體實(shí)現(xiàn)使用開(kāi)源庫(kù):keyframe-resample-wasm,它提供了WebAssembly版本的重采樣方式,會(huì)比純js的版本快一些,而且這個(gè)庫(kù)的重采樣過(guò)程是無(wú)損的。
- 壓縮關(guān)鍵幀的times數(shù)據(jù)
如果times數(shù)據(jù)是均勻的,僅使用attribute模式而不使用任何過(guò)濾器已經(jīng)能取得比較高的壓縮率了;
為了保證最終的動(dòng)畫(huà)不變形,一般不建議對(duì)關(guān)鍵幀的times數(shù)據(jù)進(jìn)行filter處理,也可以繼續(xù)使用具有最大尾數(shù)位數(shù)(23)的exponential過(guò)濾器進(jìn)行處理,從而保證最小的精度損失;
最后使用attributes模式進(jìn)行存儲(chǔ);
壓縮關(guān)鍵幀的values數(shù)據(jù)
旋轉(zhuǎn)的數(shù)據(jù)可以使用16-bit進(jìn)行量化處理,并應(yīng)用quaternion過(guò)濾器進(jìn)行處理;
位移和縮放數(shù)據(jù)可以應(yīng)用exponential過(guò)濾器應(yīng)用相同的指數(shù)進(jìn)行處理;
最后使用attributes模式進(jìn)行存儲(chǔ);
解壓縮流程
對(duì)于動(dòng)畫(huà)數(shù)據(jù)的meshopt解壓縮,互動(dòng)容器中的實(shí)現(xiàn)具體流程如下:
- 解壓縮關(guān)鍵幀的times數(shù)據(jù)
- 按attributes模式進(jìn)行解壓縮;
- 如果壓縮時(shí)采用了exponential的過(guò)濾器(filter),還需要再進(jìn)行exponential的過(guò)濾器解壓縮;
- 解壓縮關(guān)鍵幀的values數(shù)據(jù)
按attributes模式進(jìn)行解壓縮;
旋轉(zhuǎn)的數(shù)據(jù)還需要用quaternion過(guò)濾器進(jìn)行解壓縮;
位移和縮放數(shù)據(jù)還需要用exponential過(guò)濾器進(jìn)行壓縮時(shí)相同指數(shù)的解壓縮;
詳情
對(duì)于動(dòng)畫(huà)數(shù)據(jù)的meshopt壓縮,同樣也是有損的,往往有40%左右的壓縮率,同樣采用了wasm的方式加速壓縮和解壓縮的過(guò)程。
附:真實(shí)業(yè)務(wù)(招財(cái)神龍)中的動(dòng)畫(huà)資源文件為例,有38.50%的壓縮率,可以減少1.9MB的資源包體積。
另:招財(cái)神龍業(yè)務(wù)中,考慮中低端機(jī)在跨端框架下wasm的兼容性問(wèn)題,開(kāi)發(fā)時(shí)直接默認(rèn)啟用了asm.js的降級(jí)方案,但在后來(lái)的性能測(cè)試環(huán)節(jié)中發(fā)現(xiàn)meshopt解壓縮的asm.js在iOS的JSC運(yùn)行時(shí)下效率較低,會(huì)嚴(yán)重增加資源的解析耗時(shí),最終上線(xiàn)時(shí)并沒(méi)有啟用動(dòng)畫(huà)數(shù)據(jù)的meshopt壓縮。
未來(lái)規(guī)劃
24年春節(jié)我們完成了引擎預(yù)熱、資產(chǎn)公共離線(xiàn)庫(kù)的落地,取得了不錯(cuò)的游戲優(yōu)化效果。但在業(yè)務(wù)落地的過(guò)程中,我們也發(fā)現(xiàn)一些存在的問(wèn)題,例如引擎預(yù)熱邏輯命中率雙端平均只達(dá)到81.33%,整體上還存在優(yōu)化的空間;另一方面隨著資產(chǎn)公共離線(xiàn)庫(kù)的托管的引擎類(lèi)型和版本越來(lái)越多,體積越來(lái)越大,我們需要加強(qiáng)對(duì)離線(xiàn)公共庫(kù)的版本管理,識(shí)別和控制ROI整體較低的引擎和版本,從而更好的控制離線(xiàn)公共庫(kù)的帶寬成本。
而在資源壓縮方面,我們完成了相關(guān)方案js和wasm版本的流程的調(diào)研和探索,以24年春節(jié)玩法招財(cái)神龍為例,我們?nèi)〉昧瞬诲e(cuò)的資源體積優(yōu)化效果,降低整體游戲包的大小。但在資源壓縮方面,由于低端機(jī)和部分iOS手機(jī)上對(duì)于網(wǎng)格優(yōu)化的解壓縮效率低下,甚至部分機(jī)型適用wasm會(huì)有崩潰的情況存在,所以雖然完成了整體的技術(shù)方案落地,但考慮到穩(wěn)定性并沒(méi)有在線(xiàn)上啟用。后續(xù)會(huì)進(jìn)一步優(yōu)化這一方面的兼容性問(wèn)題,解壓的性能問(wèn)題上也會(huì)直接采用C++而非wasm的方案,將資源壓縮方案完整在正式的游戲業(yè)務(wù)落地,同時(shí)覆蓋更多的游戲業(yè)務(wù)場(chǎng)景。
另外,在3D游戲場(chǎng)景下,一般意義上的資源還包括圖片、視頻、字體、腳本以及特定編輯器導(dǎo)出的資源(如lottie、spine等),對(duì)于這些資源文件的壓縮也有著明顯的意義,我們將在后續(xù)進(jìn)一步探索相關(guān)資產(chǎn)的壓縮,從而優(yōu)化整體游戲的資產(chǎn)大小。