alpha 通道分离

using UnityEngine;  
using System.Collections;  
using System.Collections.Generic;  
using UnityEditor;  
using System.IO;  
using System.Reflection;  

public class MaterialTextureForETC1{  

public static float sizeScale =1f;   //the size decrease scale for alphaTexture  
public static Dictionary<string, bool> texturesAlphaDic = new Dictionary<string, bool>();  

[MenuItem("EffortForETC1/Seperate RGB and Alpha Channel for All Textures")]  
static void SeperateAllTexturesRGBandAlphaChannel()  
{  
    string[] paths = Directory.GetFiles(Application.dataPath+"/test", "*.*", SearchOption.AllDirectories);  
    foreach (string path in paths)  
    {  
        if (!string.IsNullOrEmpty(path) && IsTextureFile(path))   //full name  
        {  
            SeperateRGBAandlphaChannel(path);  
        }  
    }   
}  

[MenuItem("EffortForETC1/Show Materials Having Textures with Alpha Chanel")]  
static void ShowMaterialsHavingTextureswithAlphaChanel()  
{  
    CalculateTexturesAlphaChannelDic();  
    string[] matpaths = Directory.GetFiles(Application.dataPath, "*.mat", SearchOption.AllDirectories);  
    foreach (string matpath in matpaths)  
    {  
        string propermatpath = GetRelativeAssetPath(matpath);  
        Material mat = (Material)AssetDatabase.LoadAssetAtPath(propermatpath, typeof(Material));  
        if (mat)  
        {  
            string[] alphatexpaths = GetMaterialTexturesHavingAlphaChannel(mat);  
            if (alphatexpaths.Length == 0)  
            {  
                continue;  
            }  
            Debug.Log("Material having texture(s) with Alpha channel : " + propermatpath);  
            foreach (string alphatexpath in alphatexpaths)  
            {  
                Debug.Log(alphatexpath + " in " + propermatpath);  
            }  
        }  
        else  
        {  
            Debug.LogError("Load material failed : " + matpath);  
        }  
    }  
    Debug.Log("Finish!");       
}  


#region inspect material  

static string[] GetMaterialTexturesHavingAlphaChannel(Material _mat)  
{  
    List<string> alphatexpaths = new List<string>();  
    string[] texpaths = GetMaterialTexturePaths(_mat);  
    foreach (string texpath in texpaths)  
    {  
        if (texturesAlphaDic[texpath])  
        {  
            alphatexpaths.Add(texpath);  
        }  
    }  

    return alphatexpaths.ToArray();  
}  

static string[] GetMaterialTexturePaths(Material _mat)  
{  
    List<string> results = new List<string>();  
    Object[] roots = new Object[] { _mat };  
    Object[] dependObjs = EditorUtility.CollectDependencies(roots);  
    foreach (Object dependObj in dependObjs)  
    {  
        if (dependObj.GetType() == typeof(Texture2D))  
        {  
            string texpath = AssetDatabase.GetAssetPath(dependObj.GetInstanceID());  
            results.Add(texpath);  
        }  
    }  
    return results.ToArray();  
}  

#endregion  


static void CalculateTexturesAlphaChannelDic()  
{  
    string[] paths = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories);  
    foreach (string path in paths)  
    {  
        if (!string.IsNullOrEmpty(path) && IsTextureFile(path))   //full name  
        {  
            string assetRelativePath = GetRelativeAssetPath(path);  
            SetTextureReadable(assetRelativePath);  
            Texture2D sourcetex = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(Texture2D)) as Texture2D;    
            if (!sourcetex)  //make sure the file is really Texture2D which can be loaded as Texture2D.  
            {  
                continue;  
            }  
            if (HasAlphaChannel(sourcetex))  
            {  
                AddValueToDic(assetRelativePath, true);                                      
            }  
            else  
            {  
                AddValueToDic(assetRelativePath, false);    
            }  
        }  
    }   
}  

static void AddValueToDic(string _key, bool _val)  
{  
    if (texturesAlphaDic.ContainsKey(_key))  
    {  
        texturesAlphaDic[_key] = _val;  
    }  
    else  
    {  
        texturesAlphaDic.Add(_key, _val);  
    }  
}  


#region process texture  

static void SeperateRGBAandlphaChannel(string _texPath)  
{  
    string assetRelativePath = GetRelativeAssetPath(_texPath);  
    SetTextureReadable(assetRelativePath);  
    Texture2D sourcetex = AssetDatabase.LoadAssetAtPath(assetRelativePath, typeof(Texture2D)) as Texture2D;  //not just the textures under Resources file  
    if (!sourcetex)  
    {  
        Debug.Log("Load Texture Failed : " + assetRelativePath);  
        return;  
    }  
    if (!HasAlphaChannel(sourcetex))  
    {  
        Debug.Log("Texture does not have Alpha channel : " + assetRelativePath);  
        return;  
    }  

    Texture2D rgbTex = new Texture2D(sourcetex.width, sourcetex.height, TextureFormat.RGB24, true);  
    Texture2D alphaTex = new Texture2D((int)(sourcetex.width * sizeScale), (int)(sourcetex.height * sizeScale), TextureFormat.RGB24, true);  

    for (int i = 0; i < sourcetex.width; ++i)  
        for (int j = 0; j < sourcetex.height; ++j)  
        {  
            Color color = sourcetex.GetPixel(i, j);  
            Color rgbColor = color;  
            Color alphaColor = color;  
            alphaColor.r = color.a;  
            alphaColor.g = color.a;  
            alphaColor.b = color.a;  
            rgbTex.SetPixel(i, j, rgbColor);  
            alphaTex.SetPixel((int)(i * sizeScale), (int)(j * sizeScale), alphaColor);  
        }  

    rgbTex.Apply();  
    alphaTex.Apply();  

    byte[] bytes = rgbTex.EncodeToPNG();  
    File.WriteAllBytes(GetRGBTexPath(_texPath), bytes);  
    bytes = alphaTex.EncodeToPNG();  
    File.WriteAllBytes(GetAlphaTexPath(_texPath), bytes);  
    Debug.Log("Succeed to seperate RGB and Alpha channel for texture : " + assetRelativePath);  
}  

static bool HasAlphaChannel(Texture2D _tex)  
{  
    for (int i = 0; i < _tex.width; ++i)  
        for (int j = 0; j < _tex.height; ++j)  
        {  
            Color color = _tex.GetPixel(i, j);  
            float alpha = color.a;  
            if (alpha < 1.0f - 0.001f)  
            {  
                return true;  
            }  
        }  
    return false;  
}  

static void SetTextureReadable(string _relativeAssetPath)  
{  
    string postfix = GetFilePostfix(_relativeAssetPath);  
    if (postfix == ".dds")    // no need to set .dds file.  Using TextureImporter to .dds file would get casting type error.  
    {  
        return;  
    }  

    TextureImporter ti = (TextureImporter)TextureImporter.GetAtPath(_relativeAssetPath);  
    ti.isReadable = true;  
    AssetDatabase.ImportAsset(_relativeAssetPath);  
}  

#endregion  


#region string or path helper  

static bool IsTextureFile(string _path)  
{  
    string path = _path.ToLower();  
    return path.EndsWith(".psd") || path.EndsWith(".tga") || path.EndsWith(".png") || path.EndsWith(".jpg") || path.EndsWith(".dds") || path.EndsWith(".bmp") || path.EndsWith(".tif") || path.EndsWith(".gif");  
}  

static string GetRGBTexPath(string _texPath)  
{  
    return GetTexPath(_texPath, "_RGB.");  
}  

static string GetAlphaTexPath(string _texPath)  
{  
    return GetTexPath(_texPath, "_Alpha.");  
}  

static string GetTexPath(string _texPath, string _texRole)  
{  
    string result = _texPath.Replace(".", _texRole);  
    string postfix = GetFilePostfix(_texPath);  
    return result.Replace(postfix, ".png");  
}  

static string GetRelativeAssetPath(string _fullPath)  
{  
    _fullPath = GetRightFormatPath(_fullPath);  
    int idx = _fullPath.IndexOf("Assets");  
    string assetRelativePath = _fullPath.Substring(idx);  
    return assetRelativePath;  
}  

static string GetRightFormatPath(string _path)  
{  
    return _path.Replace("\\", "/");  
}  

static string GetFilePostfix(string _filepath)   //including '.' eg ".tga", ".dds"  
{  
    string postfix = "";  
    int idx = _filepath.LastIndexOf('.');  
    if (idx > 0 && idx < _filepath.Length)  
        postfix = _filepath.Substring(idx, _filepath.Length - idx);  
    return postfix;  
}  

#endregion     
}

shader

Shader "Custom/TextureETC" {
Properties 
{
     _MainTex ("Base (RGB)", 2D) = "white" { }
     _AlphaTex("AlphaTex",2D) = "white"{}
}
SubShader
{
     Tags
     {
        "Queue" = "Transparent+80"
     }
     Pass
     {
        Lighting Off
        ZTest Off
        Blend SrcAlpha OneMinusSrcAlpha
        Cull Off
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"

        sampler2D _MainTex;
        sampler2D _AlphaTex;

        float _AlphaFactor;
    
        struct v2f 
        {
            float4  pos : SV_POSITION;
            float2  uv : TEXCOORD0;
            float4 color :COLOR;
        };

        half4 _MainTex_ST;
        half4 _AlphaTex_ST;

        v2f vert (appdata_full v)
        {
            v2f o;
            o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
            o.uv =  v.texcoord;
            o.color = v.color;
            return o;
        }

        half4 frag (v2f i) : COLOR
        {
            half4 texcol = tex2D (_MainTex, i.uv);

            half4 result = texcol;

            result.a = tex2D(_AlphaTex,i.uv)*i.color.a ;

            return result;
        }
        ENDCG
     }
}
}  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容