您的位置:首页 > 其它

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

2017-12-13 23:28 197 查看
尊重原创,转载请在文首注明出处: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.n
4000
ame + "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,运行效果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: