Unity Android平台下针对Alpha分离的优化---三张Alpha贴图合并为一张
2017-05-02 14:56
465 查看
Alpha分离:
开发一款移动端游戏总会遇到选择贴图格式的问题, 目前在Android平台上比较理想的, 而且压缩率比较高的贴图格式ETC1, 因为ETC1本身就是OpenGL ES图形标准的一部分,并所有的Android设备所支持。 不过可惜的是这种压缩格式只支持RGB三个通道的要说,所以损失了A通道。
针对这个问题, 江湖上很早就有人相处了对策: 使用Alpha分离的方式, 即一张贴图分离为一张RGB贴图和一张Alpha贴图。 然后各自要说为ETC1格式。这样两张贴图总的大小依然比原先一张贴图RGBA32要小得多。 一张1024*1024的RGBA32格式的贴图占用内存4M, 而两张1024*1024 ETC1格式的贴图才1m(各0.5m)。 这样似乎很好的解决这个问题。而且互联网上搜索一下几乎都这么做的。
被浪费的两个通道:
Alpha贴图由个通道,现在只用了一个通道。另外两个就被浪费掉。 能利用起来吗。显然是可以的呀。但还是有条件的:
a、 我们要可以把相同尺寸的三张贴图的Alpha值合并为一张Alpha贴图,或者尺寸比例一致,并且大小相差不太大的贴图的alpha合并为一张Alpha贴图。
b、然后要指定Shader取特定通道alpha值。
对于前者,使用了NGUI的UIAltas的项目是特别适合的, 以为很多小图都集中到了一张图集,而图集的大小应该都是相近或者一样的。我们项目中Atlas的贴图只有两种size:512*512 和 1024*1024。 对于后者,只要将Unity的Material更换一个Shader即可。
怎么做:针对UIAtlas进行优化
步骤1: 准备三套alpha分离的UIShander(本来准备3个Shader即可,但UIPanel还要求有两个裁剪的shader,所以是三套)。
一套shader读取AlphaTex的r通道作为alpha : ShaderR
一套shader读取AlphaTex的g通道作为alpha : ShaderG
一套shader读取AlphaTex的b通道作为alpha : ShaderB
步骤2: 把所有的Atlas收集起来,根据其贴图尺寸大小进行分类。
每一类中再分成三个一组
步骤3: 同一组内, 把所有Atlas贴图的alpha提取出来,合成一张新的Alpha贴图。三张贴图的alpha信息分别保存在新的Alpha贴图中的r、g、b通道。Alpha贴图格式设置为ETC1.
步骤4: 同一组内,为每个Atlas生成一个新的材质球,根据其alpha分配在Alpha贴图中的通道分别选择ShaderR, ShaderG, ShaderB。
步骤5: 分别为新的材质球指定MainTex 和 Alpha贴图
步骤6: 为Atlas赋值新的材质球
到此,生成新的材质球和替换工作就已经结束了。 然后可以进入正常的打包程序了。
后话:
1、可以节省原先三分之二的贴图
2、写好工具之后,并不需要增加任何人工的工作量
3、不可能针对所有的的贴图都这么做。 目前最合适的就是那些大的UI贴图
4、贴图的分组需要根据项目的实际情况进行分配
开发一款移动端游戏总会遇到选择贴图格式的问题, 目前在Android平台上比较理想的, 而且压缩率比较高的贴图格式ETC1, 因为ETC1本身就是OpenGL ES图形标准的一部分,并所有的Android设备所支持。 不过可惜的是这种压缩格式只支持RGB三个通道的要说,所以损失了A通道。
针对这个问题, 江湖上很早就有人相处了对策: 使用Alpha分离的方式, 即一张贴图分离为一张RGB贴图和一张Alpha贴图。 然后各自要说为ETC1格式。这样两张贴图总的大小依然比原先一张贴图RGBA32要小得多。 一张1024*1024的RGBA32格式的贴图占用内存4M, 而两张1024*1024 ETC1格式的贴图才1m(各0.5m)。 这样似乎很好的解决这个问题。而且互联网上搜索一下几乎都这么做的。
被浪费的两个通道:
Alpha贴图由个通道,现在只用了一个通道。另外两个就被浪费掉。 能利用起来吗。显然是可以的呀。但还是有条件的:
a、 我们要可以把相同尺寸的三张贴图的Alpha值合并为一张Alpha贴图,或者尺寸比例一致,并且大小相差不太大的贴图的alpha合并为一张Alpha贴图。
b、然后要指定Shader取特定通道alpha值。
对于前者,使用了NGUI的UIAltas的项目是特别适合的, 以为很多小图都集中到了一张图集,而图集的大小应该都是相近或者一样的。我们项目中Atlas的贴图只有两种size:512*512 和 1024*1024。 对于后者,只要将Unity的Material更换一个Shader即可。
怎么做:针对UIAtlas进行优化
步骤1: 准备三套alpha分离的UIShander(本来准备3个Shader即可,但UIPanel还要求有两个裁剪的shader,所以是三套)。
一套shader读取AlphaTex的r通道作为alpha : ShaderR
一套shader读取AlphaTex的g通道作为alpha : ShaderG
一套shader读取AlphaTex的b通道作为alpha : ShaderB
步骤2: 把所有的Atlas收集起来,根据其贴图尺寸大小进行分类。
每一类中再分成三个一组
步骤3: 同一组内, 把所有Atlas贴图的alpha提取出来,合成一张新的Alpha贴图。三张贴图的alpha信息分别保存在新的Alpha贴图中的r、g、b通道。Alpha贴图格式设置为ETC1.
步骤4: 同一组内,为每个Atlas生成一个新的材质球,根据其alpha分配在Alpha贴图中的通道分别选择ShaderR, ShaderG, ShaderB。
步骤5: 分别为新的材质球指定MainTex 和 Alpha贴图
步骤6: 为Atlas赋值新的材质球
到此,生成新的材质球和替换工作就已经结束了。 然后可以进入正常的打包程序了。
后话:
1、可以节省原先三分之二的贴图
2、写好工具之后,并不需要增加任何人工的工作量
3、不可能针对所有的的贴图都这么做。 目前最合适的就是那些大的UI贴图
4、贴图的分组需要根据项目的实际情况进行分配
相关文章推荐
- Unity工程里图片的RGB和Alpha通道的分离,以及显示所有带有Alpha通道贴图的Material
- 针对Unity NGUI图集的Alpha通道分离优化
- 移动平台前端开发总结(针对iphone,Android等手机)
- 移动平台前端开发总结(针对iphone,Android等手机)
- android中将两张图片合并为一张图片 .
- Android平台根据分辨率计算屏幕尺寸,基于物理尺寸来验证手机和平板应用合并的可行性
- android中将两张图片合并为一张图片
- 索爱针对Android平台推出WebSDK, 主要是为其Android手机开发应用。
- Android平台根据分辨率计算屏幕尺寸,基于物理尺寸来验证手机和平板应用合并的可行性
- 移动平台前端开发总结(针对iphone,Android等手机)
- linux摄像头驱动的拍照流程分析(针对展讯8810(ARM架构),android平台)
- Android平台根据分辨率计算屏幕尺寸,基于物理尺寸来验证手机和平板应用合并的可行性
- 移动平台前端开发总结(针对iphone,Android等手机)
- android中将两张图片合并为一张图片
- Unity制作的应用在android平台上的发布步骤
- Unity制作的应用在android平台上的发布步骤
- Novell推出针对SAP所有应用而优化Linux平台
- 移动平台前端开发总结(针对iphone,Android等手机)
- Android平台根据分辨率计算屏幕尺寸,基于物理尺寸来验证手机和平板应用合并的可行性
- Android平台根据分辨率计算屏幕尺寸,基于物理尺寸来验证手机和平板应用合并的可行性