ETC1+Alpha纹理压缩自动化脚本

尊重原创,转载请在文首注明出处:http://blog.csdn.net/cai612781/article/details/78798054

一,压缩方式

我们在Unity中对于图集和纹理,常用的压缩方案按照质量从低到高可以分为:

高压缩:Android:ETC1+Alpha, IOS:PVRTC4
中压缩:RGBA16+Dithering
无压缩:RGBA32


二,自动化脚本

有很多工具可以处理上述压缩方案,例如TexturePack。今天来总结下采用脚本自动将纹理生成ETC1+Alpha的压缩方案。


采用的是Unity自带的一个压缩/解压缩ETC格式的图像工具:etcpack.exe。在Unity 4.x中可以在Unity安装目录/Editor/Data/Tools/中找到,Unity5.x中就被移除了。
更多参考: https://en.wikipedia.org/wiki/Ericsson_Texture_Compression


1,有了这个工具,我们并不知道怎么用。首先打开cmd,在cmd中运行这个exe。可以看到输出了使用方法和例子。
ETC1+Alpha纹理压缩自动化脚本_第1张图片 ETC1+Alpha纹理压缩自动化脚本_第2张图片


2,接着我们写个bat脚本来调用这个工具,保存为etc.bat文件
@echo etc tool
@echo %1
@echo %2
@echo %3
@echo %4
@echo %5
@echo %6
@echo %7
@echo %8
@set pngPath=%1
@set outputPath=%2
@set pkmPath=%3
@set alphaPkmPath=%4
@set pkmName=%5
@set alphaPkmName=%6
@set etcToolPath=%7
@set speed=%8

cd /d %etcToolPath%
@echo Convert PNG to PKM without alpha channel and solo alpha PKM files
etcpack %pngPath% %outputPath% -c etc1 -s %speed% -as -progress
@echo Convert PKM files to PNG files
etcpack %pkmPath% %outputPath% -ext PNG
etcpack %alphaPkmPath% %outputPath% -ext PNG
@echo Remove PKM files
cd /d %outputPath%
del %pkmName% /f
del %alphaPkmName% /f
@echo DONE
#pause



3,我们在Unity中调用这个bat脚本,主要步骤有:

A,C#创建cmd进程的方法

public static void ExecuteProcess(string filePath, string command, string workPath = "", int seconds = 0)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                return;
            }
            Process process = new Process();//创建进程对象
            process.StartInfo.WorkingDirectory = workPath;
            process.StartInfo.FileName = filePath;
            process.StartInfo.Arguments = command;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardOutput = false;//不重定向输出
            try
            {
                if (process.Start())
                {
                    if (seconds == 0)
                    {
                        process.WaitForExit(); //无限等待进程结束
                    }
                    else
                    {
                        process.WaitForExit(seconds); //等待毫秒
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }
            finally
            {
                process.Close();
            }
        }

B,通过A中方法传入参数执行etc.bat,方法参数是图片asset

public static void CompressPngToEtc(UnityEngine.Object asset)
        {
            string pngPath = string.Concat(Application.dataPath.Replace("/Assets", "/"),
                AssetDatabase.GetAssetPath(asset));
            string etcToolPath = string.Concat(Application.dataPath.Replace("/Assets", ""), "/tools/etc_tool/");
            string etcBatPath = etcToolPath + "/etc.bat";

            string pngName = asset.name + "png";
            string pngFolderPath = Path.GetDirectoryName(pngPath);

            string outputPath = pngFolderPath + "/etc";

            string pkmName = pngName.Replace(".png", ".pkm");
            string pkmPath = outputPath + "/" + pkmName;

            string alphaPkmName = pngName.Replace(".png", "_alpha.pkm");
            string alphaPkmPath = outputPath + "/" + alphaPkmName;

            string speed = "fast";

            string args = string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\" {4} {5} \"{6}\" {7}", pngPath, outputPath,
                pkmPath, alphaPkmPath, pkmName, alphaPkmName, etcToolPath, speed);
            ExecuteProcess(etcBatPath, args);
        }
C,增加编辑器菜单选择要处理的图片

        [MenuItem("Assets/Compress png 2 etc", false, 10001)]
        public static void CreateEtc()
        {
            string path;
            UnityEngine.Object matAsset;
            UnityEngine.Object[] selectedAssets = Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);
            foreach (Object asset in selectedAssets)
            {
                path = AssetDatabase.GetAssetPath(asset);
                matAsset = AssetDatabase.LoadAssetAtPath(path.Replace(".png", ".mat"), typeof (Material)) as Material;
                if (matAsset != null)
                {
                    CompressPngToEtc(asset);
                }
            }
        }


        [MenuItem("Assets/Compress png 2 etc", true, 10001)]
        public static bool CreateEtcEnabled()
        {
            for (int i = 0; i < Selection.objects.Length; i++)
            {
                var obj = Selection.objects[i];
                var filePath = AssetDatabase.GetAssetPath(obj);
                if (filePath.EndsWith(".png", System.StringComparison.CurrentCultureIgnoreCase) ||
                    filePath.EndsWith(".jpg", System.StringComparison.CurrentCultureIgnoreCase))
                {
                    return true;
                }
            }
            return false;
        }
D,生成rgb图片以及alpha图片后设置图片格式
public static void SetTextureType(string path, TextureImporterFormat format, FilterMode mode = FilterMode.Bilinear)
        {
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                importer.textureType = TextureImporterType.Sprite;
                importer.textureFormat = format;
                importer.filterMode = mode;
                importer.mipmapEnabled = false;
                
                TextureImporterSettings tis = new TextureImporterSettings();
                importer.ReadTextureSettings(tis);
                importer.SetTextureSettings(tis);
                AssetDatabase.ImportAsset(path);
            }
        }


public static void SetTextureTypeCompressed(object pngAsset)
        {
	    Texture2D mainTexture = AssetDatabase.LoadAssetAtPath(pngPath.Replace(pngAsset.name, "etc/" + pngAsset.name), typeof (Texture2D)) as Texture2D;
            Texture2D alphaTexture = AssetDatabase.LoadAssetAtPath(pngPath.Replace(pngAsset.name, "etc/" + pngAsset.name + "_alpha"), typeof (Texture2D)) as Texture2D;
            string mainPath = AssetDatabase.GetAssetPath(mainTexture);
            string alphaPath = AssetDatabase.GetAssetPath(alphaTexture);
            SetTextureType(mainPath, TextureImporterFormat.AutomaticCompressed);
            SetTextureType(alphaPath, TextureImporterFormat.AutomaticCompressed);
        }



E,设置材质球Shader为UIETC,并引用两张生成的图片

public static void SetMaterialEtcShader(UnityEngine.Object asset)
        {
            string path;
            Material mat;
            Texture2D mainTexture;
            Texture2D alphaTexture;

            path = AssetDatabase.GetAssetPath(asset);
            mat = asset as Material;
            if (mat == null)
            {
                return;
            }
            mat.shader = Shader.Find("Mogo/UIETC");
            mainTexture = AssetDatabase.LoadAssetAtPath(path.Replace(asset.name + ".mat", "etc/" + asset.name + ".png"), typeof(Texture2D)) as Texture2D;
            mat.mainTexture = mainTexture;
            alphaTexture = AssetDatabase.LoadAssetAtPath(path.Replace(asset.name + ".mat", "etc/" + asset.name + "_alpha.png"), typeof(Texture2D)) as Texture2D;
            mat.SetTexture("_AlphaTex", alphaTexture);
        }

4,运行效果


你可能感兴趣的:(Ngui,ETC1,Alpha)