手機遊戲開發中如何選擇適合的紋理格式

爲毛要寫這個


原本以爲像這樣的問題,是沒法歸類的,由於不一樣的項目有不一樣的需求,但今天由於quick論壇中的一個技術疑問貼,鉤起了我整理這篇文章的興趣 http://www.cocoachina.com/bbs/read.php?tid=214811php

因而,我決定盡力描述一下紋理格式選擇方面的問題,一是起到一個科普的做用,由於目前沒有發現十分完整的講這方面的文章。二是整理一下本身的思路。css

固然,這些東西確定不是我本身憑空YY出來的,我也是參考了很多文章,也從項目中總結了一些問題。在此先列出一些連接,先睹爲快html

移動平臺GPU壓縮文理大全android

使用Mali官方工具進行ETC1紋理壓縮算法

Ericsson Texture Compressionide

iOS和android遊戲紋理優化和內存優化(cocos2d-x)grunt

優化你的手機遊戲(沒有延遲,纔是健康的)工具

Cocos2d-x紋理優化方案的一些總結優化

手機遊戲開發紋理圖片優化心得網站

手機遊戲開發,如何選擇和優化圖片素材

 

嗯 ,我以爲已經足夠多了,而且,可能你也沒有耐心把全部連接看完。 至少我沒有……。

 

 

GPU紋理與非GPU紋理


不少小夥伴其實一直不明白GPU紋理與非GPU紋理的區別,以至於我打了將近1000字,他也沒有懂爲何JPG不能省內存。

常見的JPG格式,是一種文件壓縮格式,即它可以把圖片像素值,使用一種有損壓縮的方式來存儲,這樣圖片的體積會變得很是小。

而咱們常常提到的GPU紋理格式,如pvrtc,etc等,是一種GPU壓縮格式,這種壓縮格式,文件大小會比JPG大,可是它讀入到內存後,不會被解壓,而是直接送到顯卡。 顯卡也不會對齊解壓,而是在執行如tex2D紋理採樣指令的時候,取訪問並索取對應像素值的內容。 這樣纔可以節省顯存和內存。 pvrtc、etc等,既可以進行壓縮,同時又提供隨機訪問(即在不所有解壓的狀況下,訪問指定UV座標的像素值)能力,所以會比jpg大許多

 

 

圖片格式簡介


->pvrtc

pvrtc有兩種格式,一種是pvrtc 2bp,一種是pvrtc4bp。 兩者沒有本質區別,最主要的區別就是2bp表示每一個像素使用2 bit來存儲,4bp使用4bit來存儲。固然這是一種理論值,因爲pvrtc還須要儲存額外的信息以保證可以恢復像素值,以及提供隨機訪問能力。 因此,實際的pvrtc格式的文件,不會是1/8和1/16這麼小。pvrtc格式讀入內存後,不會進行解壓,而是直接送給GPU。 GPU也不會進行解壓,從而保證了內存和顯存的節約。 而tex2D可以對這種格式的紋理直接採樣。

另外,pvrtc目前有兩個大版本,pvrtc1和pvrtc2,pvrtc2對壓縮算法作了明顯的改進。 但須要新款的GPU才支持,因此,若是要使用pvrtc2版本的PVRTC紋理,記得檢查OPENGL ES的擴展標記。

pvrtc建議只對IOS平臺使用,由於這是power vr顯卡專用的紋理格式。

->etc

etc目前有兩種格式,etc1/etc2。 etc1是opengl es 1.x和opengl es 2.0提供的必須支持的硬件格式,其惟一的缺點就是不支持ALPHA通道。 而etc2是opengl es 3.0才支持的,且增長了ALPHA通道能力。

因爲目前opengles 3.0設備的普及率還不高,目前(寫這文章的時候是2014年7月18日)建議使用etc1格式

建議etc1格式使用在ANDROID平臺上。

 

->png24/32

png24和32實際上是同樣的,24表示ALPHA通道不使用,所以,這是一種RGBA8888的紋理格式,這種格式不進行任何壓縮,徹底保持原始像素值。能夠提供較高的質量,但這種紋理佔用的磁盤空間較大。(與其內存佔用等同),能夠簡單地經過 長x寬x4來計算大小。 好比1024x1024的PNG24/32紋理,佔用磁盤空間和內存爲 4MB。

->png8

png8十分複雜,由於png8的意義比較多。

僅包含ALPHA通道的8位PNG:這種一般拿來提供單獨的ALPHA通道能力,opengl d3d等均支持這種8位ALPHA紋理。

256色調色板的PNG:這種一般見於網站圖標等,它只有一位表示ALPHA,即鏤空效果。且不適合用在須要表現豐富和高飽和度的場合。

經過一些壓縮方式獲得的壓縮PNG:如grunt-png8,tinypng等, 這些工具,使用了較高的壓縮技巧,使PNG24/32的RGBA能夠保存在8位通道中。 且可以提供較高的還原度。 這種和PNG同樣,讀入內存後,每一個像素依然佔4BYTES。

->jpg

jpg是一種經過有損壓縮算法,使原始圖片能夠以很小的文件來存儲的格式。 這種和上面提到的png8十分相似,但JPG不支持ALPHA通道。 雖然不支持ALPHA通道,但它讀進內存後,內存佔用依然是每一個像素4BYTES。

 

另外還有一些dds,tga等,因爲我我的在手機遊戲開發方面涉及這方面較少(端遊使用tga和dds較多),在此不做論述。

 

如何選擇紋理格式


人生之因此糾結,在於許多事情你能夠選擇

                                             ---糾結帝·麒麟子·Alex

 

上面的紋理格式,同一種狀況下,可能多種都適合,那如何選擇呢。 咱們仍是根據具體狀況而定。

 

一、場景、背景、全屏圖片

2D手機遊戲中,多半都有這樣的圖片,以做爲背景,特別在一些SLG,橫版過關遊戲中。這種圖片對ALPHA沒有要求,而且,在同一時間,只會出現一張(若是是多張拼接,也不會超過屏幕尺寸太多),內存不會成爲關鍵點。因此,在這種狀況下,咱們大膽選擇JPG就能夠了。

二、場景的前景,裝飾物,可移動對象

這種要看規模,若是規模較小,類型很少。 或者類型雖然多,但同一時間出如今場景中的類型很少,那咱們能夠選擇壓縮PNG8的方式,它支持ALPHA通道,文件又小。

若是同屏可能出現多種這種,則須要考慮在IOS上使用PVRTC,在ANDROID上使用ETC1+ALPHA_MASK

三、UI

UI的背景圖,能夠優先考慮使用壓縮PNG8,若是達不到精度要求,則使用PNG32。而對於UI的小元素,能夠考慮使用壓縮PNG8.

對於UI的圖標,通常是不帶ALPHA的PVRTC/ETC + 一張公共的ALPHA掩碼圖,經過雙層混合來實現圓邊效果。 由於圖標同屏出現可能較大。 若是圖標可以控制在必定範圍內,因爲圖標是48X48等大小,一張1024x1024的大圖,能夠放400個圖標。 換用JPG,也有4MB的開銷,若是這個是能夠接受的,也可使用JPG+ALPHA_MASK的方式。

 

寫到這裏才發現,其實只須要下面一句話就能夠搞定。

這類圖片會不會同時出現多個,同時出現時,內存開銷是否沒法接受, 若是確實沒法接受,則使用GPU紋理,不然,優先考慮JPG,JPG+ALPHA,或者PNG8

 

就是說,首先要減少安裝包大小,若是內存有沒法接受的狀況,才須要用GPU紋理進行優化。而咱們在優化的時候,最好是對某一類圖片進行統一處理。 好比場景圖片,若是決定了使用JPG,那就清一色的JPG。

 

紋理的出圖和處理


這麼多格式,若是讓美術來出圖,不是要折騰死麼。

所以,只須要規定,美術出圖只給PNG(有些可能會是TGA)便可,剩下的事情,程序本身寫腳本進行解決。 這樣能夠保證美術出圖的規範性,同時也避免了程序在優化過程當中,切換紋理格式帶來的從新出圖問題。

PS:pvrtc和etc均可以使用pvrtex tool進行轉換, etc的轉換也可使用mali的工具,看各人愛好了。 pvr的工具不論是下載,仍是查看文檔,都須要註冊,就不給連接了……。

 

結束


或許你會說,JJYY半天,沒有帶點實際的。

這句話真的挺嘲諷的,但我真的打算結束了,一是我想要說的,就是這些,二是,我沒有打算寫一個如何在移動平臺上使用各類紋理的文章。

但願這篇文章可以給迷茫的兄弟帶來靈感。

相關文章
相關標籤/搜索