欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-06 15:57:56
...

尊重原创,转载请在文首注明出处: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纹理压缩自动化脚本ETC1+Alpha纹理压缩自动化脚本


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,运行效果


相关标签: ETC1 Alpha