这个方法已经有很多人写过很多变了,方法基本都是一样的,这里仅仅是做个记录。
Android平台使用ETC1格式压缩。
目前主流的Android机型基本都支持ETC1格式压缩。但ETC1只能支持非Alpha通道的图片压缩。
所以一般把RGB和ALPHA分离出来,r值,g值,b值从RGB图获取,a值从Alpha图里获取。就算两张ETC1贴图加起来也不及原贴图的1/4。而且加载速度也快了很多。
随着OPENGL ES 3.0的发布,etc2也出了,支持Alpha通道,但就目前的市场,支持的机型还比较少,所以可以不用考虑。
IOS平台使用PVRT压缩纹理,它支持Alpha通道。
下面这张别人家的图是几种贴图的加载耗时对比
然后直接代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
public class SeparateNGUITextureRGBAndAlphaChannel {
static string texturePath = "/Texture";
static string materialPath = "/Texture";
static Dictionary<string, int[]> generatedTextures = new Dictionary<string, int[]> ();
[MenuItem("Tools/拆分Texture为RGBTexture和AlphaTexture")]
static void SeparateTexturesRGBAndAlphaChannel()
{
Debug.Log ("----------------- start: separate textures to rgb texture and alpha texture ------------------");
string[] paths = Directory.GetFiles (Application.dataPath + texturePath, "*.*", SearchOption.AllDirectories);
foreach(string path in paths)
{
if (!string.IsNullOrEmpty(path) && IsTextureFile (path) && !IsAlreadySeparated(path) && !IsMetaFile(path))
{
SeparateTextureRGBAndAlphaChannel (path);
}
}
AssetDatabase.Refresh ();
ReimportGeneratedTextures ();
Debug.Log ("----------------- finish: separate textures to rgb texture and alpha texture ------------------");
}
[MenuItem("Tools/替换NGUI图集Material的Shader为支持ETC1的Shader,并替换贴图")]
static void ReplaceShadersForECT1Textures()
{
Debug.Log ("----------------- start: replace shader for ETC1 texture ------------------");
string[] paths = Directory.GetFiles (Application.dataPath + materialPath, "*.mat", SearchOption.AllDirectories);
foreach(string path in paths)
{
string relativePath = GetRelativePath (path);
ReplaceShaderForETC1Texture (relativePath);
}
Debug.Log ("----------------- finish: replace shader for ETC1 texture ------------------");
}
static void SeparateTextureRGBAndAlphaChannel(string path)
{
string relativePath = GetRelativePath (path);
SetTextureReadable (relativePath);
Texture2D originalTex = (Texture2D)AssetDatabase.LoadAssetAtPath (relativePath, typeof(Texture2D));
if (originalTex == null)
{
Debug.Log ("not found texture, path is " + relativePath);
return;
}
if (!IsHaveAlphaChannel (originalTex))
{
Debug.Log ("not found texture alpha channel, texture path is " + relativePath);
return;
}
Color[] colors = originalTex.GetPixels ();
Texture2D rgbTex = new Texture2D (originalTex.width, originalTex.height, TextureFormat.RGB24, false);
rgbTex.SetPixels (colors);
rgbTex.Apply ();
byte[] bytes = rgbTex.EncodeToPNG ();
string rgbPath = GetRGBTexturePath (relativePath);
File.WriteAllBytes (rgbPath, bytes);
AddToReimportList (rgbPath, originalTex.width, originalTex.height);
Texture2D alphaTex = new Texture2D (originalTex.width, originalTex.height, TextureFormat.RGB24, false);
Color[] alphaColors = new Color[colors.Length];
for(int i = 0; i < colors.Length; i++)
{
alphaColors [i].r = colors [i].a;
alphaColors [i].g = colors [i].a;
alphaColors [i].b = colors [i].a;
}
alphaTex.SetPixels (alphaColors);
bytes = alphaTex.EncodeToPNG ();
string alphaPath = GetAlphaTextureP