unity中, 将图集的 alpha 通道剥离出来可减少包体大小和内存使用大小。

方法是将原来的一张 rgba 图分成一张 rgb 和一张 alpha 图,android上rgb和alpha图均采用etc压缩格式,ios上采用pvrtc格式。其中alpha通道信息可以存在r中。

分享 alpha 通道工具的源代码如下:

 using System;
using System.IO;
using UnityEditor;
using UnityEngine; public static class TextureAlphaSpliter
{
const string
RGBEndName = "(rgb)",
AlphaEndName = "(a)"; public static bool WhetherSplit = true;
public static bool AlphaHalfSize; static Texture s_rgba; public static void SplitAlpha(Texture src, bool alphaHalfSize, out Texture rgb, out Texture alpha)
{
if (src == null)
throw new ArgumentNullException("src"); // make it readable
string srcAssetPath = AssetDatabase.GetAssetPath(src);
var importer = (TextureImporter)AssetImporter.GetAtPath(srcAssetPath);
{
importer.isReadable = true;
importer.SetPlatformTextureSettings("Standalone", , TextureImporterFormat.ARGB32, , true);
importer.SetPlatformTextureSettings("Android", , TextureImporterFormat.ARGB32, , true);
importer.SetPlatformTextureSettings("iPhone", , TextureImporterFormat.ARGB32, , true);
}
AssetDatabase.ImportAsset(srcAssetPath); alpha = CreateAlphaTexture((Texture2D)src, alphaHalfSize);
rgb = CreateRGBTexture(src);
} static Texture CreateRGBTexture(Texture src)
{
if (src == null)
throw new ArgumentNullException("src"); string srcPath = AssetDatabase.GetAssetPath(src);
string rgbPath = GetPath(src, RGBEndName);
int size = Mathf.Max(src.width, src.height, ); AssetDatabase.DeleteAsset(rgbPath);
AssetDatabase.CopyAsset(srcPath, rgbPath);
AssetDatabase.ImportAsset(rgbPath); SetSettings(rgbPath, size, TextureImporterFormat.ETC_RGB4, TextureImporterFormat.PVRTC_RGB4); return (Texture)AssetDatabase.LoadAssetAtPath(rgbPath, typeof(Texture));
} static Texture CreateAlphaTexture(Texture2D src, bool alphaHalfSize)
{
if (src == null)
throw new ArgumentNullException("src"); // create texture
var srcPixels = src.GetPixels();
var tarPixels = new Color[srcPixels.Length];
for (int i = ; i < srcPixels.Length; i++)
{
float r = srcPixels[i].a;
tarPixels[i] = new Color(r, r, r);
} Texture2D alphaTex = new Texture2D(src.width, src.height, TextureFormat.ARGB32, false);
alphaTex.SetPixels(tarPixels);
alphaTex.Apply(); // save
string saveAssetPath = GetPath(src, AlphaEndName);
string fullPath = BuildingAssetBundle.GetFullPath(saveAssetPath);
var bytes = alphaTex.EncodeToPNG();
File.WriteAllBytes(fullPath, bytes); AssetDatabase.SaveAssets();
AssetDatabase.Refresh(); // setting
int size = alphaHalfSize ? Mathf.Max(src.width / , src.height / , ) : Mathf.Max(src.width, src.height, );
SetSettings(saveAssetPath, size, TextureImporterFormat.ETC_RGB4, TextureImporterFormat.PVRTC_RGB4); return (Texture)AssetDatabase.LoadAssetAtPath(saveAssetPath, typeof(Texture));
} static void SetSettings(string assetPath, int maxSize, TextureImporterFormat androidFormat, TextureImporterFormat iosFormat)
{
var importer = (TextureImporter)AssetImporter.GetAtPath(assetPath);
{
importer.npotScale = TextureImporterNPOTScale.ToNearest;
importer.isReadable = false;
importer.mipmapEnabled = false;
importer.alphaIsTransparency = false;
importer.wrapMode = TextureWrapMode.Clamp;
importer.filterMode = FilterMode.Bilinear;
importer.anisoLevel = ;
importer.SetPlatformTextureSettings("Android", maxSize, androidFormat, , true);
importer.SetPlatformTextureSettings("iPhone", maxSize, iosFormat, , true);
importer.SetPlatformTextureSettings("Standalone", maxSize, TextureImporterFormat.ARGB32, , true);
}
AssetDatabase.ImportAsset(assetPath);
} static string GetPath(Texture src, string endName)
{
if (src == null)
throw new ArgumentNullException("src"); string srcAssetPath = AssetDatabase.GetAssetPath(src);
if (string.IsNullOrEmpty(srcAssetPath))
return null; string dirPath = Path.GetDirectoryName(srcAssetPath);
string ext = Path.GetExtension(srcAssetPath);
string fileName = Path.GetFileNameWithoutExtension(srcAssetPath); if (fileName.EndsWith(RGBEndName))
fileName = fileName.Substring(, fileName.Length - RGBEndName.Length); if (fileName.EndsWith(AlphaEndName))
fileName = fileName.Substring(, fileName.Length - AlphaEndName.Length); return string.Format("{0}/{1}{2}{3}", dirPath, fileName, endName ?? "", ext);
} public static Texture GetRGBA(Texture src)
{
if (src != null && (s_rgba == null || s_rgba.name != src.name))
{
string path = GetPath(src, "");
if (!string.IsNullOrEmpty(path))
s_rgba = AssetDatabase.LoadAssetAtPath(path, typeof(Texture)) as Texture;
} return s_rgba;
}
}

SplitAlpha

然后改造一下 shader,以ngui的shader为例。

原来要用一张 rgba 图的地方,现在改成用两张图,一张 rgb 和一张 alpha,改造为下:

Shader "Custom/Alpha Splited Colored"
{
Properties
{
_MainTex ("RGB", 2D) = "black" {}
_AlphaTex ("Alpha", 2D) = "black" {}
} SubShader
{
LOD Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
} Pass
{
Cull Off
Lighting Off
ZWrite Off
Fog { Mode Off }
Offset -, -
Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM
#pragma vertex vert
#pragma fragment frag sampler2D _MainTex;
sampler2D _AlphaTex; struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
}; struct v2f
{
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
fixed4 color : COLOR;
}; v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = v.texcoord;
o.color = v.color;
return o;
} fixed4 frag (v2f IN) : COLOR
{
// [dev]
fixed4 col;
col.rgb = tex2D(_MainTex, IN.texcoord).rgb;
col.a = tex2D(_AlphaTex, IN.texcoord).r; if (IN.color.r < 0.001 && IN.color.g < 0.001 && IN.color.b < 0.001)
{
float grey = dot(col.rgb, float3(0.299, 0.587, 0.114));
col.rgb = float3(grey, grey, grey);
}
else
col = col * IN.color; return col;
}
ENDCG
}
} SubShader
{
LOD Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
} Pass
{
Cull Off
Lighting Off
ZWrite Off
Fog { Mode Off }
Offset -, -
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
ColorMaterial AmbientAndDiffuse SetTexture [_MainTex]
{
Combine Texture * Primary
} SetTexture [_AlphaTex]
{
Combine previous, texture * primary
}
}
}
}

shader

转载请注明出处:http://www.cnblogs.com/jietian331/p/5167422.html

Unity3d之剥离alpha通道的更多相关文章

  1. 什么是Alpha通道?

    图像处理(Alpha通道,RGB,...)祁连山(Adobe 系列教程)****的UI课程 一个也许很傻的问题,在图像处理中alpha到底是什么?  Alpha通道是计算机图形学中的术语,指的是特别的 ...

  2. 如何基于纯GDI实现alpha通道的矢量和文字绘制

    今天有人在QQ群里问GDI能不能支持带alpha通道的线条绘制? 大家的答案当然是否定的,很多人推荐用GDI+. 一个基本的图形引擎要包括几个方面的支持:位图绘制,文字绘制,矢量绘制(如矩形,线条). ...

  3. [ActionScript 3.0] AS3.0 将图像的Alpha通道转换为黑白图像(分离ARGB方式)

    import flash.display.BitmapData; import flash.display.Bitmap; /** * 将图像的Alpha通道转换为黑白图像(分离ARGB方式) */ ...

  4. [ActionScript 3.0] AS3.0将图像的Alpha通道转换为黑白图像(复制通道方式)

    import flash.display.BitmapData; /** * 将图像的Alpha通道转换为黑白图像 */ var p:Point = new Point(0,0); var bmpd: ...

  5. ImagXpress中如何修改Alpha通道方法汇总

    ImagXpress支持处理Alpha通道信息来管理图像的透明度,Alpha通道支持PNG ,TARGA和TIFF文件,同时还支持BMP和ICO文件.如果说保存的图像样式不支持Alpha通道,就将会丢 ...

  6. RGBa颜色 css3的Alpha通道支持

    CSS3中,RGBa 为颜色声明添加Alpha通道. RGB值被指定使用3个8位无符号整数(0 – 255)并分别代表红色.蓝色.和绿色.增加的一个alpha通道并不是一个颜色通道——它只是用来指定除 ...

  7. ImageList半透明,Alpha通道bug处理。

    由于ImageList的先天障碍,对alpha通道支持不好.虽然到xp有所改善,但瑕疵依然存在. 通过reflactor发现ImageList通过windows api来进行读写的.写入数据时会对原始 ...

  8. 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题

    #include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...

  9. 关于Opengl中将24位BMP图片加入一个alpha通道并实现透明的问题

    #include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...

随机推荐

  1. 安卓之PreferenceActivity分享

    PerferenceActivity是什么,看下面的截图: Android的系统截图 乐手设置截图 好了,我们看到Android系统本身就大量用到了PreferenceActivity来对系统进行信息 ...

  2. 最大独立集 HDU 1068

    题目大意:有n个人,两个人之间有相互的关系,问最大的关系数目. 思路:n-(最大匹配数/2).因为这里给出的是n个人之间的两两关系 //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心 ...

  3. 最大边和最小边之差最小的生成树 UVA 1394

    题目大意:给你n个点的图,求苗条度(最大边减最小编)尽量小的生成树 思路:sort以后暴力枚举区间即可 //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #inclu ...

  4. headless

    http://www.oschina.net/translate/using-headless-mode-in-java-se

  5. php的错误和异常处理

    php中try catch的例子: <?php try { if (@mysql_connect('localhost','root','123456')){ // echo 'success! ...

  6. 【stack】模拟网页浏览 poj 1028

    #include<stdio.h> #include<string.h> int main() { ][]; ]; int i,depth; strcpy(s[]," ...

  7. MFC 透明内存DC

    在MFC中绘制比较复杂图形,通常采用双缓冲技术来绘图,的确可以大大加快绘制速度和减少闪烁,但是有些情况也不尽然. 我最近遇到了一个问题,采用的也是双缓冲来加快绘图,但是绘制效果还是不尽人意.A对象里大 ...

  8. C语言版的16进制与字符串互转函数

    http://www.cnblogs.com/nio-nio/p/3309367.html /* // C prototype : void StrToHex(BYTE *pbDest, BYTE * ...

  9. 线程访问 DevExpress控件异常时 解决方法

    Control.CheckForIllegalCrossThreadCalls = false; DevExpress.Data.CurrencyDataController.DisableThrea ...

  10. PAT (Advanced Level) 1108. Finding Average (20)

    简单模拟. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #i ...