最近研究了一下Texture2D.PackTextures方法。它可以在运行时或者编辑时对贴图进行合并。运行时它不支持任意贴图格式的合并,比如现在主流的ASTC,它会合并成RGBA32格式。而且无法指定贴图合并到大图具体某个位置上。
动态合并贴图的方法可以参考我之前的文章,这篇主要考虑静态合并,也就是编辑模式下合并
Unity3D研究院之运行时合并ETC1、ETC2、ASTC、DXT1、DXT5、PVRTC贴图
既然是编辑模式下合并,我们肯定不希望每张小贴图也需要标记read/write enable 那样就太麻烦了。如下代码所示,提供需要合并的小图,以及小图所在大图的偏移即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
using System; using System.IO; using UnityEditor; using UnityEngine; public class TextureCombine { [MenuItem("Tools/TextureCombine")] static void Combine() { Texture2D tex512 = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/512.jpg"); Texture2D tex128 = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/128.jpg"); Texture2D @out = Combine( new[] { tex512, tex128 }, //贴图 new[] { (0, 0), (600, 600) } //偏移 ,1024);//最终贴图大小 File.WriteAllBytes("Assets/out.jpg", @out.EncodeToJPG()); AssetDatabase.Refresh(); } static Texture2D Combine(Texture2D []texs, ValueTuple<int,int>[]offests,int size) { Texture2D @out = new Texture2D(size, size, TextureFormat.RGBA32, true); for (int i = 0; i < texs.Length; i++) { var tex = texs[i]; var offest = offests[i]; var width = tex.width; var height = tex.height; RenderTexture tmp = RenderTexture.GetTemporary(width,height,0,RenderTextureFormat.Default,RenderTextureReadWrite.Linear); Graphics.Blit(tex, tmp); RenderTexture previous = RenderTexture.active; RenderTexture.active = tmp; Texture2D @new = new Texture2D(width, height); @new.ReadPixels(new Rect(0, 0, width, height), 0, 0); @new.Apply(); @out.SetPixels(offest.Item1, offest.Item2, width, height, @new.GetPixels()); RenderTexture.active = previous; RenderTexture.ReleaseTemporary(tmp); } return @out; } } |
最后合并的结果
- 本文固定链接: https://www.xuanyusong.com/archives/4729
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!