美文网首页
alpha 通道分离

alpha 通道分离

作者: UnityAsk | 来源:发表于2017-02-07 16:28 被阅读33次
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
     }
}
}  

相关文章

网友评论

      本文标题:alpha 通道分离

      本文链接:https://www.haomeiwen.com/subject/zwhmittx.html