using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; using UnityEngine.Experimental.Rendering; public class ShaderTextureCombiner : EditorWindow { //Input textures private Texture2D[] textures = new Texture2D[4]; //Invert bool for each texture private bool[] invert = new bool[4]; //Output texture private Texture2D generatedTexture; //Dimensions of output texture private Vector2Int textureDimensions; //The value for the channels where a texture is not provided private float defaultValue = 1.0f; //Counter of generated textures used for naming private int totalTextures; private bool hasAlpha = false; [MenuItem("Tools/ShaderTextureCombiner")] private static void ShowWindow() { var window = GetWindow(); window.titleContent = new GUIContent("Texture Combiner"); window.Show(); } private void OnGUI() { //Displaying the texture fields textures[0] = (Texture2D) EditorGUILayout.ObjectField("Texture 1 (R)", textures[0], typeof(Texture2D), false); invert[0] = GUILayout.Toggle(invert[0], "Invert", "Button"); textures[1] = (Texture2D) EditorGUILayout.ObjectField("Texture 2 (G)", textures[1], typeof(Texture2D), false); invert[1] = GUILayout.Toggle(invert[1], "Invert", "Button"); textures[2] = (Texture2D) EditorGUILayout.ObjectField("Texture 3 (B)", textures[2], typeof(Texture2D), false); invert[2] = GUILayout.Toggle(invert[2], "Invert", "Button"); textures[3] = (Texture2D) EditorGUILayout.ObjectField("Texture 4 (A)", textures[3], typeof(Texture2D), false); invert[3] = GUILayout.Toggle(invert[3], "Invert", "Button"); //Displaying the texture information textureDimensions = EditorGUILayout.Vector2IntField("Dimensions", textureDimensions); defaultValue = EditorGUILayout.Slider("Default value", defaultValue, 0.0f, 1.0f); GUILayout.BeginHorizontal(); if (GUILayout.Button("Generate texture")) { GenerateTexture(); } if (GUILayout.Button("Save texture")) { SaveGeneratedTexture(); } GUILayout.EndHorizontal(); //Showing preview of the generated texture and its alpha (if it has any) if (generatedTexture != null) { EditorGUILayout.LabelField("Generated texture preview"); EditorGUI.DrawPreviewTexture(new Rect(50, 450, 100, 100), generatedTexture); if (hasAlpha) { EditorGUI.DrawTextureAlpha(new Rect(200, 450, 100, 100), generatedTexture); } } } private void GenerateTexture() { generatedTexture = null; if (AllTexturesAreEmpty()) { Debug.LogWarning("No input textures given, not generating a texture!"); return; } hasAlpha = (textures[3] != null); RenderTexture rt = new RenderTexture(textureDimensions.x, textureDimensions.y, 0, GraphicsFormat.R8G8B8A8_SRGB); RenderTexture.active = rt; //Creating a material based on the custom shader Material mat = new Material(Shader.Find("Hidden/TextureCombinerShader")); SetMaterialProperties(mat); //Rendering on the render texture using the custom material Graphics.Blit(null, rt, mat); generatedTexture = new Texture2D(textureDimensions.x, textureDimensions.y, hasAlpha ? TextureFormat.RGBA32 : TextureFormat.RGB24, false); generatedTexture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); generatedTexture.Apply(); } private void SetMaterialProperties(Material mat) { mat.SetTexture("_TextureR", textures[0]); mat.SetTexture("_TextureG", textures[1]); mat.SetTexture("_TextureB", textures[2]); mat.SetTexture("_TextureA", textures[3]); mat.SetFloat("_DefaultValue", defaultValue); mat.SetVector("_TexturesGiven", GetTexturesGiven()); mat.SetVector("_InvertedTextures", GetInvertedTextures()); } private Vector4 GetInvertedTextures() { Vector4 invertedTextures = new Vector4(); invertedTextures.x = (invert[0]) ? 1 : 0; invertedTextures.y = (invert[1]) ? 1 : 0; invertedTextures.z = (invert[2]) ? 1 : 0; invertedTextures.w = (invert[3]) ? 1 : 0; return invertedTextures; } private Vector4 GetTexturesGiven() { Vector4 texturesGiven = new Vector4(); texturesGiven.x = (textures[0] == null) ? 0 : 1; texturesGiven.y = (textures[1] == null) ? 0 : 1; texturesGiven.z = (textures[2] == null) ? 0 : 1; texturesGiven.w = (textures[3] == null) ? 0 : 1; return texturesGiven; } private void SaveGeneratedTexture() { GenerateTexture(); //If a directory called "Textures/Generated Textures" doesn't exist, create it if (!Directory.Exists(Application.dataPath + "Textures/Generated Textures")) { Directory.CreateDirectory(Application.dataPath + "/Textures/Generated Textures/"); totalTextures = 0; } else { totalTextures = Directory.GetFiles(Application.dataPath + "/Textures/Generated Textures/").Length; } byte[] bytes = generatedTexture.EncodeToPNG(); while (File.Exists(Application.dataPath + "/Textures/Generated Textures/generated_texture_" + totalTextures.ToString() + ".png")) { totalTextures++; } File.WriteAllBytes(Application.dataPath + "/Textures/Generated Textures/generated_texture_" + totalTextures.ToString() + ".png", bytes); AssetDatabase.Refresh(); EditorUtility.FocusProjectWindow(); Selection.activeObject = AssetDatabase.LoadMainAssetAtPath("Assets/Textures/Generated Textures/generated_texture_" + totalTextures.ToString() + ".png"); } private bool AllTexturesAreEmpty() { for (int i = 0; i < 4; i++) { if (textures[i] != null) { return false; } } return true; } }