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& ...
随机推荐
- Windows中安装jdk,出现javac不是内部或外部命令 也不是可运行的程序
在经过多次实验,终于解决了在dos窗口验证jdk是否安装成功的错误提示-----javac不是内部或外部命令 也不是可运行的程序 首先要明确的是 在新建 JAVA_HOME , CLASSPATH文件 ...
- 戏说云计算之PaaS,IaaS,SaaS【转载】
最近我们聊到“CRM系统PAAS化”,有些可能就不了解,到底什么是PAAS.云计算还有IaaS,SaaS概念,这三者之间有什么区别?今天智云通CRM系统小编用通俗易懂的例子跟大家分享Paas,IaaS ...
- android studio布局文件/XML怎么代码补全
android studio中的布局文件代码补全方式是打第一个字母就提示了,而java代码有时候要按快捷键. 布局文件的话呢,要写在标签开始处才提示,在标签闭合处有时候不提示,有时候在内容里也会有不提 ...
- 07-09 07:28:38.350: E/AndroidRuntime(1437): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.googleplay.ui.activity.MainActivity" on path: DexPathList[[zip file "/data/app/c
一运行,加载mainActivity就报错 布局文件乱写一通,然后急着运行,报莫名其妙的错误: 07-09 07:28:38.350: E/AndroidRuntime(1437): Caused b ...
- 关于WIFI DIRECT功能的
http://processors.wiki.ti.com/index.php/WiFi_Direct_Configuration_Scripts#p2p_find https://wire ...
- 一款值得推荐的shell工具
1. 一款比较出色的shell工具 熟练的运用shell语言可以提高我们的工作效率,而一款好的shell工具能提高学习的效率,fish shell就是这样一款工具.并且是一款跨平台的工具, 同时可以在 ...
- linux视频学习(简单介绍)20160405
看一周学会linux系统的学习笔记. 1.linux系统是一个安全性高的开源,免费的多用户多任务的操作系统. 2.linux工作分为linux系统管理员,linux程序员(PC上软件开发,嵌入式开发) ...
- oracle中的常用函数1-------decode方法
DECODE函数是ORACLE PL/SQL是功能强大的函数之一,目前还只有ORACLE公司的SQL提供了此函数,其他数据库厂商的SQL实现还没有此功能.DECODE有什么用途呢? 先构造一个例子,假 ...
- 学习笔记——建造者模式Builder
构造者模式.外部场景如果需要一个汽车类,它不需要关心如何构造,它只需要告诉Director需要什么,就可以从Director获得. 如:CDirector(IBuilder* aBuilder); 场 ...
- Maven常用插件配置和使用
主要介绍Maven的几个常见第三方插件(cobertura.findbugs.source.assembly.插件开发)配置和使用,接Maven介绍 maven本质上是一个插件框架,它的所有工作都交给 ...