分离图片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" }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端