当前位置:   article > 正文

Unity工程里图片的RGB和Alpha通道的分离,以及显示所有带有Alpha通道贴图的Material_unity3d rgb通道如果查看

unity3d rgb通道如果查看

背景:ETC1图片格式的罪孽,不支持Alpha通道。于是程序员们将一些气力浪费在Alpha通道的处理上。 为了能使用ETC1,同时某些透明效果必须有Alpha通道,一般的处理方式是将RGB和Alpha分为两张图片分别储存。 只存Alpha通道的图片及RGB都为要存的Alpha值,因为熵比较小,图片尺寸也可以相应减小一些。

要做的工作:

1. 将带有Alpha通道的图片,另存为两张图片,一张只存RGB信息,另一张只存Alpha信息。建议保持为图片原目录,名称加后缀“_RGB”, "_Alpha"。

2. 带有Alpha通道的图片,所用的Shader要更新为支持RGB和Alpha信息分别从两张不同图片读取的shader。这个功能,因为不能的Material的Shader会很不一样,因此,不用程序来强硬指定了。但程序起码需要给出提示,工程中哪些Material用到了哪些带有Alpha通道的图片。

不罗嗦了,直接上代码。

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEditor;
  5. using System.IO;
  6. using System.Reflection;
  7. public class MaterialTextureForETC1{
  8. public static float sizeScale = 0.5f; //the size decrease scale for alphaTexture
  9. public static Dictionary<string, bool> texturesAlphaDic = new Dictionary<string, bool>();
  10. [MenuItem("EffortForETC1/Seperate RGB and Alpha Channel for All Textures")]
  11. static void SeperateAllTexturesRGBandAlphaChannel()
  12. {
  13. string[] paths = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories);
  14. foreach (string path in paths)
  15. {
  16. if (!string.IsNullOrEmpty(path) && IsTextureFile(path)) //full name
  17. {
  18. SeperateRGBAandlphaChannel(path);
  19. }
  20. }
  21. }
  22. [MenuItem("EffortForETC1/Show Materials Having Textures with Alpha Chanel")]
  23. static void ShowMaterialsHavingTextureswithAlphaChanel()
  24. {
  25. CalculateTexturesAlphaChannelDic();
  26. string[] matpaths = Directory.GetFiles(Application.dataPath, "*.mat", SearchOption.AllDirectories);
  27. foreach (string matpath in matpaths)
  28. {
  29. string propermatpath = GetRelativeAssetPath(matpath);
  30. Material mat = (Material)Resources.LoadAssetAtPath(propermatpath, typeof(Material));
  31. if (mat)
  32. {
  33. string[] alphatexpaths = GetMaterialTexturesHavingAlphaChannel(mat);
  34. if (alphatexpaths.Length == 0)
  35. {
  36. continue;
  37. }
  38. Debug.Log("Material having texture(s) with Alpha channel : " + propermatpath);
  39. foreach (string alphatexpath in alphatexpaths)
  40. {
  41. Debug.Log(alphatexpath + " in " + propermatpath);
  42. }
  43. }
  44. else
  45. {
  46. Debug.LogError("Load material failed : " + matpath);
  47. }
  48. }
  49. Debug.Log("Finish!");
  50. }
  51. #region inspect material
  52. static string[] GetMaterialTexturesHavingAlphaChannel(Material _mat)
  53. {
  54. List<string> alphatexpaths = new List<string>();
  55. string[] texpaths = GetMaterialTexturePaths(_mat);
  56. foreach (string texpath in texpaths)
  57. {
  58. if (texturesAlphaDic[texpath])
  59. {
  60. alphatexpaths.Add(texpath);
  61. }
  62. }
  63. return alphatexpaths.ToArray();
  64. }
  65. static string[] GetMaterialTexturePaths(Material _mat)
  66. {
  67. List<string> results = new List<string>();
  68. Object[] roots = new Object[] { _mat };
  69. Object[] dependObjs = EditorUtility.CollectDependencies(roots);
  70. foreach (Object dependObj in dependObjs)
  71. {
  72. if (dependObj.GetType() == typeof(Texture2D))
  73. {
  74. string texpath = AssetDatabase.GetAssetPath(dependObj.GetInstanceID());
  75. results.Add(texpath);
  76. }
  77. }
  78. return results.ToArray();
  79. }
  80. #endregion
  81. static void CalculateTexturesAlphaChannelDic()
  82. {
  83. string[] paths = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories);
  84. foreach (string path in paths)
  85. {
  86. if (!string.IsNullOrEmpty(path) && IsTextureFile(path)) //full name
  87. {
  88. string assetRelativePath = GetRelativeAssetPath(path);
  89. SetTextureReadable(assetRelativePath);
  90. Texture2D sourcetex = Resources.LoadAssetAtPath(assetRelativePath, typeof(Texture2D)) as Texture2D;
  91. if (!sourcetex) //make sure the file is really Texture2D which can be loaded as Texture2D.
  92. {
  93. continue;
  94. }
  95. if (HasAlphaChannel(sourcetex))
  96. {
  97. AddValueToDic(assetRelativePath, true);
  98. }
  99. else
  100. {
  101. AddValueToDic(assetRelativePath, false);
  102. }
  103. }
  104. }
  105. }
  106. static void AddValueToDic(string _key, bool _val)
  107. {
  108. if (texturesAlphaDic.ContainsKey(_key))
  109. {
  110. texturesAlphaDic[_key] = _val;
  111. }
  112. else
  113. {
  114. texturesAlphaDic.Add(_key, _val);
  115. }
  116. }
  117. #region process texture
  118. static void SeperateRGBAandlphaChannel(string _texPath)
  119. {
  120. string assetRelativePath = GetRelativeAssetPath(_texPath);
  121. SetTextureReadable(assetRelativePath);
  122. Texture2D sourcetex = Resources.LoadAssetAtPath(assetRelativePath, typeof(Texture2D)) as Texture2D; //not just the textures under Resources file
  123. if (!sourcetex)
  124. {
  125. Debug.Log("Load Texture Failed : " + assetRelativePath);
  126. return;
  127. }
  128. if (!HasAlphaChannel(sourcetex))
  129. {
  130. Debug.Log("Texture does not have Alpha channel : " + assetRelativePath);
  131. return;
  132. }
  133. Texture2D rgbTex = new Texture2D(sourcetex.width, sourcetex.height, TextureFormat.RGB24, true);
  134. Texture2D alphaTex = new Texture2D((int)(sourcetex.width * sizeScale), (int)(sourcetex.height * sizeScale), TextureFormat.RGB24, true);
  135. for (int i = 0; i < sourcetex.width; ++i)
  136. for (int j = 0; j < sourcetex.height; ++j)
  137. {
  138. Color color = sourcetex.GetPixel(i, j);
  139. Color rgbColor = color;
  140. Color alphaColor = color;
  141. alphaColor.r = color.a;
  142. alphaColor.g = color.a;
  143. alphaColor.b = color.a;
  144. rgbTex.SetPixel(i, j, rgbColor);
  145. alphaTex.SetPixel((int)(i * sizeScale), (int)(j * sizeScale), alphaColor);
  146. }
  147. rgbTex.Apply();
  148. alphaTex.Apply();
  149. byte[] bytes = rgbTex.EncodeToPNG();
  150. File.WriteAllBytes(GetRGBTexPath(_texPath), bytes);
  151. bytes = alphaTex.EncodeToPNG();
  152. File.WriteAllBytes(GetAlphaTexPath(_texPath), bytes);
  153. Debug.Log("Succeed to seperate RGB and Alpha channel for texture : " + assetRelativePath);
  154. }
  155. static bool HasAlphaChannel(Texture2D _tex)
  156. {
  157. for (int i = 0; i < _tex.width; ++i)
  158. for (int j = 0; j < _tex.height; ++j)
  159. {
  160. Color color = _tex.GetPixel(i, j);
  161. float alpha = color.a;
  162. if (alpha < 1.0f - 0.001f)
  163. {
  164. return true;
  165. }
  166. }
  167. return false;
  168. }
  169. static void SetTextureReadable(string _relativeAssetPath)
  170. {
  171. string postfix = GetFilePostfix(_relativeAssetPath);
  172. if (postfix == ".dds") // no need to set .dds file. Using TextureImporter to .dds file would get casting type error.
  173. {
  174. return;
  175. }
  176. TextureImporter ti = (TextureImporter)TextureImporter.GetAtPath(_relativeAssetPath);
  177. ti.isReadable = true;
  178. AssetDatabase.ImportAsset(_relativeAssetPath);
  179. }
  180. #endregion
  181. #region string or path helper
  182. static bool IsTextureFile(string _path)
  183. {
  184. string path = _path.ToLower();
  185. return path.EndsWith(".psd") || path.EndsWith(".tga") || path.EndsWith(".png") || path.EndsWith(".jpg") || path.EndsWith(".dds") || path.EndsWith(".bmp") || path.EndsWith(".tif") || path.EndsWith(".gif");
  186. }
  187. static string GetRGBTexPath(string _texPath)
  188. {
  189. return GetTexPath(_texPath, "_RGB.");
  190. }
  191. static string GetAlphaTexPath(string _texPath)
  192. {
  193. return GetTexPath(_texPath, "_Alpha.");
  194. }
  195. static string GetTexPath(string _texPath, string _texRole)
  196. {
  197. string result = _texPath.Replace(".", _texRole);
  198. string postfix = GetFilePostfix(_texPath);
  199. return result.Replace(postfix, ".png");
  200. }
  201. static string GetRelativeAssetPath(string _fullPath)
  202. {
  203. _fullPath = GetRightFormatPath(_fullPath);
  204. int idx = _fullPath.IndexOf("Assets");
  205. string assetRelativePath = _fullPath.Substring(idx);
  206. return assetRelativePath;
  207. }
  208. static string GetRightFormatPath(string _path)
  209. {
  210. return _path.Replace("\\", "/");
  211. }
  212. static string GetFilePostfix(string _filepath) //including '.' eg ".tga", ".dds"
  213. {
  214. string postfix = "";
  215. int idx = _filepath.LastIndexOf('.');
  216. if (idx > 0 && idx < _filepath.Length)
  217. postfix = _filepath.Substring(idx, _filepath.Length - idx);
  218. return postfix;
  219. }
  220. #endregion
  221. }


上面的代码中,图片的处理,用的是已经整合进Unity的有限的图片处理功能,分离RGB和Alpha通道的图片都被存为了.png格式。其实可以将C#的System.Drawing.dll导入到工程里,用C#原生的Bitmap类来处理图片。

.dds格式图片的处理比较特殊。一般用Texture2D.GetPixel()等函数处理Texture2D时,需要设置Texture的Import属性里的Readable,但.dds格式的图片不用处理。同时,Unity只支持Int格式的dds, float32格式的.dds不支持。


【改进版】Unity工程里图片的RGB和Alpha通道的分离

http://blog.csdn.net/u010153703/article/details/45502895







声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/126927?site
推荐阅读
相关标签
  

闽ICP备14008679号