在遊戲中,紋理不僅佔據大量的包體,也佔據了大量的記憶體。傳統的壓縮格式(如jpeg、png等)雖能減少資源大小,但是不能被gpu直接識別,還是需要先載入到記憶體通過cpu解碼,轉換成rgb/rgba等能被gpu識別的格式,才能傳送到gpu進行渲染。
為避免這些問題,壓縮紋理,指的是一種針對gpu的紋理壓縮方案,使紋理能夠直接被gpu識別並進行渲染,它具有以下優點。
傳統的壓縮主要目的是儲存和傳輸,為了盡可能的高效壓縮,使用了可變的壓縮比率,因此在解壓時需要解壓更多的畫素位才能讀取某個畫素的位置,不適合隨機和快速讀取,也發揮不了gpu的並行處理優勢。
而壓縮紋理使用乙個固定的壓縮比率,將紋理劃分成多個畫素塊,每個畫素塊包含2*2
或4*4
個畫素,然後對每個畫素塊進行壓縮,被壓縮的畫素資訊儲存在乙個畫素集合中,每個畫素塊的索引位置儲存在乙個塊索引圖中。讀取時,首先將紋理座標轉化為塊索引值,然後在畫素集合中查詢對應的畫素塊,最後在這個畫素塊中找到紋理顏色值。
因為採用了固定的壓縮比率,gpu內部可以並行處理,從而快速的解壓縮。與之相對的是,紋理的壓縮過程發生在程式執行之前,並不在意編碼速度,因此在壓縮時會遍歷所有可能性,找到和原始畫素差值最小的編碼,這也是紋理壓縮耗時較久的原因。
順便說一下,普通格式中,png是無失真壓縮,jpeg是有失真壓縮。而壓縮紋理都是有失真壓縮,只是在絕大部分情況下,手機上看不出來而已。
手機上使用壓縮紋理依賴於opengl es的支援,opengl es 2.0本身並沒有定義任何紋理壓縮格式,它僅提供 glcompressteximage2d() 方法**用程式上傳壓縮紋理,壓縮紋理的格式由各個gpu廠商定義和實現。
opengl es 3.0提供了壓縮紋理標準,使各個平台都可以使用同一種壓縮紋理,但市面上的裝置還需要很長時間才會全部過渡到opengl es 3.0。因此,仍然需要對不同的平台和裝置使用不同的壓縮紋理格式。
手機遊戲中常用的有以下格式。
3.1 etc1
etc1把4*4
的畫素塊壓縮成固定的64位編碼(8個位元組),4*4
畫素塊是16個畫素,每個畫素4位元組,一共佔64個位元組,所以壓縮比是 64/8=8。但是etc1只能儲存rgb資訊,不適用帶透明度的紋理,為解決這個問題,creator在etc1檔案中額外寫入了透明度資訊,即etc1+a格式,它的壓縮比是 64/16=4。
etc1/etc1+a需要opengl es 2.0(對應webgl 1.0)環境,目前幾乎所有android手機都支援etc1,但是ios不支援。
etc1/etc1+a紋理的長寬可以不相等,但要求是2的冪次方。
3.2 etc2
etc2是etc1的擴充套件,壓縮比率一樣,但壓縮質量更高,而且支援透明通道,能完整儲存rgba資訊。
etc2需要opengl es 3.0(對應webgl 2.0)環境,目前還有不少低端android手機不相容,ios方面從 iphone5s 開始都支援opengl es 3.0。
etc2和etc1一樣,長寬可以不相等,但要求是2的冪次方。
3.3 pvrtc
creator中常用的是pvrtc4+a,壓縮比和etc一樣,ios全系列支援,但是android不支援。另外pvr要求紋理長寬相等(正方形)且是2的冪次方,例如1280*720
的png,轉換後變成2048*2048
,這一點會大大增加記憶體消耗。在實測中還發現轉換後的質量不如etc1,存在模糊、毛邊現象,對畫面要求高的遊戲不適合。
壓縮紋理的使用非常簡單,根據構建平台新增需要的格式即可,具體參見creator官方文件,本文不再重複了。
creator編輯器還提供了轉換壓縮紋理的選項,根據轉換速度分為fast、slow等好幾檔,速度越慢則畫面質量越好。但不管選哪個,只影響顯示效果和轉換時長,視訊記憶體占用都是一樣的。一般情況下,視訊記憶體占用就是壓縮紋理的檔案大小,例如檔案大小是1.5m,則它占用的視訊記憶體也是1.5m。
在設定壓縮紋理格式時,目前creator 2.x版本還需手動乙個乙個設定。如果想一次性設定所有或部分資源,自己寫個指令碼遍歷修改對應的.meta
檔案也比較方便,這裡是乙個我寫好的指令碼 一鍵自動化設定壓縮紋理格式
在實際專案中的測試結果是,單圖、自**集、texturepack合圖加起來超過兩千張的creator工程,使用png時打出來的apk包大小近500m,記憶體占用1.3g。採用壓縮紋理後,包體大小降到150m,記憶體占用降到600m。
定製乙個winCE5 0作業系統
2009 04 01 09 01 14 分類 字型大小 訂閱定製乙個作業系統並模擬器上執行,需要以下幾個步驟 step 1 用platform builder 的new platform wizard 建立乙個 os,需要以下幾步 1 開啟platform builde 應用程式 2 file ne...
Beanstalkd乙個高效能分布式記憶體佇列系統
高效能離不開非同步,非同步離不開佇列,內部是producer consumer模型的原理。設計中的核心概念 job 乙個需要非同步處理的任務,是beanstalkd中得基本單元,需要放在乙個tube中 tube 乙個有名的任務佇列,用來儲存統一型別的job,是producer和consumer操作的...
乙個小遊戲 讓你感受「如何等待成功」!
相信各位都玩過了開心網的三國殺。不知道有多少人會自己建房間?我就在不同的時間段做了測試。首先開個空房間,然後等待加入者到8個,滿人開始遊戲。這個等待過程非常的有趣,首先會有1 2個人嘗試性加入,也有可能等待一會兒,然後走了。然後會慢慢到4 5個人加入。這個時候,很大概率會突然100 的人又走了,剩下...