剖析plist文件在游戏中运用的优点

1. 预备知识

什么是图片的alpha通道?
它一个8位的灰度通道,用256级灰度来记录图像中的透明度信息,定义透明不透明半透明区域,其中表示不透明,表示透明,表示半透明。


如何计算图片所占内存的大小

  • 计算像素总数:640*480
  • 32位,每个像素占32Bit:640x480x32
  • 8Bit = 1Byte = 1/1024 KB = 1/1024/1024 MB:64048032/8/1024/1024

索引彩色模式
以往图片都是保存每个像素的彩色信息,现在却是从图像中挑选出来具有代表性的颜色编号,每个颜色编号对应一个颜色,这样图片的数据量较小
索引透明
设置特定索引值为透明色
alpha透明
设置索引色附加八位透明度

2. 纹理格式

2.1 png格式

无损压缩的位图图形格式,支持索引、灰度、RGB三种颜色方案、Alpha通道

优点:无损、高视觉质量、可处理8位和16位透明度
缺点:高GPU成本

2.1.1 为什么很少直接使用png

PNG是变长编码格式,颜色变化少频率低的部分,编码后占的内存字节数就少。除非你把整张图片都解压完毕,否则无法准确的计算出原图一个坐标处的color对应的压缩到了哪里
PNG是用来在游戏制作流程中间传递美术内容的,最终在游戏引擎里需要转变成一种固定码率的、可寻址的流式压缩格式,以方便随机寻址和采样,所以就出现了PVRTC/ETC等格式。

2.2 pkm格式

PVRTC/ETC等Texture Compression格式,直接被GPU读取到显存,用时无需解压
pkm属于ETC纹理压缩类别(4bits)。ETC纹理压缩是由Khronos为OpenGL ES 2.0制定的纹理压缩格式,几乎所有的Android设备都可以使用这种纹理压缩格式。
ETC的缺点:不支持RGBA 4通道的图片压缩即不支持透明图片

2.2.1 如何使etc支持透明图片
  • 方法一: 一种是通过Mali工具生成pkm文件时选择Create atlas,这样就生成了一张拼接在一起的纹理。这张纹理上半部分是原始图片(无alpha信息),下半部分是alpha信息图片。在渲染的时候使用特殊的shader进行渲染
  • 方法二: 创建两张分离的图片,分别是原始图片和alpha图片。渲染时加载这两张纹理,然后alpha图片当做参数传递给原始图片的shader

2.3 PVRTC格式

2.3.1 什么是PVRTC格式

PowerVR纹理压缩(PVRTC)纹理压缩是一种有损固定速率的纹理压缩格式(4bits)。它目前被用作所有iPhone ,iPod 和iPad 设备的标准压缩格式,它们的图形芯片对它提供硬件支持。
与ETC不同,PVRTC不是基于块的。相反,它涉及两个低分辨率图像的双线性放大和低精度混合。除了PVRTC格式的独特压缩过程外,它还支持2-bpp(每像素位数)和4-bpp选项的RGBA(支持alpha通道)。

2.3.2 优缺点

优点:
(1)支持alpha通道/组件。
(2)支持2-bpp和4-bpp模式下的RGBA数据。
(3)文件大小比通过PNG纹理压缩产生的小得多。
(4)PowerVR GPU上的GPU硬件加速。
缺点:
(1)质量不如PNG纹理压缩(PVRTC是有损压缩格式)。
(2)PVRTC仅在PowerVR硬件上受支持。
(3)只有正方形(幂的两个)尺寸纹理被确定为一致地工作,尽管在某些情况下,为压缩纹理提供了矩形支撑。
(4)将纹理压缩为这种格式可能会很慢。

3. 为什么要使用plist合图

内存问题:OpenGL ES纹理的宽和高都是2次幂数,假设1.png本身是480x320,但是载入内存后,会变成一张512x512的纹理,当我们使用plist把图片拼在一起后,这些浪费的空间就被合理利用起来了。
渲染速度:从OpenGL ES上来说我们应该尽量减少渲染时切换纹理和调用glDrawArray。如果我们是一张张散图,那么每画一个图像都会切换一次纹理并调用一次glDrawArray。而使用了合图,就可以进行批次的渲染。

4. 批次渲染

与普通渲染不同,它不是每渲染一次就进行清除,而是渲染了一段时间再清除。
优点:io次数明显减少,渲染效率提高(可参考CCSpriteBatchNode

4.1 自动批次渲染

只要精灵使用同一纹理,没有更改blendFunc,shader,就满足自动批次渲染,会自动将这些精灵加入同一渲染批次里,优化渲染速度。(相同纹理、相同混合函数、相同shader)

5. DrawCall

简单来说,因为GPU渲染三角形的效率非常高,如果我们每次在draw call只提交极少的数据,那么大部分CPU就会处于空闲状态,CPU将不能足够快的提供数据给GPU。并且GPU在draw call之间,为了防止前后Draw的依赖关系造成的绘制错误,一般会在draw call后刷新整个缓冲区,那么如果draw call的数据过少,那么一直不断的在刷新缓冲区,这对GPU也会造成浪费

参考资料:
减少Draw Call(批渲染)
why are draw calls expensive?
优化 Cocos2d-x 游戏性能
纹理像素格式

你可能感兴趣的:(剖析plist文件在游戏中运用的优点)