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. 关于video.js

    网址:http://www.cnblogs.com/webenh/p/5815741.html

  2. Python 线程,进程

    Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元 线程不能实现多并发 只能实现伪并发 每次工作 只能是一个线程完成 由于python解释器 原生是c  原生线程 底层都会有一把 ...

  3. ubuntu 安装LNMP

    How To Install Linux, nginx, MySQL, PHP (LEMP) stack on Ubuntu 12.04 PostedJune 13, 2012 802.8kviews ...

  4. CSS样式 初学

    CSS样式 参考网站: CSS用法:3种 一:直接样式表 如<p style="color:red;">这是一个段落</p> 二:内部样式表 如:<s ...

  5. Spring Boot 系列教程17-Cache-缓存

    缓存 缓存就是数据交换的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找.由于缓存的运行速度比内存快得多,故缓存的作用就是帮 ...

  6. linux ubuntu平台下安装Scrapy

    1.安装Python sudo apt-get install python2.7 python2.7-dev 2.安装pip 下载get-pip.py 选中该文件所在路径,执行下面的命令 sudo ...

  7. iOS8.0以后的相册

    在 iOS 8.0 后, 使用the Photos framework 代替 the Assets Library framework , The Photos framework 提供更特色和更好的 ...

  8. Android摄像头:只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整(原理:底层SurfaceView+上层绘制ImageView)

    Android摄像头:只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整实现(原理:底层SurfaceView+上层绘制ImageView) 分类: Android开发 Androi ...

  9. 使用U盘在Mac机上装win8.1系统

    1.首先要准备一个8G的U盘,用苹果机格式化为FAT格式.注意:U盘格式化之前要对U盘里的文件备份,U盘格式化后,里边的内容会清空. 2.下载原版win8.1系统,不要下载ghost版,http:// ...

  10. 转:通过ant来批量执行jmeter脚本,并生成报告(附: 生成报告时报“Content is not allowed in prolog”这个错误的解决方案)

    最近在使用jmeter写脚本来进行测试,最终写了很多份脚本,然后,就在想,这么多脚本,我不可能一个一个的手动去点啊,有没有什么办法来批量运行Jmeter脚本呢? 这个时候,自然而然地想到了万能的ant ...