Unity3D:資源包的壓縮(Asset Bundle Compression)

Unity支持三種資源包的壓縮方式:LZMA,LZ4和不壓縮。

LZMA格式

資源包默認編譯壓縮格式的。標準壓縮格式使用的是單一的LZMA算法的序列化的數據文件流,使用前需要獲取完整的數據再解壓縮。

LZMA壓縮包下載容量最小,但會導致解壓變慢和加載時間更長。

LZ4格式

Unity還支持LZ4壓縮,會導致較大的壓縮文件,但是這種方式不要求完整的數據包就可以解壓縮。LZ4算法是“基於塊”的,因此當對象從一個LZ4壓縮包加載時,僅用於該對象的相應塊會被解壓。這發生在瞬間,意味着使用前無需解壓完整的資源包。LZ4格式是在Unity 5.3引入,以前的版本不可用。

不壓縮格式

第三個壓縮選項是不壓縮。未壓縮的資源包很大,但一旦下載後則訪問最快。

壓縮包的緩存

WWW.LoadFromCacheOrDownload 函數下載並緩存資源包到磁盤上,極大的加快了加載速度。從Unity 5.3開始,緩存數據也可以使用LZ4算法壓縮。相比未壓縮的包它能節省40%60%的空間。在下載過程中同時進行壓縮,因此最終用戶幾乎不會察覺。當數據從網絡到達,Unity將解壓並以LZ4格式重新壓縮它。在下載數據流同時重新壓縮,這意味着一旦數據足夠就馬上進行緩存壓縮,並一直持續增長到下載完成。在此之後,數據在需要時會從高速緩存的包中即時解壓並讀取。

緩存壓縮默認是啓用的,由屬性Caching.compressionEnabled 控制。它同時影響緩存到磁盤和存儲在內存中的資源包。

AssetBundle加載API概述

此表提供了使用不同的壓縮類型和不同的加載方法時內存和性能開銷的比較。

 

無壓縮

塊壓縮(LZ4

流壓縮(LZMA

WWW *

內存:未壓縮的包的大小+(當WWW未釋放時,未壓縮的包的大小)。性能:沒有額外的開銷。

內存:LZ4HC壓縮的包的大小+(當WWW未釋放時,LZ4HC壓縮的包的大小)。性能:沒有額外的開銷。

內存:LZ4壓縮的包的大小+(當WWW未釋放時,LZMA壓縮的包的大小)。性能:LZMA解壓+ 在下載過程中LZ4壓縮。

LoadFromCacheOrDownload

內存:沒有額外的開銷。性能:從磁盤讀取。

內存:沒有額外的開銷。性能:從磁盤讀取。

內存:沒有額外的開銷。性能:從磁盤讀取。

LoadFromMemory(異步)

內存:未壓縮的包的大小。性能:沒有額外的開銷。

內存:LZ4HC壓縮的包的大小。性能:沒有額外的開銷。

內存:LZ4壓縮的包的大小。性能:LZMA壓縮+ LZ4壓縮。

LoadFromFile(異步)

內存:沒有額外的開銷。性能:從磁盤讀取。

內存:沒有額外的開銷。性能:從磁盤讀取。

內存:LZ4壓縮的包的大小。性能:從磁盤讀取+ LZMA壓縮+ LZ4壓縮。

WebRequest的(也支持緩存)

內存:未壓縮的包的大小。性能:沒有額外開銷[+是否從磁盤讀取緩存]。

內存:LZ4HC壓縮的包的大小。性能:沒有額外的開銷[+是否從磁盤讀取緩存]。

內存:LZ4壓縮的包的大小。性能:下載過程中LZMA壓縮+ LZ4壓縮[+是否從磁盤讀取緩存]。

*當使用WWW下載資源包,WebRequest還需要一個從socket讀取數據的8x64KB的累加器緩存。

因此,使用在遊戲中使用低級加載API時遵循以下原則:

1.    爲遊戲部署資源包時使用StreamingAssets:使用BuildAssetBundleOptions);使用基於塊的壓縮方式來構建包和資源包使用LoadFromFileAsync來加載它。這使您的內存數據壓縮和加載速度幾乎等於讀取緩存。

2.    下載用作DLC的資源包使用默認的編譯選項(LZMA壓縮)和LoadFromCacheOrDownload / WebRequest來下載和緩存它。這樣你可以有最好的壓縮比,並得到資源包。LoadFromFile加載性能進一步提升。

3.    加密包使用BuildAssetBundleOptions;使用基於塊的壓縮方式,並使用LoadFromMemoryAsync加載(通常這是唯一方案)。

4.    自定義壓縮使用BuildAssetBundleOptions;使用非壓縮方式來構建資源包。用自定義的算法解壓之後使用LoadFromFileAsync加載包。

你應該使用異步函數,因爲他們不阻塞主線程,並且能讓加載更高效和操作隊列化。絕對避免在同時使用同步和異步函數這可能會在主線程上產生"打嗝"。

兼容性

資源包容器格式發生了變化,來支持新的壓縮類型,並且爲進一步改進提供基礎。Unity5還支持由Unity 4創建的包,但是更早期版本(2.X,3.X)不支持。

 

---------------------------------------------------- 以下是原文 ----------------------------------------------------

 

Asset Bundle Compression

Unity supports three compression options for Asset Bundles: LZMA, LZ4, and Uncompressed.

LZMA Format

By default, when Asset Bundles are built, they are stored in a compressed format. The standard compressed format is a single LZMA stream of serialized data files, and needs to be decompressed in its entirety before use.

LZMA-Compressed bundles give the smallest possible download size, but has relatively slow decompression resulting in higher apparent load times.

LZ4 Format

Unity also supports LZ4 compression, which results in larger compressed file sizes, but does not require the entire bundle to be decompressed before use. LZ4 is a “chunk-based” algorithm, and therefore when objects are loaded from an LZ4-compressed bundle, only the corresponding chunks for that object are decompressed. This occurs on-the-fly, meaning there are no wait times for the entire bundle to be decompressed before use. The LZ4 Format was introduced in Unity 5.3 and was unavailable in prior versions.

Uncompressed Format

The third compression option is no compression at all. Uncompressed bundles are large, but are the fastest to access once downloaded.

Caching of Compressed Bundles

The WWW.LoadFromCacheOrDownload function downloads and caches asset bundles to disk and thus greatly speeds up loading afterwards. From Unity 5.3 onwards, cached data can also be compressed with the LZ4 algorithm. This saves 40%–60% of space compared to uncompressed bundles. Recompression happens during download and thus is almost unnoticeable by the end users. As data arrives from the socket, Unity will decompress it and recompress it in LZ4 format. This recompression occurs during the download streaming, which means the cache compression begins as soon as enough of the data is downloaded, and continues incrementally until the download is complete. After that, data is read from the cached bundle by decompressing chunks on-the-fly when needed.

Cache compression is enabled by default and is controlled by the Caching.compressionEnabled

 property. It affects bundles cached to disk and stored in memory.

AssetBundle load API overview

This table provides a comparison of memory and performance overheads when using different compression types and different loading methods.

 

Uncompressed

Chunk Compressed (LZ4)

Stream Compressed (LZMA)

WWW *

Memory: uncompressed bundle size + (while WWW is not disposed, uncompressed bundle size). Performance: no extra processing.

Memory: LZ4HC compressed bundle size + (while WWW is not disposed, LZ4HC compressed bundle size). Performance: no extra processing.

Memory: LZ4 compressed bundle size + (while WWW is not disposed, LZMA compressed bundle size). Performance: LZMA decompression + LZ4 compression during download.

LoadFromCacheOrDownload

Mem: no extra memory is used. Perf: reading from disk.

Mem: no extra memory is used. Perf: reading from disk.

Mem: no extra memory is used. Perf: reading from disk.

LoadFromMemory (Async)

Mem: uncompressed bundle size. Perf: no extra processing.

Mem: LZ4HC compressed bundle size. Perf: no extra processing.

Mem: LZ4 compressed bundle size. Perf: LZMA decompression + LZ4 compression.

LoadFromFile(Async)

Mem: no extra memory is used. Perf: reading from disk.

Mem: no extra memory is used. Perf: reading from disk.

Mem: LZ4 compressed bundle size. Perf: reading from disk + LZMA decompression + LZ4 compression.

WebRequest (also supports caching)

Mem: uncompressed bundle size. Perf: no extra processing [+reading from disk if cached].

Mem: LZ4HC compressed bundle size. Perf: no extra processing [+reading from disk if cached].

Mem: LZ4 compressed bundle size. Perf: LZMA decompression + LZ4 compression during download [+reading from disk if cached].

* When downloading a bundle using WWW, WebRequest there is also an 8x64KB accumulator buffer which stores data from a socket.

Thus, use the following guidelines when using low-level loading API in your games:

1.    Deploying asset bundles with your game as StreamingAssets - use BuildAssetBundleOptions.ChunkBasedCompression when building bundles and AssetBundle.LoadFromFileAsync to load it. This gives you data compression and the fastest possible loading performance with a memory overhead equal to read buffers.

2.    Downloading asset bundles as DLCs - use default build options (LZMA compression) and LoadFromCacheOrDownload/WebRequest to download and cache it. Here you’ll have the best possible compression ratio and AssetBundle.LoadFromFile loading performance for further loads.

3.    Encrypted bundles - choose BuildAssetBundleOptions.ChunkBasedCompression and use LoadFromMemoryAsync for loading (this is pretty much the only scenario where LoadFromMemory[Async] should be used).

4.    Custom compression - use BuildAssetBundleOptions.UncompressedAssetBundle to build and AssetBundle.LoadFromFileAsync to load a bundle after it was decompressed by your custom compression algorithm.

You should generally always choose asynchronous functions - they don’t stall the main thread and they allow loading operations to be queued more efficiently. And absolutely avoid calling synchronous and asynchronous functions at the same time - this might introduce hiccups on the main thread.

Compatibility

The Asset Bundle container format was changed in order to support new compression type, and to provide basis for further improvements. Unity 5 still supports bundles created in Unity 4, however bundles created in earlier version (2.x, 3.x) are not supported.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章