分离图片alpha通道

 

#if UNITY_EDITOR

using System;
using System.IO;
using UnityEditor;
using UnityEngine;

public class TextureAlphaExport : MonoBehaviour
{
    [MenuItem("MyTool/Texture/分离Alpha通道-UI文件夹")]
    private static void MenuItemClick()
    {
        Material exportAlphaMat = AssetDatabase.LoadAssetAtPath<Material>("Assets/Texture/ExportAlpha.mat");
        if (null == exportAlphaMat)
        {
            Debug.LogError($"mat load fail");
            return;
        }

        var files = Directory.GetFiles("Assets/UI/", "*.*", SearchOption.AllDirectories);
        foreach (var filePath in files)
        {
            ExportAlpha(exportAlphaMat, filePath);
        }

        Debug.Log("finish");
    }

    private static void ExportAlpha(Material mat, string filePath)
    {
        var srcTexFileExt = Path.GetExtension(filePath);
        switch (srcTexFileExt.ToLower())
        {
        case ".png":
        case ".jpg":
        case ".jpeg":
            break;
        default:
            return;
        }

        var srcTexFileNameNoExt = Path.GetFileNameWithoutExtension(filePath);
        if (srcTexFileNameNoExt.EndsWith("_rgb", StringComparison.OrdinalIgnoreCase)
            || srcTexFileNameNoExt.EndsWith("_alpha", StringComparison.OrdinalIgnoreCase))
        {
            return;
        }

        var srcTex = AssetDatabase.LoadAssetAtPath<Texture2D>(filePath);
        if (null == srcTex)
        {
            Debug.LogError($"Texture2D load fail: {filePath}");
            return;
        }

        var srcTempRT = RenderTexture.GetTemporary(srcTex.width, srcTex.height);
        {
            var srcTexDirPath = Path.GetDirectoryName(filePath);

            var oldActiveRT = RenderTexture.active;
            RenderTexture.active = srcTempRT;

            Graphics.Blit(srcTex, srcTempRT, mat, 0); //rgb部分写到RT上
            Texture2D rgbTex = new Texture2D(srcTex.width, srcTex.height, TextureFormat.RGB24, false);
            var rgbFilePath = $"{srcTexDirPath}{Path.DirectorySeparatorChar}{srcTexFileNameNoExt}_rgb{srcTexFileExt}";
            RenderRTToTextureAndWriteOut(rgbTex, rgbFilePath);
            //Debug.Log($"write rgb file: {rgbFilePath}");
            var rgbTexImporter = (TextureImporter)AssetImporter.GetAtPath(rgbFilePath);
            rgbTexImporter.SaveAndReimport();

            Graphics.Blit(srcTex, srcTempRT, mat, 1); //alpha部分写到RT上
            //Texture2D alphaTex = new Texture2D(srcTex.width, srcTex.height, TextureFormat.Alpha8, false); //用Alpha8就只能把Format设为Alpha8
            Texture2D alphaTex = new Texture2D(srcTex.width, srcTex.height, TextureFormat.RGBA32, false); //这里alpha也要写出, 不要用TextureFormat.RGBA24, 否则Format使用Alpha 8时会变成纯白色
            var alphaFilePath = $"{srcTexDirPath}{Path.DirectorySeparatorChar}{srcTexFileNameNoExt}_alpha{srcTexFileExt}";
            RenderRTToTextureAndWriteOut(alphaTex, alphaFilePath);
            //Debug.Log($"write alpha file: {alphaFilePath}");
            var alphaTexImporter = (TextureImporter)AssetImporter.GetAtPath(alphaFilePath);
            alphaTexImporter.SaveAndReimport();

            RenderTexture.active = oldActiveRT;
        }
        RenderTexture.ReleaseTemporary(srcTempRT);
    }

    private static void RenderRTToTextureAndWriteOut(Texture2D tex, string outTexFilePath)
    {
        tex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
        tex.Apply();
        var texBytes = tex.EncodeToPNG();
        File.WriteAllBytes(outTexFilePath, texBytes);

        AssetDatabase.ImportAsset(outTexFilePath);
    }

}

#endif

用到的shader

Shader "My/Texture/ExportAlpha"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
    }

    SubShader
    {
        CGINCLUDE

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
        };

        sampler2D _MainTex;
        float4 _MainTex_ST;

        v2f vert(appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.uv = TRANSFORM_TEX(v.uv, _MainTex);
            return o;
        }

        fixed4 frag_rgb(v2f i) : SV_Target
        {
            fixed4 c = tex2D(_MainTex, i.uv);
            //c.a = 1;
            return c;
        }

        fixed4 frag_alpha(v2f i) : SV_Target
        {
            fixed4 c = tex2D(_MainTex, i.uv);
            return fixed4(c.a, c.a, c.a, c.a);
        }

        ENDCG


        Tags
        {
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
        }

        Cull Off
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            NAME "RGB"

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag_rgb

            ENDCG
        }

        Pass
        {
            NAME "Alpha"

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag_alpha

            ENDCG
        }

    }

    //FallBack "Diffuse"
}

 

 

posted @ 2023-03-17 23:57  yanghui01  阅读(64)  评论(0编辑  收藏  举报