2016年4月21日 星期四

0421 cocos2d-x學習筆記-紋理優化

cocos2d-x學習筆記-紋理優化


http://blog.chukong-inc.com/index.php/2013/02/04/%E5%A6%82%E4%BD%95%E4%BC%98%E5%8C%96cocos2d-x%E6%B8%B8%E6%88%8F%E7%9A%84%E5%86%85%E5%AD%98/
在遊戲項目優化中都會碰到一個問題,如何既能減少內存又能儘量減少包的大小?在實際項目中有些經驗分享一下,事實上2D遊戲中最佔內存的就是圖片資源,一張圖片使用不同的紋理格式帶來的性能差異巨大,下表是我在IOS平台一個小Demo中的測試結果,該Demo的原始內存佔用是7M,測試方法是一次性加載5張2048*2048的圖片,使用TexturePacker工具生成圖片,內存統計使用Instrument工具,加載時間統計用-X引擎提供的CCTime類,單位是微秒。
圖片格式               加載時間   內存佔用 備註
png                         782080     88M         5張 2048*2048 的PNG
pvr.ccz(POT)      394769       102M        5張 2048*2048 的pvr.ccz(POT:2的整次方)
pvr.ccz(NPOT)   338099      85M          5張 2047*1680 的pvr.ccz(NPOT:非2的整次方,即圖的實際大小)
pvr(PVRTC4)     8875            33M          5張 2048*2048 的pvr(PVRTC4:壓縮比率為8:1的有損壓縮,實際測試發現畫質基本沒有損失)
結論:
1)比較加載速度:原始PNG是最慢的,使用POT的pvr.ccz大約是原始PNG的50%,使用NPOT的pvr.ccz大約是原始PNG的43%,使用pvr則只要原始PNG的1%;
2)比較內存佔用:使用POT的pvr.ccz大約是原始PNG的1.2倍,使用NPOT的pvr.ccz和原始PNG差不多,使用pvr只要原始PNG的40%;
從中可以看到,對於尺寸大的圖片,選擇紋理格式時,最優先使用的是PVR,其次是NPOT的pvr.ccz,考慮到多平台支持,綜合起來,對圖片資源的管理方案可以如下(以下所說圖片尺寸以iPad高清為標準):
1)對於1024*1024及以下的小圖片,還是使用PNG,因為簡單,所有平台都能用;
2)對於1024*1024以上的圖片,首選用pvr,它能直接載入到IOS設備的顯存裡,無需經過內存解析,所以快;但是,遺憾1:安卓設備不支持;遺憾2:TP工具不支持生成2048*2048以上的pvr;
3)如2所述,對於2048*2048以上的圖片,及安卓設備,則使用NPOT的pvr.ccz,在Cocos2d-x 2.x引擎裡默認已經支持,所有3代(iphone 3GS)以後的ios設置都支持cocos2d 2.x(因為它們支持OpenGL ES2.0),所以也都能支持NPOT紋理;
4)經過測試,安卓設備也支持NPOT,所以方案比較簡單,1024*1024及以下的用PNG,1024*1024以上的使用NPOT選項的pvr.ccz;
採用以上方案後,遊戲所佔內存從90多M降到了60多M,在IOS各種設備跑過了,touch3、touch4、iPad1等低端設備都沒問題。


http://codingnow.cn/cocos2d-x/821.html
轉載自:紅孩兒的遊戲編程之路CSDN博客地址http://blog.csdn.net/honghaier
在目前的移動平台遊戲開發過程中,很多朋友會遇到開發出來的DEMO佔用內存過大,導致渲染效率低下的問題。究其原因,是由硬件本身和軟件邏輯兩方面的因素造成的。在硬件上,移動設備往往可用內存相比於PC還比較小,所以所能使用的內存就少。在軟件邏輯上,大量使用大圖片導致佔用內存過大,以及過多單圖片導致渲染時多次切換使用的紋理,也會大大降低渲染效率。
首先,硬件的內存限制我們是沒有辦法踰越的,所以在你開發一款遊戲時,一定要清楚的知道你的程序在運行時的內存需求量,它務必要小於可用內存,而且要越少越好。我們在開發2D遊戲時,最多用到的資源就是紋理,一張寬高均為1024大小的格式為ARGB8888的紋理。其佔用的內存量至少是4M。所以,你一定要在紋理的優化上下功夫。
紋理的優化,方案有很多。我們逐個來列舉。
(1)色深優化
大家先來看一下下面這張對比圖:

第一張圖是ARGB888格式,第二張圖是我轉為A1R5G5B5後的PVR圖,我以一個一般玩家的視角來看是看不出有什麼差別的。但是第一個圖每個像素佔4字節,而第二張圖每個像素佔2字節。這意味著看起來幾乎相同的圖片,佔用的內存可以減少一半。
這一方案並不適用於所有情況,你需要對每種圖片進行考慮,如果說你的圖片的ALPHA通道不是用於鏤空,而是用於渲染ALPHA混合。那你轉為只佔1位的ALPHA通道格式紋理是肯定不行的,你可以試試ARGB4444。而對於無ALPHA通道的圖片,如果使用的是RGB888,可以嘗試轉為RGB565。另外,轉換之後一定要由美術人員進行實際觀察進行確定。如果轉換後的圖像有明顯的失真,那就算了。
(2)拼圖優化
還是先上圖吧,首先是一堆小圖:

這一堆小圖共有20張,都是PNG格式的RGBA8888。其中有15張圖大小是85×121,一張52×139,兩張是52×200,還有兩張是37×37。
下面是拼合後的PNG圖,格式與小圖一致。

此圖大小為512×512,可以看到其仍然有很大一片空白可供繼續拼合一些小圖。
好吧,我們來對比一下它們所佔的內存。
第二張圖大小為512×512,所以創建RGBA8888格式紋理需要1M內存來存儲像素數據。
前面那一堆小圖呢?
15張圖大小是85×121。我們知道OpenGL ES在生成紋理時大小會擴展成2的冪次方。那85×121圖片所生成的實際紋理大小為128×128,一張128×128大小的RGBA8888格式紋理需要64K內存來存儲像素數據。15x64K = 960K。
1張52×139,實際紋理大小為64×256 ,也需要64K
兩張是52×200,實際紋理大小為 64×256,需要64K,兩張需要128K
還有兩張是37×37。實際紋理大小為64×64,兩張需要32K
算一算吧,只是存儲像素數據總共需要的內存大小為 1184K。還不包括產生的紋理其它信息所佔用的內存量,而且我們的拼合圖還有很大的空白可供更多的小圖進行拼合佔用。
這還會導致一個更明顯的效率問題,因為在渲染中,使用散圖意味著增加切換紋理的開銷,如果圖片很多,那麼紋理的頻繁切換會導致你的遊戲FPS大大降低。而採用拼合圖,你將只需要很少次設定使用紋理,就可以渲染出大量的圖形,大大減少了切換紋理的開銷。
(3)骨骼動畫
是剛知道Cocos2d-x2.0.3版本已經支持骨骼動畫系統。Cocosbuilder2.1版本工具中也可以進行相應的骨骼動畫編輯。這對於優化內存是一個很好的方案。
以前做人物動畫我們常常使用每一幀畫一幅圖片的逐幀動畫方式。使用骨骼動畫可以大大降低圖片幀的數量,它只需要很少的圖量就可以達到幾乎相同的動畫效果。但需要做比較複雜的編輯工做,對每一個關健幀的骨骼點進行編輯。
骨骼動畫的製做流程一般為:
1.通過設定基礎的骨骼點並構建出骨架關係樹。將人物按骨架樹劃分成各個身體部件。
2.按照劃定的身體部件來製做人物或動物圖片,當然一般是將整個人物或動物圖片進行切圖命名圖塊來取得。
3.將身體部件圖塊綁定到相應的骨骼上。
4.設定關鍵幀,編輯關鍵幀上所有骨骼的位置及縮放與旋轉變化。
5.播放動畫,使骨骼按照時間進行兩個關鍵幀間的變化插值計算,使用插值後的結果來影響身體部件圖塊繪製時的頂點位置。
骨骼動畫的算法關鍵是對於骨骼動畫編輯器的掌握,希望大家多多研究使用。
可參看網友豆奶哥哥的博文:
http://www.cnblogs.com/lovegame/archive/2012/10/15/2722626.html
(4)批次處理
批次,即Batch,也是遊戲引擎中一個重要的優化指標。它指的是一次渲染凋用。顯而易見,渲染的次數越少則遊戲的運行效率越高。
Cocos2d-x是明顯懂得這個道理的,舉個最明顯的栗子。咱們之前講過的「深入分析Cocos2d-x中的圖字原理」中有一個類CCSpriteBatchNode,它就是為了降低渲染批次而創造的一個專門管理精靈的類。這麼說吧,我們渲染一段話「你吃了麼?」,這裡面有五個字,所以要創建五個CCSprite來對應這五個這的圖塊繪製,但繪製時我們如果一個一個的繪製,那是很恐怖的一件事,你的遊戲寫的字如果很多,你就可以放棄干其它的事情了,因為渲染調用次數太多而導致效率低下。為了提高渲染效率,專門的類CCSpriteBatchNode就出現了!他在一次渲染中把這所有的CCSprite都繪製了出來。所以,我想說,如果你要提高你的渲染效率,好好分析分析怎麼使用CCSpriteBatchNode,將你的遊戲中的大量圖片精靈儘可能的放在CCSpriteBatchNode中來渲染,一定可以提高FPS的。
Cocos2d-x 2.0之後在左下角加入了渲染批次統計,呵呵,好像借鑑了OGRE的統計方式,為什麼要統計渲染批次呢?就是為了讓我們在進行優化時有個可以觀察的指標。如圖所示:
(5)使用壓縮紋理
IOS設備用的是PowerVR顯示芯片,而PVR格式可以被該顯示芯片直接讀取,在之前的博文裡有分析過PVR格式紋理的源碼,大家可以從中瞭解到PVR格式所支持的多種壓縮格式。我們在開發IOS遊戲時,也應該儘量使用合適的壓縮格式的圖片。如「pvr.ccz」。
這部分有個性能小測試,有興趣的可以參見:
http://blog.sina.com.cn/s/blog_6fbe210701015j7z.html
經過上面的一些優化策略,應該已經可以大大的降低內存使用,並提高渲染效率。如果大家還有什麼更好的方案,也歡迎大家隨時提出來。

沒有留言:

張貼留言

cocos2dx-lua 建立滑鼠監聽

重要關鍵字  EVENT_MOUSE_SCROLL addEventListenerWithSceneGraphPriority      if IsPc() then --建立滑鼠監聽         local listener = cc.EventListenerMouse...