Unity3d之剥离alpha通道
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通道的更多相关文章
- 什么是Alpha通道?
图像处理(Alpha通道,RGB,...)祁连山(Adobe 系列教程)****的UI课程 一个也许很傻的问题,在图像处理中alpha到底是什么? Alpha通道是计算机图形学中的术语,指的是特别的 ...
- 如何基于纯GDI实现alpha通道的矢量和文字绘制
今天有人在QQ群里问GDI能不能支持带alpha通道的线条绘制? 大家的答案当然是否定的,很多人推荐用GDI+. 一个基本的图形引擎要包括几个方面的支持:位图绘制,文字绘制,矢量绘制(如矩形,线条). ...
- [ActionScript 3.0] AS3.0 将图像的Alpha通道转换为黑白图像(分离ARGB方式)
import flash.display.BitmapData; import flash.display.Bitmap; /** * 将图像的Alpha通道转换为黑白图像(分离ARGB方式) */ ...
- [ActionScript 3.0] AS3.0将图像的Alpha通道转换为黑白图像(复制通道方式)
import flash.display.BitmapData; /** * 将图像的Alpha通道转换为黑白图像 */ var p:Point = new Point(0,0); var bmpd: ...
- ImagXpress中如何修改Alpha通道方法汇总
ImagXpress支持处理Alpha通道信息来管理图像的透明度,Alpha通道支持PNG ,TARGA和TIFF文件,同时还支持BMP和ICO文件.如果说保存的图像样式不支持Alpha通道,就将会丢 ...
- RGBa颜色 css3的Alpha通道支持
CSS3中,RGBa 为颜色声明添加Alpha通道. RGB值被指定使用3个8位无符号整数(0 – 255)并分别代表红色.蓝色.和绿色.增加的一个alpha通道并不是一个颜色通道——它只是用来指定除 ...
- ImageList半透明,Alpha通道bug处理。
由于ImageList的先天障碍,对alpha通道支持不好.虽然到xp有所改善,但瑕疵依然存在. 通过reflactor发现ImageList通过windows api来进行读写的.写入数据时会对原始 ...
- 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题
#include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...
- 关于Opengl中将24位BMP图片加入一个alpha通道并实现透明的问题
#include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...
随机推荐
- zend笔记
ZEND_STRL(str) 等价于 (str), (sizeof(str)-1) ZEND_STRS(str)等价于 (str), (sizeof(str))
- Rsync数据远程同步备份
rsync的使用方法 一.设置Rsync Server端 Rsync server需要设定四个方面: 1.规划建立备份目录区 2.设定: /etc/xinetd.d/rsync 3.设定: /etc/ ...
- HDU 5963 博弈
http://acm.hdu.edu.cn/showproblem.php?pid=5963 题目大意:中文题 思路:看ICPC camp好了,简单易懂:https://async.icpc-camp ...
- WebRequest 对象的使用
// 待请求的地址 string url = "http://www.cnblogs.com"; // 创建 WebRequest 对象,WebRequest 是抽象类,定义了请求 ...
- curl 测试web站点的响应时间
curl -s -w "\n"::%{time_namelookup}::%{time_connect}::%{time_starttransfer}::%{time_total} ...
- java应用测试报告生成(二):利用ant的build.xml生成测试报告
1.将写好的项目导出 在工程下会生成一个build.xml的蚂蚁图标的文件. 2.右击该文件,选择run as Ant build 其中的测试目录是可以选择的,如果涉及到顺序也可以调整顺序 3.执行后 ...
- linux视频学习(简单介绍)20160405
看一周学会linux系统的学习笔记. 1.linux系统是一个安全性高的开源,免费的多用户多任务的操作系统. 2.linux工作分为linux系统管理员,linux程序员(PC上软件开发,嵌入式开发) ...
- Notes over compiling..
When compiling VIM on windows, using nmake may be a better choice.. Because so far my attempts to co ...
- required 引发的小小思考
原创:转载请注明出处 首先,因为遇到问题如下: class MainTabBar: UITabBar { override init(frame: CGRect) { super.init(frame ...
- C语言客户端服务器代码
/* sockclnt.c*/ #include <stdio.h>#include <string.h>#include <stdlib.h>#include & ...