├── .gitignore ├── Editor.meta ├── Editor ├── TextureItem.cs ├── TextureItem.cs.meta ├── TexturePacker.asmdef ├── TexturePacker.asmdef.meta ├── TexturePackerStyles.cs ├── TexturePackerStyles.cs.meta ├── TexturePackerWindow.cs ├── TexturePackerWindow.cs.meta ├── TexturePreview.cs └── TexturePreview.cs.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── Resources.meta ├── Resources │ ├── TexturePacker.shader │ └── TexturePacker.shader.meta ├── TextureChannel.cs ├── TextureChannel.cs.meta ├── TextureChannelInput.cs ├── TextureChannelInput.cs.meta ├── TextureFormat.cs ├── TextureFormat.cs.meta ├── TextureInput.cs ├── TextureInput.cs.meta ├── TexturePacker.asmdef ├── TexturePacker.asmdef.meta ├── TexturePacker.cs ├── TexturePacker.cs.meta ├── TextureUtility.cs └── TextureUtility.cs.meta ├── Screenshots.meta ├── Screenshots ├── screen00.gif └── screen00.gif.meta ├── package.json └── package.json.meta /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Visual Studio 2015 cache directory 9 | /.vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | 26 | # Unity3D generated meta files 27 | *.pidb.meta 28 | 29 | # Unity3D Generated File On Crash Reports 30 | sysinfo.txt 31 | 32 | # Builds 33 | *.apk 34 | *.unitypackage 35 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e8fef3745f4b7b49816f2db7fa729d5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/TextureItem.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace TexPacker 5 | { 6 | class TextureItem 7 | { 8 | public TextureInput input; 9 | public bool toDelete { get; private set; } 10 | 11 | private bool _fold = true; 12 | 13 | public TextureItem(TextureInput input) 14 | { 15 | this.input = input; 16 | } 17 | 18 | private Rect GetFoldRect() 19 | { 20 | var r = EditorGUILayout.GetControlRect(); 21 | var rFold = r; 22 | rFold.width = 20; 23 | return rFold; 24 | } 25 | 26 | public void Draw() 27 | { 28 | GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1)); 29 | 30 | EditorGUILayout.BeginHorizontal(); 31 | 32 | _fold = EditorGUI.Foldout(GetFoldRect(), _fold, "Input"); 33 | 34 | var gearStyle = new GUIStyle(); 35 | GUILayout.FlexibleSpace(); 36 | if (GUILayout.Button(gearStyle.normal.background, new GUIStyle("IconButton"))) 37 | { 38 | var menu = new GenericMenu(); 39 | menu.AddItem(new GUIContent("Remove"), false, data => 40 | { 41 | var item = data as TextureItem; 42 | item.toDelete = true; 43 | 44 | }, this); 45 | 46 | menu.ShowAsContext(); 47 | } 48 | 49 | using (new EditorGUI.IndentLevelScope(1)) 50 | { 51 | EditorGUILayout.EndHorizontal(); 52 | if (_fold) 53 | { 54 | 55 | GUILayout.BeginHorizontal(TexturePackerStyles.Heading); 56 | 57 | GUILayout.BeginVertical(TexturePackerStyles.Heading); 58 | 59 | GUILayout.Label("Channels Selection:"); 60 | 61 | string[] channels = new string[] { "Red", "Green", "Blue", "Alpha" }; 62 | 63 | for (int i = 0; i < 4; ++i) 64 | { 65 | GUILayout.BeginHorizontal(); 66 | 67 | var texChannel = (TextureChannel)i; 68 | 69 | var channelInput = input.GetChannelInput(texChannel); 70 | 71 | channelInput.enabled = GUILayout.Toggle(channelInput.enabled, new GUIContent(" " + channels[i]), GUILayout.Width(60)); 72 | 73 | GUILayout.Label(">"); 74 | 75 | channelInput.output = (TextureChannel)EditorGUILayout.Popup((int)channelInput.output, channels, GUILayout.Width(80)); 76 | 77 | channelInput.invert = GUILayout.Toggle(channelInput.invert, "Invert"); 78 | 79 | input.SetChannelInput(texChannel, channelInput); 80 | 81 | GUILayout.EndHorizontal(); 82 | } 83 | 84 | GUILayout.EndVertical(); 85 | 86 | input.texture = EditorGUILayout.ObjectField(input.texture, typeof(Texture2D), false, GUILayout.Width(90), GUILayout.Height(80)) as Texture2D; 87 | 88 | GUILayout.EndHorizontal(); 89 | 90 | } 91 | } 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /Editor/TextureItem.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0cd187a7df676144f9ec54a8dfd7f019 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/TexturePacker.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TexturePacker.Editor", 3 | "references": [ 4 | "TexturePacker.Runtime" 5 | ], 6 | "optionalUnityReferences": [], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false 12 | } -------------------------------------------------------------------------------- /Editor/TexturePacker.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 417e30a6501c9ec428bbd14e342e477d 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/TexturePackerStyles.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | namespace TexPacker 7 | { 8 | public class TexturePackerStyles 9 | { 10 | 11 | static GUIStyle heading = null; 12 | public static GUIStyle Heading 13 | { 14 | get 15 | { 16 | if (heading == null) 17 | { 18 | try 19 | { 20 | heading = new GUIStyle("OL Title"); 21 | heading.padding = new RectOffset(10, 10, 10, 10); 22 | heading.margin = new RectOffset(4, 4, 4, 4); 23 | heading.fixedHeight = 0; 24 | heading.fontSize = 15; 25 | heading.alignment = TextAnchor.MiddleCenter; 26 | } 27 | catch { heading = GetErrorGUIStyle(); } 28 | } 29 | return heading; 30 | } 31 | } 32 | 33 | static GUIStyle midBox; 34 | public static GUIStyle MidBox 35 | { 36 | get 37 | { 38 | if (midBox == null) 39 | { 40 | try 41 | { 42 | midBox = new GUIStyle(GUI.skin.GetStyle("Box")); 43 | midBox.normal.background = GetBorderedTexture(new Color(0.26f, 0.26f, 0.26f), new Color(0.15f, 0.15f, 0.15f, 1)); 44 | midBox.border = new RectOffset(1, 1, 1, 1); 45 | midBox.padding = new RectOffset(5, 5, 5, 5); 46 | midBox.normal.textColor = new Color(0.7f, 0.7f, 0.7f, 1); 47 | midBox.alignment = TextAnchor.MiddleCenter; 48 | midBox.fontSize = 10; 49 | 50 | } 51 | catch 52 | { 53 | midBox = GetErrorGUIStyle(); 54 | } 55 | } 56 | return midBox; 57 | } 58 | } 59 | 60 | static GUIStyle section = null; 61 | public static GUIStyle Section 62 | { 63 | get 64 | { 65 | if (section == null) 66 | { 67 | try 68 | { 69 | section = new GUIStyle(GUI.skin.GetStyle("sv_iconselector_back")); 70 | section.padding = new RectOffset(4, 4, 4, 4); 71 | section.margin = new RectOffset(4, 4, 4, 4); 72 | section.stretchHeight = false; 73 | section.stretchWidth = true; 74 | 75 | } 76 | catch { section = GetErrorGUIStyle(); } 77 | } 78 | return section; 79 | } 80 | } 81 | 82 | private static GUIStyle m_Button = null; 83 | public static GUIStyle Button 84 | { 85 | get 86 | { 87 | if (m_Button == null) 88 | { 89 | try 90 | { 91 | m_Button = new GUIStyle(GUI.skin.button); 92 | 93 | m_Button.padding = new RectOffset(1, 1, 15, 15); 94 | m_Button.margin = new RectOffset(5, 5, 5, 0); 95 | m_Button.contentOffset = Vector2.zero; 96 | 97 | m_Button.fontSize = 11; 98 | 99 | m_Button.normal.textColor = EditorGUIUtility.isProSkin ? new Color(0.8f, 0.8f, 0.8f) : new Color(0.35f, 0.35f, 0.35f); 100 | m_Button.hover.textColor = EditorGUIUtility.isProSkin ? Color.white : new Color(0.2f, 0.2f, 0.2f); 101 | m_Button.active.textColor = EditorGUIUtility.isProSkin ? Color.gray : new Color(0.2f, 0.2f, 0.2f); 102 | m_Button.focused.textColor = Color.gray; 103 | 104 | m_Button.alignment = TextAnchor.MiddleCenter; 105 | 106 | m_Button.border = new RectOffset(3, 3, 3, 3); 107 | } 108 | catch { m_Button = GetErrorGUIStyle(); } 109 | 110 | } 111 | return m_Button; 112 | } 113 | } 114 | 115 | static Texture2D GetBorderedTexture(Color border, Color centre) 116 | { 117 | Texture2D returnTex = new Texture2D(3, 3); 118 | returnTex.filterMode = FilterMode.Point; 119 | for (int x = 0; x < returnTex.width; x++) 120 | { 121 | for (int y = 0; y < returnTex.height; y++) 122 | { 123 | returnTex.SetPixel(x, y, border); 124 | if (x == 1 && y == 1) 125 | { 126 | returnTex.SetPixel(x, y, centre); 127 | } 128 | } 129 | } 130 | returnTex.Apply(); 131 | returnTex.hideFlags = HideFlags.HideAndDontSave; 132 | return returnTex; 133 | } 134 | 135 | private static GUIStyle GetErrorGUIStyle() 136 | { 137 | GUIStyle s = new GUIStyle(); 138 | s.normal.textColor = Color.magenta; 139 | return s; 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Editor/TexturePackerStyles.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b2d0a4316a8fe248b51fc50b879152d 3 | timeCreated: 1518231934 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Editor/TexturePackerWindow.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | namespace TexPacker 8 | { 9 | public class TexturePackerWindow : EditorWindow 10 | { 11 | private readonly string _windowTitle = "Channel Packer"; 12 | private readonly Vector2 _windowSize = new Vector2(300, 450); 13 | private readonly int _maxInputCount = 4; 14 | private readonly int _textureSupportedResolutionMin = 64; 15 | private readonly int _textureSupportedResolutionMax = 8192; 16 | 17 | Vector2 _windowScrollPos; 18 | 19 | private TextureFormat _textureFormat = TextureFormat.PNG; 20 | 21 | private TexturePacker _texturePacker = new TexturePacker(); 22 | 23 | private List _textureResolutions = new List(); 24 | private List _textureResolutionsNames = new List(); 25 | 26 | private List _items = new List(); 27 | private TexturePreview _preview; 28 | 29 | [MenuItem("Window/Channel Packer")] 30 | static void Open() 31 | { 32 | TexturePackerWindow window = GetWindow(); 33 | window.Initialize(); 34 | } 35 | 36 | public void Initialize() 37 | { 38 | minSize = _windowSize; 39 | titleContent = new GUIContent(_windowTitle); 40 | 41 | for(int i = _textureSupportedResolutionMin; i <= _textureSupportedResolutionMax; i *= 2) 42 | { 43 | _textureResolutions.Add(i); 44 | _textureResolutionsNames.Add(i.ToString()); 45 | } 46 | 47 | _texturePacker.Initialize(); 48 | _preview = new TexturePreview(); 49 | } 50 | 51 | private void RefreshItems() 52 | { 53 | if (_items.Count == 0) 54 | return; 55 | 56 | var toDeleteItems = _items.Where(x => x.toDelete==true).ToList(); 57 | foreach (var item in toDeleteItems) 58 | { 59 | _texturePacker.Remove(item.input); 60 | _items.Remove(item); 61 | } 62 | } 63 | 64 | private void OnGUI() 65 | { 66 | _windowScrollPos = EditorGUILayout.BeginScrollView(_windowScrollPos, false, false); 67 | 68 | RefreshItems(); 69 | 70 | GUILayout.Label(_windowTitle, TexturePackerStyles.Heading); 71 | GUILayout.BeginVertical(TexturePackerStyles.Section); 72 | 73 | GUILayout.Label("Inputs", TexturePackerStyles.Heading); 74 | foreach (TextureItem item in _items) 75 | { 76 | item.Draw(); 77 | } 78 | 79 | EditorGUILayout.BeginHorizontal(); 80 | GUILayout.FlexibleSpace(); 81 | 82 | GUI.enabled = _items.Count < _maxInputCount; 83 | 84 | if (GUILayout.Button("+")) 85 | { 86 | TextureInput entry = new TextureInput(); 87 | _texturePacker.Add(entry); 88 | _items.Add(new TextureItem(entry)); 89 | } 90 | 91 | GUI.enabled = true; 92 | 93 | GUILayout.FlexibleSpace(); 94 | EditorGUILayout.EndHorizontal(); 95 | 96 | int prevRes = _texturePacker.resolution; 97 | _texturePacker.resolution = 128; 98 | 99 | _preview.Draw(_texturePacker); 100 | 101 | _texturePacker.resolution = prevRes; 102 | 103 | GUILayout.Label("Options", TexturePackerStyles.Heading); 104 | GUILayout.BeginVertical(TexturePackerStyles.Section); 105 | _textureFormat = (TextureFormat)EditorGUILayout.EnumPopup("> Format:", _textureFormat); 106 | _texturePacker.resolution = EditorGUILayout.IntPopup("> Resolution:", _texturePacker.resolution, _textureResolutionsNames.ToArray(), _textureResolutions.ToArray()); 107 | GUILayout.EndVertical(); 108 | 109 | if (GUILayout.Button("Generate Texture", TexturePackerStyles.Button)) 110 | { 111 | string defaultPath = Application.dataPath; 112 | if(_texturePacker.texInputs.Count > 0 && _texturePacker.texInputs[0].texture != null) 113 | { 114 | string path = AssetDatabase.GetAssetPath(_texturePacker.texInputs[0].texture); 115 | if(path != null && !string.IsNullOrEmpty(path)) 116 | { 117 | path = Path.Combine(Application.dataPath, "..", path); 118 | defaultPath = Path.GetDirectoryName(path); 119 | } 120 | } 121 | string savePath = EditorUtility.SaveFilePanel("Save", defaultPath, "texture.png", _textureFormat.ToString()); 122 | if (savePath != string.Empty) 123 | { 124 | Texture2D output = _texturePacker.Create(); 125 | 126 | if(_textureFormat == TextureFormat.JPG) 127 | File.WriteAllBytes(savePath, output.EncodeToJPG()); 128 | else if(_textureFormat == TextureFormat.PNG) 129 | File.WriteAllBytes(savePath, output.EncodeToPNG()); 130 | else 131 | File.WriteAllBytes(savePath, output.EncodeToEXR()); 132 | 133 | AssetDatabase.Refresh(); 134 | } 135 | } 136 | 137 | GUILayout.EndVertical(); 138 | EditorGUILayout.EndScrollView(); 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /Editor/TexturePackerWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ccb4b81226a897345898c0c1e08e4f14 3 | timeCreated: 1518232730 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Editor/TexturePreview.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | namespace TexPacker 5 | { 6 | public class TexturePreview 7 | { 8 | private int toolbarItem = 0; 9 | 10 | public void Draw(TexturePacker texPacker) 11 | { 12 | GUILayout.Label("Preview", TexturePackerStyles.Heading); 13 | 14 | GUILayout.BeginVertical(TexturePackerStyles.Section); 15 | 16 | GUILayout.BeginHorizontal(); 17 | GUILayout.FlexibleSpace(); 18 | 19 | Vector2 previewSize = new Vector2(256, 256); 20 | GUILayout.Label("", TexturePackerStyles.MidBox, GUILayout.Width(previewSize.x), GUILayout.Height(previewSize.y)); 21 | Rect previewRect = GUILayoutUtility.GetLastRect(); 22 | Rect alphaRect = new Rect(previewRect.x + 5, previewRect.y + 5, previewRect.width - 10, previewRect.height - 10); 23 | 24 | texPacker.ClearProperties(); 25 | 26 | Texture2D preview = texPacker.Create(); 27 | preview.alphaIsTransparency = true; 28 | 29 | if(toolbarItem == 0) 30 | EditorGUI.DrawPreviewTexture(alphaRect, preview); 31 | else 32 | EditorGUI.DrawTextureAlpha(alphaRect, preview); 33 | 34 | GUILayout.FlexibleSpace(); 35 | GUILayout.EndHorizontal(); 36 | 37 | string[] toolbarItems = { "RBG", "Alpha" }; 38 | toolbarItem = GUILayout.Toolbar(toolbarItem, toolbarItems); 39 | 40 | GUILayout.EndVertical(); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Editor/TexturePreview.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e41eb0696a90e74a907fb189f28036b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Andy Duboc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2615ccad97ee13644b5fd9e72f5b1e94 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | unity-texture-packer [![License](https://img.shields.io/badge/License-MIT-lightgrey.svg?style=flat)](http://mit-license.org) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/andyduboc/5usd) 2 | ========== 3 | 4 | 5 | :hammer: Utility to merge different texture channels into a final texture output. 6 | 7 | ![screenshot](Screenshots/screen00.gif) 8 | 9 | ## Install 10 | 11 | ### Using Git 12 | 13 | Make sure the Git client is installed on your marchine and that you have added the Git executable path to your PATH environment variable. 14 | 15 | Go in %ProjectFolder%/Packages/ and open the "manifest.json" file. 16 | 17 | in the "dependencies" section add: 18 | 19 | ```sh 20 | { 21 | "dependencies": { 22 | ... 23 | "ca.andydbc.unity-texture-packer":"https://github.com/andydbc/unity-texture-packer.git#0.1.0" 24 | ... 25 | } 26 | } 27 | ``` 28 | 29 | Find more information about this [here](https://docs.unity3d.com/Manual/upm-git.html). 30 | 31 | ### Manual 32 | 33 | Dowload this repository as a zip file, extract the archive.
34 | In Unity, go in "Window" -> "Package Manager" -> "Add Package from disk"
35 | Select the "package.json" file located at the root of the package folder.
36 | 37 | The tool is located under "Window" and is called "Channel Packer" 38 | 39 | ## Note 40 | 41 | This is still under development and may be buggy. 42 | 43 | ## License 44 | 45 | MIT. See [LICENSE](https://github.com/andydbc/unity-texture-packer/blob/master/LICENSE) for details. 46 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5bd95c17d9c7e647b152e3351d5748d 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60c7174790d61dc438065bc9241f177f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6da4e8b7c9fed3146a453b774f32b732 3 | folderAsset: yes 4 | timeCreated: 1518232730 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Runtime/Resources/TexturePacker.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/TexturePacker" 2 | { 3 | Properties 4 | { 5 | _Input00Tex ("Input00", 2D) = "black" {} 6 | _Input01Tex ("Input01", 2D) = "black" {} 7 | _Input02Tex ("Input02", 2D) = "black" {} 8 | _Input03Tex ("Input03", 2D) = "black" {} 9 | 10 | _Input00In ("Input00 In", Vector) = (0,0,0,0) 11 | _Input01In ("Input01 In", Vector) = (0,0,0,0) 12 | _Input02In ("Input02 In", Vector) = (0,0,0,0) 13 | _Input03In ("Input03 In", Vector) = (0,0,0,0) 14 | } 15 | SubShader 16 | { 17 | Tags { "RenderType"="Opaque" } 18 | LOD 100 19 | 20 | Pass 21 | { 22 | CGPROGRAM 23 | #pragma vertex vert 24 | #pragma fragment frag 25 | #pragma target 4.6 26 | 27 | #include "UnityCG.cginc" 28 | 29 | struct appdata 30 | { 31 | float4 vertex : POSITION; 32 | float2 uv : TEXCOORD0; 33 | }; 34 | 35 | struct v2f 36 | { 37 | float4 vertex : SV_POSITION; 38 | float2 uv : TEXCOORD0; 39 | }; 40 | 41 | sampler2D _Input00Tex; 42 | sampler2D _Input01Tex; 43 | sampler2D _Input02Tex; 44 | sampler2D _Input03Tex; 45 | 46 | float4 _Input00In; 47 | float4 _Input01In; 48 | float4 _Input02In; 49 | float4 _Input03In; 50 | 51 | float4 _Input00Inv; 52 | float4 _Input01Inv; 53 | float4 _Input02Inv; 54 | float4 _Input03Inv; 55 | 56 | float4x4 _Input00Out; 57 | float4x4 _Input01Out; 58 | float4x4 _Input02Out; 59 | float4x4 _Input03Out; 60 | 61 | v2f vert (appdata v) 62 | { 63 | v2f o; 64 | o.vertex = UnityObjectToClipPos(v.vertex); 65 | o.uv = v.uv; 66 | return o; 67 | } 68 | 69 | float4 SwapChannels(sampler2D tex, float2 uv, float4 e, float4 inv, float4x4 v) 70 | { 71 | float4 inColor = tex2D(tex, uv); 72 | 73 | float4 r = (inv[0] ? 1 - inColor.rrrr : inColor.rrrr) * v[0] * e.r; 74 | float4 g = (inv[1] ? 1 - inColor.gggg : inColor.gggg) * v[1] * e.g; 75 | float4 b = (inv[2] ? 1 - inColor.bbbb : inColor.bbbb) * v[2] * e.b; 76 | float4 a = (inv[3] ? 1 - inColor.aaaa : inColor.aaaa) * v[3] * e.a; 77 | 78 | return r + g + b + a; 79 | } 80 | 81 | fixed4 frag (v2f i) : SV_Target 82 | { 83 | float4 c00 = SwapChannels(_Input00Tex, i.uv, _Input00In, _Input00Inv, _Input00Out); 84 | float4 c01 = SwapChannels(_Input01Tex, i.uv, _Input01In, _Input01Inv, _Input01Out); 85 | float4 c02 = SwapChannels(_Input02Tex, i.uv, _Input02In, _Input02Inv, _Input02Out); 86 | float4 c03 = SwapChannels(_Input03Tex, i.uv, _Input03In, _Input03Inv, _Input03Out); 87 | return c00 + c01 + c02 + c03; 88 | } 89 | ENDCG 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Runtime/Resources/TexturePacker.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bea3dd713e1ce8d489e7d497974f902c 3 | timeCreated: 1518232731 4 | licenseType: Free 5 | ShaderImporter: 6 | externalObjects: {} 7 | defaultTextures: [] 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Runtime/TextureChannel.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | namespace TexPacker 5 | { 6 | public enum TextureChannel 7 | { 8 | ChannelRed, 9 | ChannelGreen, 10 | ChannelBlue, 11 | ChannelAlpha 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/TextureChannel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b91199eac73d6e44a6c99183cf83360 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/TextureChannelInput.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace TexPacker 6 | { 7 | public class TextureChannelInput 8 | { 9 | public bool enabled; 10 | public TextureChannel output; 11 | public bool invert; 12 | } 13 | } -------------------------------------------------------------------------------- /Runtime/TextureChannelInput.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 14de51b9d53880344b7db4f33265621b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/TextureFormat.cs: -------------------------------------------------------------------------------- 1 | namespace TexPacker 2 | { 3 | public enum TextureFormat 4 | { 5 | JPG, 6 | PNG, 7 | EXR, 8 | TGA 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Runtime/TextureFormat.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 440fe1e8d1a2eb34cbfca8517c3375f3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/TextureInput.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections.Generic; 4 | 5 | namespace TexPacker 6 | { 7 | public class TextureInput 8 | { 9 | public Texture2D texture; 10 | 11 | private Dictionary _inputs = new Dictionary(); 12 | 13 | public TextureInput() 14 | { 15 | _inputs[TextureChannel.ChannelRed] = new TextureChannelInput() { output = TextureChannel.ChannelRed }; 16 | _inputs[TextureChannel.ChannelGreen] = new TextureChannelInput() { output = TextureChannel.ChannelGreen }; 17 | _inputs[TextureChannel.ChannelBlue] = new TextureChannelInput() { output = TextureChannel.ChannelBlue }; 18 | _inputs[TextureChannel.ChannelAlpha] = new TextureChannelInput() { output = TextureChannel.ChannelAlpha }; 19 | } 20 | 21 | public TextureChannelInput GetChannelInput(TextureChannel channel) 22 | { 23 | return _inputs[channel]; 24 | } 25 | 26 | public void SetChannelInput(TextureChannel channel, TextureChannelInput channelInput) 27 | { 28 | _inputs[channel] = channelInput; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/TextureInput.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fce8d857a926c7d44b0fdf563e67ac37 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/TexturePacker.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TexturePacker.Runtime", 3 | "optionalUnityReferences": [], 4 | "includePlatforms": [], 5 | "excludePlatforms": [], 6 | "allowUnsafeCode": false 7 | } -------------------------------------------------------------------------------- /Runtime/TexturePacker.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3d1fb76a17114c9469f4f41657963541 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/TexturePacker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace TexPacker 5 | { 6 | public class TexturePacker 7 | { 8 | private readonly string _shaderName = "Hidden/TexturePacker"; 9 | private Material _material; 10 | 11 | private List _texInputs = new List(); 12 | public List texInputs { 13 | get { return _texInputs; } 14 | } 15 | 16 | public int resolution = 2048; 17 | 18 | public void Initialize() 19 | { 20 | if (_material == null) 21 | { 22 | _material = new Material(Shader.Find(_shaderName)); 23 | _material.hideFlags = HideFlags.HideAndDontSave; 24 | } 25 | } 26 | 27 | public void Add(TextureInput entry) 28 | { 29 | _texInputs.Add(entry); 30 | } 31 | 32 | public void Remove(TextureInput input) 33 | { 34 | _texInputs.Remove(input); 35 | } 36 | 37 | private string GetPropertyName(int i, string param) 38 | { 39 | return string.Format("_Input0{0}{1}", i, param); 40 | } 41 | 42 | public void ClearProperties() 43 | { 44 | for (int i = 0; i < 6; ++i) 45 | { 46 | _material.SetTexture(GetPropertyName(i, "Tex"), Texture2D.blackTexture); 47 | _material.SetVector(GetPropertyName(i, "In"), Vector4.zero); 48 | } 49 | } 50 | 51 | private Vector4 GetInputs(TextureInput texInput) 52 | { 53 | Vector4 states = Vector4.zero; 54 | 55 | for (int i = 0; i < 4; ++i) 56 | { 57 | var state = texInput.GetChannelInput((TextureChannel)i).enabled; 58 | states[i] = state ? 1f : 0f; 59 | } 60 | 61 | return states; 62 | } 63 | 64 | private Vector4 GetInverts(TextureInput texInput) 65 | { 66 | Vector4 states = Vector4.zero; 67 | 68 | for (int i = 0; i < 4; ++i) 69 | { 70 | var state = texInput.GetChannelInput((TextureChannel)i).invert; 71 | states[i] = state ? 1f : 0f; 72 | } 73 | 74 | return states; 75 | } 76 | 77 | private Matrix4x4 GetOutputs(TextureInput texInput) 78 | { 79 | Matrix4x4 m = Matrix4x4.zero; 80 | 81 | for (int i = 0; i < 4; ++i) 82 | { 83 | Vector4 inChannel = Vector4.zero; 84 | var output = texInput.GetChannelInput((TextureChannel)i).output; 85 | inChannel[(int)output] = 1f; 86 | m.SetRow(i, inChannel); 87 | } 88 | 89 | return m; 90 | } 91 | 92 | public Texture2D Create() 93 | { 94 | int idx = 0; 95 | foreach(var input in _texInputs) 96 | { 97 | var Tex = input.texture; 98 | _material.SetTexture(GetPropertyName(idx, "Tex"), Tex); 99 | 100 | var In = GetInputs(input); 101 | _material.SetVector(GetPropertyName(idx, "In"), In); 102 | 103 | var Inv = GetInverts(input); 104 | _material.SetVector(GetPropertyName(idx, "Inv"), Inv); 105 | 106 | var Out = GetOutputs(input); 107 | _material.SetMatrix(GetPropertyName(idx, "Out"), Out); 108 | ++idx; 109 | } 110 | 111 | var texture = TextureUtility.GenerateTexture(resolution, resolution, _material); 112 | 113 | return texture; 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /Runtime/TexturePacker.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a45ee38a261334140b3a7ed63679725f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/TextureUtility.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace TexPacker 4 | { 5 | public static class TextureUtility 6 | { 7 | public static Texture2D GenerateTexture(int width, int height, Material mat) 8 | { 9 | RenderTexture tempRT = RenderTexture.GetTemporary(width, height); 10 | Graphics.Blit(Texture2D.blackTexture, tempRT, mat); 11 | 12 | Texture2D output = new Texture2D(tempRT.width, tempRT.height, UnityEngine.TextureFormat.RGBA32, false); 13 | RenderTexture.active = tempRT; 14 | 15 | output.ReadPixels(new Rect(0, 0, tempRT.width, tempRT.height), 0, 0); 16 | output.Apply(); 17 | output.filterMode = FilterMode.Bilinear; 18 | 19 | RenderTexture.ReleaseTemporary(tempRT); 20 | RenderTexture.active = null; 21 | 22 | return output; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Runtime/TextureUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d78f92166bc95d84cbbe74e15007e99e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Screenshots.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7df9a486603777e4686242d10bd86f44 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Screenshots/screen00.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andydbc/unity-texture-packer/2e7ade973895a31b8b5d02672c1642b8b2bde6bb/Screenshots/screen00.gif -------------------------------------------------------------------------------- /Screenshots/screen00.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c2e1bcdf1fe109743bab2df404e5a884 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 10 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 3 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | forceMaximumCompressionQuality_BC6H_BC7: 0 73 | spriteSheet: 74 | serializedVersion: 2 75 | sprites: [] 76 | outline: [] 77 | physicsShape: [] 78 | bones: [] 79 | spriteID: 80 | internalID: 0 81 | vertices: [] 82 | indices: 83 | edges: [] 84 | weights: [] 85 | secondaryTextures: [] 86 | spritePackingTag: 87 | pSDRemoveMatte: 0 88 | pSDShowRemoveMatteOption: 0 89 | userData: 90 | assetBundleName: 91 | assetBundleVariant: 92 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Andy Duboc", 3 | "description": "Tool used to merge arbitary texture channels in one texture ouput.", 4 | "displayName": "Texture Channel Packer", 5 | "license": "MIT", 6 | "name": "ca.andydbc.unity-texture-packer", 7 | "unity": "2019.2", 8 | "unityRelease": "0f1", 9 | "version": "0.1.0" 10 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad1883742e4b0644ead4870a98157c69 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------