于是,我決定盡力描述一下紋理格式選擇方面的問題,一是起到一個科普的作用,因為目前沒有發現十分完整的講這方面的文章。二是整理一下自己的思路。
當然,這些東西肯定不是我自己憑空yy出來的,我也是參考了不少文章,也從項目中總結了一些問題。在此先列出一些連結,先睹為快
<a href="http://www.cnblogs.com/geniusalex/p/3561099.html" target="_blank">移動平台gpu壓縮文理大全</a>
<a href="http://malideveloper.arm.com/cn/develop-for-mali/sample-code/etcv1-texture-compression-and-alpha-channels/" target="_blank">使用mali官方工具進行etc1紋理壓縮</a>
<a href="http://en.wikipedia.org/wiki/ericsson_texture_compression" target="_blank">ericsson texture compression</a>
<a href="http://www.j2megame.org/index.php/content/view/2825/165.html" target="_blank">ios和android遊戲紋理優化和記憶體優化(cocos2d-x)</a>
<a href="http://www.bennychen.cn/2013/05/optimising_your_mobile_game/" target="_blank">優化你的手機遊戲(沒有延遲,才是健康的)</a>
<a href="http://blog.csdn.net/honghaier/article/details/8075354" target="_blank">cocos2d-x紋理優化方案的一些總結</a>
<a href="http://blog.csdn.net/langresser_king/article/details/9313255" target="_blank">手機遊戲開發紋理圖檔優化心得</a>
<a href="http://youxiputao.com/articles/1152" target="_blank">手機遊戲開發,如何選擇和優化圖檔素材</a>
嗯 ,我覺得已經足夠多了,并且,可能你也沒有耐心把所有連結看完。 至少我沒有……。
很多小夥伴其實一直不明白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
上面的紋理格式,同一種情況下,可能多種都适合,那如何選擇呢。 我們還是根據具體情況而定。
1、場景、背景、全屏圖檔
2d手機遊戲中,多半都有這樣的圖檔,以作為背景,特别在一些slg,橫版過關遊戲中。這種圖檔對alpha沒有要求,并且,在同一時間,隻會出現一張(如果是多張拼接,也不會超過螢幕尺寸太多),記憶體不會成為關鍵點。是以,在這種情況下,我們大膽選擇jpg就可以了。
2、場景的前景,裝飾物,可移動對象
這種要看規模,如果規模較小,類型不多。 或者類型雖然多,但同一時間出現在場景中的類型不多,那我們可以選擇壓縮png8的方式,它支援alpha通道,檔案又小。
如果同屏可能出現多種這種,則需要考慮在ios上使用pvrtc,在android上使用etc1+alpha_mask
3、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半天,沒有帶點實際的。
這句話真的挺嘲諷的,但我真的打算結束了,一是我想要說的,就是這些,二是,我沒有打算寫一個如何在移動平台上使用各種紋理的文章。
希望這篇文章能夠給迷茫的兄弟帶來靈感。
簡介:09年入行,喜歡遊戲和程式設計,對3d遊戲和引擎尤其感興趣。
版權聲明:本文版權歸作者和部落格園共有,歡迎轉載。轉載必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
轉載:http://www.cnblogs.com/geniusalex/p/3854410.html