参考链接:
http://blog.csdn.net/u010153703/article/details/45502895
http://blog.csdn.net/candycat1992/article/details/42127811
http://www.cnblogs.com/joeshifu/p/5489906.html
这是本篇文章的主角:
0.
贴图压缩:
Android平台使用ETC1格式压缩,但它不支持含Alpha通道的图片压缩。
所以一般把RGB和ALPHA分离出来,rgb值从RGB图获取,a值从Alpha图获取。
随着OPENGL ES 3.0的发布,ETC2也出了,支持Alpha通道,但就目前的市场,支持的机型还比较少,所以可以不用考虑。
IOS平台使用PVRTC格式压缩,它支持含Alpha通道的图片压缩。
贴图设置:
宽高为2的n次方
Read/Write Enabled不勾
Generate Mip Maps不勾
1.首先先理解一下Texture2D.GetPixels()这个方法,它会返回纹理中所有像素的颜色值,其中有一个参数是miplevel,通过调节下图中右上方那个滑动按钮即可看到不同miplevel下的样子。
miplevel为0时(默认),像素数目最多,最清晰:
miplevel为3时,有点像素风的感觉:
那么miplevel不同时,真正的差别究竟是什么呢,测试一下:
using UnityEngine;
using System.Collections;
public class TestTexture : MonoBehaviour {
//需要先将TextureType设置为Advanced,然后设置Read/Write Enabled为true
//如果图片宽高不为2的n次方,建议将NonPowerOf2设置为非None的选项,方便测试
public Texture2D texture2D;
private Color[] colors;
void Start ()
{
//api:public Color[] GetPixels(int miplevel = 0);
//以一张512x512的图为例,输出为:
//262144,262144,65536,16384
//结论:miplevel每增加1,则宽高同时除以2
colors = texture2D.GetPixels();
Debug.Log(colors.Length);
colors = texture2D.GetPixels(0);
Debug.Log(colors.Length);
colors = texture2D.GetPixels(1);
Debug.Log(colors.Length);
colors = texture2D.GetPixels(2);
Debug.Log(colors.Length);
}
}
miplevel的取值范围:以一张512x512的图为例(512,即2的9次方),那么取值就是0到9。
那么知道miplevel之后,再说一下Generate Mip Maps,下图分别是勾选和不勾选的区别。勾选后,会生成各种不同miplevel值的纹理,当纹理距离摄像机较远时,会自动使用先前生成的纹理,优点是减少运算量,缺点是增加内存占用;不勾选,则相反。
2.那么回到正题,使用脚本批量处理,分离通道:
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.IO;
/// <summary>
/// 选择文件夹或者选择单个多个图片,然后右键即可
/// </summary>
public class SeperateChannel {
private static List<string> allFiles;
private static bool mipmap = false;
[MenuItem("Assets/Seperate Channel")]
static void Seperate()
{
string path = GetFullPath(Selection.objects[0]);
allFiles = new List<string>();
//如果选择的是文件夹,就获取文件夹下的所有文件
//否则就获取选择的文件
if (!path.Contains(".")) GetAllFiles(path);
else GetAllFiles();
allFiles.RemoveAll((s) => { return s.Contains("meta"); });
string[] suffix = new string[] { ".psd", ".tga", ".png", ".jpg", ".bmp", ".tif", ".gif" };
string[] convert = new string[] { "_RGB", "_Alpha" };//经处理后的纹理会带有这些字样
for (int i = 0; i < allFiles.Count; i++)
{
bool needHandle = false;
//经过两个for循环筛选出要处理的纹理
for (int j = 0; j < suffix.Length; j++)
{
if (allFiles[i].EndsWith(suffix[j]))
{
needHandle = true;
break;
}
}
for (int j = 0; j < convert.Length; j++)
{
if (allFiles[i].Contains(convert[j]))
{
needHandle = false;
break;
}
}
if (!needHandle) continue;
Debug.Log(allFiles[i]);
allFiles[i] = GetAssetPath(allFiles[i]);
TextureImporter ti = TextureImporter.GetAtPath(allFiles[i]) as TextureImporter;
ti.isReadable = true;
Texture2D sourceTex = AssetDatabase.LoadAssetAtPath<Texture2D>(allFiles[i]);
Color[] sourceColor = sourceTex.GetPixels();
Texture2D rgbTex = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.RGB24, mipmap);
rgbTex.SetPixels(sourceColor);
WriteTexture(rgbTex, allFiles[i], true);
Texture2D alphaTex = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.RGB24, mipmap);
Color[] c = new Color[sourceColor.Length];
for (int j = 0; j < c.Length; j++)
{
c[j] = new Color(sourceColor[j].a, 0, 0);
}
alphaTex.SetPixels(c);
WriteTexture(alphaTex, allFiles[i], false);
}
AssetDatabase.Refresh();
Debug.Log("分离完毕");
}
//获取完整的路径(用于递归遍历)
public static string GetFullPath(Object assetObj)
{
string path = AssetDatabase.GetAssetPath(assetObj);
path = Application.dataPath + path;
path = path.Replace("AssetsAssets", "Assets");
return path;
}
//获取以Asset开头的路径
public static string GetAssetPath(string fullPath)
{
fullPath = fullPath.Substring(fullPath.IndexOf("Assets"));
return fullPath;
}
//获取选择的所有文件
public static void GetAllFiles()
{
for (int i = 0; i < Selection.objects.Length; i++)
{
string s = GetFullPath(Selection.objects[i]);
allFiles.Add(s);
}
}
//递归获取一个根目录下的所有文件
public static void GetAllFiles(string dir)
{
string[] files = Directory.GetFiles(dir);
foreach (var item in files)
{
allFiles.Add(item);
}
string[] dirs = Directory.GetDirectories(dir);
foreach (var item in dirs)
{
GetAllFiles(item);
}
}
//写入
public static void WriteTexture(Texture2D tex, string assetPath, bool rgb)
{
string path = Application.dataPath + assetPath;
path = path.Replace("AssetsAssets", "Assets");
string suffix = path.Substring(path.IndexOf("."));
if (rgb) path = path.Replace(suffix, "_RGB" + suffix);
else path = path.Replace(suffix, "_Alpha" + suffix);
Debug.Log(path);
tex.Apply();
byte[] bytes = tex.EncodeToPNG();
File.WriteAllBytes(path, bytes);
AssetDatabase.Refresh();
//重新导入
path = GetAssetPath(path);
TextureImporter ti = TextureImporter.GetAtPath(path) as TextureImporter;
ti.isReadable = false;
ti.textureFormat = TextureImporterFormat.AutomaticCompressed;
AssetDatabase.ImportAsset(path);
}
}