转载请注明出处
我们知道手游的表现力和美术密不可分,美术资源的滥用往往会导致大量的美术返工。所以根据游戏的需要制定合理的美术规格十分重要的。写这篇文章的目的在于解决两个问题。第一,美术作图有怎么样的规范,第二,图片unity怎么处理最好。
因为我们项目是2D项目,很少涉及3D模型,我们这里的美术资源就特指2D Texture。
特别的,我们在这里只研究texture type为sprite 的情况。因为场景中的object的component只有sprite render,而且这样也覆盖了gui。
首先介绍一下sprite的各个参数的简单含义。
Sprite Mode: single独立图片multiple 多张有关联图片,可以editor切割
Packing tag: 同样的tag可以在sprite packer中打包图集,pro only
Pixelstounit: 单元sprite像素数量,越大越精细,默认100
Pivot: 中心点,设计到rotate的时候特别要当心
Mipmaps: 多重纹理,内存多1/3。做3D的话建议详细了解一下
Fitermode: 被拉伸时候的填充模式
Maxsize: 图片大小
Format: 纹理格式
详情参见
与纹理相关的几个方面:内存大小,安装包大小和drawcall。当然还有cpu,gpu处理速度,读取速度,这里就不讨论了,我们专心讨论以上三点。
首先讨论内存和安装包:
Unity资源选中图片,inspector显示的大小,即读入内存的大小。我们知道,unity可以读取多种图片格式,它内部会处理成为自己的专门格式,打包的时候会以assetbundle方式存放。所以,内存的大小依赖于纹理参数,而与图片是什么格式的没有关系的。而打包成为assetbudle和内存相关同时也和原图的大小相关。(其实取决于原图大小和纹理参数)。我们可以简单地认为内存占用多了,安装包就大。
我们首先来看一下psd图片直接放在unity的情况。(maxsize= 1024 format = truecolor)
再看一下maxsize,format对内存及安装包的影响。
上面两份表格中1024*1024分辨率的用的是同样的图片。我们可以看出,IOS上可以压缩(POT图,正方形图)对内存和包大小有很大的优化,而format和maxsize同样也有影响。
抛开实验图片不谈,针对我们的游戏(大量透明图,色彩数广)对原图(大于1024*1024)的不同处理会有不同的效果:
1 maxsize调整为512。稍微失真,可以接受。
2 format由RGBA32调整为 RGBA16。完全失真,不能接受。
3 IOS压缩为PVRTC4bit。失真非常小,完全可以接受。
4安卓压缩为RGBA16。完全失真,不能接受。
再看一份表格,同样的图片表现,美术在作图时处理为不同分辨率。
其中1024*1024的图片内存直接从4M到0.5M,安装包减少4倍。优势实在太明显了,遗憾的是,它只支持IOS,安卓却不可以。
再次我们讨论drawcall
对于纹理首先想到的就是纹理合并。对于spritepacker,官方文档中“For optimal performance”主要有两点,即对于empty space和 drawcall的影响。于是对于drawcall的讨论我们这里变成对spritepacker的讨论
详情参见。
Sprite render同一材质不同纹理依旧会产生多个drawcall,而纹理的合并会减少drawcall。实际上在我们的游戏中,摄像机范围内的图片总是有限的,drawcall的数量很低的,所以我们的重点不在这里,而是spritepacker对空间的影响。
如果我们对场景中大图小图全图打包会如何,场景加载时候无论用到什么图,都会载入图集的内存,如果只用到了小图,那么图集的出场无异于牛刀杀鸡,这也是为什么好多项目谈经验的时候只对GUI的图进行图集处理,并不是NGUI做了这份工作,以前没有UGUI的时候没做。
而我们的场景中基本都是背景图,所以并不适合打包进图集,而小的“零件图片”却可以被pack,,多余的加载可以换来IO的节省,这样的规划应该是比较合理的。
关于spritepacker其实还有个问题没有研究清楚。Pack后的图集是放在library的cache里面的,library添加到SVN的ignore里面的。按照官方说法,如果cache没有图集,则会再次pack。可是我们知道,pack的时候可以定制的。改变pack方式难道不保存在一个setting文件里面传上去吗?还是在library文件里面被ignore掉了。前面我在思考这样一个问题:
如果美术给的图是NPOT的多张RGBA32图,打包到了一个1024*1024的图中,选择的是定制的spritepacker,设置图集的entry.settings.format =TextureFormat.PVRTC_RGBA4,是否意味着我对这10张都进行了合并成一个RGBA32格式的图集然后进行对图集PVRTC压缩?如果是这样的话,那么不就是可以进一步优化了?不过话说回来,小图的表现力就那么微观,稍微一点失真还是可以看出来的,另一方面优化的程度也没有那么大,整个等项目后期处理时候再考虑吧。
总结上面,针对我们项目的处理方案:
美术作图:Height/width 256以下图片任意作图,因为好多与UI类似。
Unity处理:选择RGBA32做spritepacker,是否可以压缩为PVRTC再做考量。
美术作图:Height/width 256+的图片,做成POT图片
Unity处理:2048/1024的maxsize设置为1024/512(失真可接受),PVRTC压缩。
人生就是要感受美丽的善良的,丑恶的病态的。