首页 > 代码库 > 转发收藏【原创】浅谈UGUI的ETC1+A的纹理压缩方案总结
转发收藏【原创】浅谈UGUI的ETC1+A的纹理压缩方案总结
这个信息很早了,2016年6月研究出来的,当时分享在ulua群1共享里面,然后就被大家的文件淹没了,但是这个话题并不老,这不整理群共享空间的时候,被我翻出来了,拿来炒炒。
ETC1+A还是目前业内绝大多数手游纹理压缩方案,因为ETC2依赖于OpenGL3.0,而安卓的OpenGL3依赖于Android 4.3.0,如果不支持OpenGL3的话,系统会自动软解码纹理压缩,但是U3D处理这块很麻烦,要自己分割Alpha通道出来,然后再修改shader合并Alpha,挺麻烦的。
Unity5.2开始吧就有个选项:
当时看到这个选项挺兴奋的,因为引擎总是自身支持ETC1+A了,我们终于不用瞎折腾了,经过测试,UGUI并不支持这个选项,什么yis意思:就是说你如果用UGUI的Image组件,它的Sprite并不能使用这个选项,设置也没卵用。fuck,那要你干嘛?后来翻了下unity官方论坛,弄了半天说是只有Sprite Renderer才支持,也就是2D/Sprite组件,但是,我想要UGUI支持咋办?官方给出的jie结论是:未来支持。。。
既然官方靠不住,那就自己研究吧,UGUI自带的Sprite Packerbie别指望了,完全黑箱操作,你也没法干预,这块直接放弃掉,想起了在NGUI时代就盛行的Texture Packer,经过研究终于搞定了。
分3部分:
(1)Editor脚本,将RGBA的纹理分割为RGB+A,然后将两张纹理分别用ETC1压缩。
Texture2D aTex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false); Color newColor = new Color(0f, 0f, 0f); for (int i = 0; i < tex.width; ++i) { for (int j = 0; j < tex.height; ++j) { newColor = tex.GetPixel(i, j); //rgbTex.SetPixel(i, j, newColor); newColor.r = newColor.a; newColor.g = 0; newColor.b = 0; aTex.SetPixel(i, j, newColor); } } string path = oldPath.Substring(0, oldPath.LastIndexOf(".")); byte bytes = aTex.EncodeToPNG(); File.WriteAllBytes(path + "_ETC1_A.png", bytes);
(2)shader部分,从官方自带的builtin_shaders-5.2.3p3里面解压出UI-Default.shader放入工程,然后修改代码:
fixed4 frag(v2f IN) : SV_Target { half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; fixed4 alpha = tex2D(_AlphaTex, IN.texcoord); if (_UseClipRect) color *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); if (_UseAlphaClip) clip (color.a - 0.001); color.a = color.a * alpha.r; return color; }
上面代码就是简单的合并了alpha通道。
(3)然后新建一个材质,选择修改后的shader,将第一步生成的2张纹理拖进去,
(4)在Canvas下面新建一个Image,选择图集的Sprite,并且选择xia相应的材质赋值上去:
至此,大功告成!!
链接: http://pan.baidu.com/s/1slDEGv7 密码: quxy
转发收藏【原创】浅谈UGUI的ETC1+A的纹理压缩方案总结