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。可以看到输出了使用方法和例子。
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,运行效果
推荐阅读