我所理解的cocos2dx - 紋理(上)


  3d圖形渲染最重要就是把紋理貼到物體表面,這過程主要發生在着色器工作階段,使用光柵化階段插值計算得出紋理坐標從紋理中采樣,然后對片段着色,可以處理豐富特效,光照陰影等。

 

光柵化

 作用是將2d圖元轉為幀緩沖的整數坐標的片段,每個片段包括顏色深度和模版值。首先確認視窗上哪些整數位置的片段會被圖元覆蓋,然后對圖元進行插值計算。這些信息會被送入后續的階段進行處理,最后結果用於更新幀緩沖上的該位置信息。片段的顏色由片段着色器決定,光柵化會生成一些易變變量。

  多重采樣:高分辨率信號以低分辨率表示無法准確運算出3d圖形坐標時導致的圖形混疊,具體就是鋸齒的產生。多重采樣就是解決這問題,它是通過以采樣點為中心位置,對附近進行采樣,共同決定這個點的顏色。多重采樣的數據存儲在幀緩沖額外的多重采樣緩沖區。cocos2dx默認沒有開多重采樣,要手動設置CCEAGLView為yes開啟,並且只能初始化的時候開啟。

  紋理坐標:紋理以左下角為原點,一個頂點在紋理中坐標通常使用uv,長寬是紋理的長寬,這是給客戶端程序使用的。片段着色器使用坐標st,范圍為0-1,這一規化過程在光柵化階段完成。

 

像素矩陣

  定義:二維像素數組,表示區域內的顏色,深度或者模版值。

  像素矩陣從內存傳輸到服務端的過程叫解包,從服務端讀取到內存叫壓包。

  像素存儲模式:紋理像素編碼用void PixelStorei(enum pname, T param)設置,會影響到像素矩陣數據傳輸相關指令,初始值4,合法值1248

  紋理數據的傳輸:客戶端->服務端,輸入是像素數據,輸出是0-1的rgba像素值,在操作的命令中,都會包含一些基本參數:

    format:一個像素矩陣中數據的構成

    data:ubyte或者ushot數組,數組中的元素被按照1,2,3或者4個分量形成一個組

    也就是說,format決定data的分量意義和順序。最后那個是亮度?

    type:表示每個像素分量的構成(format),以及data數組中每個元素的數據類型(data里數據組成)代表上圖每一個分享的大小,565說明是5紅5藍6綠的大小占位,人眼對綠色敏感。

  解包:format描述像素矩陣的數據類型,type決定每個分量的構成,所以所有編碼格式的像素矩陣的數量由format和type共同決定。其所有組合方式如下:byte占據一個byte,ushort占據2個。像素矩陣數據的傳輸,應該適當的選擇內存中數據的對齊方式(c++里也有類似的思想),提升數據傳輸的性能。這里只是簡單的對齊,會由8-4-2-1方式進行檢查,哪個滿足用哪個對齊,其參數為UNPACK_ALIGNMENT。

  unsigned_short_4444,5551,565會被包裝成一個ushort,2個byte,16位,數字代表每個分量的構成。例如5551就是rgb和1位alpha,要么透明套么不透明,適合用於字體或者蒙板。

  所有類型,格式的數據被解包之后,他們的byte或者short會被轉為浮點型,實際上是執行了歸一化計算[-1,1],之后還需要轉為rgb格式,主要針對的是LUMINANCE和LUMINANCE_ALPHA,luminance會轉化為rgb3個分量。所以最后,每個組都被轉化為4個分量。一個像素矩陣就被解包為一個顏色值上傳到gl緩沖區。

 

 客戶端圖像格式

  服務端上為了渲染性能,紋理數據都是沒壓縮的,而客戶端為了節省占用空間,一般進行了壓縮,所以在傳輸前,需要解壓圖像,轉為服務端可支持的格式。

  紋理格式的對應關系:

  圖像數據格式轉換:客戶端需要把不同的圖片格式轉換成對應的客戶端格式,通過convertDataToFormat實現,默認為auto,auto會嘗試轉為最接近的格式。實際上默認為rgba8888,如果我們不需要如此高質量的圖像,可以設置為其他,玩家也看不出。

 

紋理對象和加載紋理

  紋理在片段着色器被使用。

  紋理對象是一個容器,擁有該紋理所需的所有數據,包括像素數據,過濾模式,擴展模式等。

  glGenTextures(GLsizei n, GLuint *textures)創建紋理,n表示創建紋理對象的數量,textures用於保存分配的紋理名稱。

  glDeleteTetures(同上)刪除

  glBindTeture(GLenum target, GLuint texture)為了操作紋理,需要綁定一個當前操作的紋理,因為opengl不持有紋理的指針。

  glTexImage2D(GLenum target, GLint level, GLenum internalFormat, width, height, border, format, type, pixels)target為紋理的一個面,level為多級紋理的級別,internalFormat為紋理在GL的存儲格式,wh尺寸,format表示客戶端圖像數據的構成和順序,type是gl中紋理的格式和數據類型,pixels表示客戶端的圖像數據緩沖對象。

  紋理一旦傳輸到gl服務端,就會一致駐留在gpu,所以不用時記得刪掉。

 

紋理單元和多重紋理

  opengl 支持一個管線中使用多個紋理,使用紋理單元管理多個紋理的使用,每一個紋理對象都被放到一個紋理單元中,用glActiveTexture來激活紋理單元。激活實際上就是設置當前紋理單元,這樣后續的命令可以將紋理綁定到這個單元上,通過賓得TextureDN來綁定紋理到紋理單元上。

 

紋理縮放

  紋理被檢測到縮放的時候,opengl會使用TEXTURE_MIN_FILTER或者TEXTURE_MAG_FILTER進行紋素過濾。

  紋理縮小:多個紋素放到一個像素點去,將用texture_min_filiter來決定紋素的選擇,有2個值:

    GL_NEAREST:選擇離坐標中心最近的紋素,速度快,導致嚴重失真

    GL_LINEAR:選擇坐標中心附近一個2*2的區域,進行雙線性插值計算,得出一個合理的顏色值,損失性能,每一幀都進行,效果平滑

  紋理放大:一般一個紋素用到多個像素點去,同上,nearest最近點取樣,linear4個點求平均。

 

cocos2dx中設置過濾模式

  設置過濾模式的方法有:

    setTexParamters(const TexParam& texParams);  //各種縮放紋理過濾模式,還能設置紋理的重復模式,來決定紋理超出尺寸的采樣行為

    setAntiAliansTexParameters();  //鋸齒

    setAliasTexParmeters();  //反鋸齒

 

多級紋理

  就預設好很多個不同size的圖片,后續進行選擇,其TEXTURE_MIN_FILTER新增4種模式

    GL_NEAREST_MIPMAP_NEAREST:選擇最近級別的紋理進行最近點采樣

    GL_NEAREST_MIPMAP_LINEAR:選擇最近2個級別的紋理進行最近點采樣,然后取線性插值

    GL_LINEAR_MIPMAP_NEAREST:選擇最近級別的紋理進行雙線性采樣

    GL_LINEAR_MIPMAP_LINEAR:選擇最近2個級別的紋理進行最近點采樣,然后雙線性采樣,再取2個采樣的線性插值

  多級紋理的上傳:level參數決定紋理的級別,一般最大尺寸為0。可以使用initWithMipmaps來上傳多級紋理。這里可以針對低分辨率的設備避免上傳過大的紋理,節省內存

  多級紋理的生成

    glGenerateMipMap()生成,需要手動調用,但每次上傳紋理需要執行,有一定性能消耗,但可減少內存占用。

    使用工具,pvrtextool之類

 

紋理壓縮

  紋理需要傳進gpu里,轉為rgb或者rgba來處理,占用大量內存。

  壓縮紋理的特點:

    1.解壓速度:需要有較快的解壓速度

    2.隨機讀取:有時候只需要紋理的一部分,就需要隨機讀取的能力

    3.壓縮率和圖像質量:一般為有損壓縮

    4.編碼速度:沒太大要求,因為一般發生在程序外

  壓縮紋理的實現:傳統圖像壓縮使用可變的壓縮比率,導致讀某位置需要解壓更多位置,不利於隨機讀取。壓縮紋理用固定壓縮比率,按比率分成多個像素塊,每一個2*2或者4*4,然后對一塊進行壓縮,存在一個像素集合中(codebook),一塊索引圖(Index Map)中。讀取時根據索引找個像素塊,解壓,讀取偏移值信息,稱為基於塊的壓縮算法。

  pvrtc 和 pvrtc2:ios全產品和安卓大部分都支持這2個壓縮格式。

  pvrtc只支持pot紋理,網上說這個pot紋理在蘋果里有個bug,會導致內存占用增多,大家都希望用npot。而pvrtc2就是增強版,支持了npot,增強畫質,支持alpha預乘。兩種都支持2bpp和4bpp的壓縮比率。

  etc,幾乎所有安卓都支持這個。

  支持4bpp,不支持alpha通道。有幾個方式讓他支持:
    1.將alpha轉為可見的灰度圖像,拼接在一起,使得紋理高度為原來的2倍。缺點是紋理尺寸變大,限制原紋理的尺寸,有的不支持那么大

    2.alpha通道單獨生成一個紋理,用多重紋理技術綁定一起,后面混合即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM