using System.IO; using UnityEditor; using UnityEngine; public class MetallicGloss : EditorWindow { Texture2D metallicMap; Texture2D smoothnessMap; bool invertMetallic; bool invertSmoothness; [MenuItem("Tools/yum_food/Metallic Gloss")] static void ShowWindow() { var window = GetWindow("Metallic Gloss"); window.minSize = new Vector2(300, 180); } void OnGUI() { EditorGUILayout.Space(5); metallicMap = (Texture2D)EditorGUILayout.ObjectField("Metallic Map", metallicMap, typeof(Texture2D), false); invertMetallic = EditorGUILayout.Toggle("Invert", invertMetallic); EditorGUILayout.Space(5); smoothnessMap = (Texture2D)EditorGUILayout.ObjectField("Smoothness Map", smoothnessMap, typeof(Texture2D), false); invertSmoothness = EditorGUILayout.Toggle("Invert", invertSmoothness); if (metallicMap != null) EnforceLinear(metallicMap); if (smoothnessMap != null) EnforceLinear(smoothnessMap); EditorGUILayout.Space(10); using (new EditorGUI.DisabledScope(metallicMap == null && smoothnessMap == null)) { if (GUILayout.Button("Merge")) Merge(); } } static void EnforceLinear(Texture2D tex) { string path = AssetDatabase.GetAssetPath(tex); if (!string.IsNullOrEmpty(path)) EnforceSettings(path); } static void EnforceSettings(string path) { var importer = AssetImporter.GetAtPath(path) as TextureImporter; if (importer == null) return; bool dirty = false; if (importer.sRGBTexture) { importer.sRGBTexture = false; dirty = true; } if (importer.textureType != TextureImporterType.Default) { importer.textureType = TextureImporterType.Default; dirty = true; } if (importer.wrapMode != TextureWrapMode.Repeat) { importer.wrapMode = TextureWrapMode.Repeat; dirty = true; } if (importer.filterMode != FilterMode.Trilinear) { importer.filterMode = FilterMode.Trilinear; dirty = true; } if (importer.anisoLevel != 4) { importer.anisoLevel = 4; dirty = true; } if (dirty) importer.SaveAndReimport(); } void Merge() { Texture2D reference = metallicMap != null ? metallicMap : smoothnessMap; int w = reference.width; int h = reference.height; Color[] mPixels = metallicMap != null ? ReadPixels(metallicMap, w, h) : null; Color[] sPixels = smoothnessMap != null ? ReadPixels(smoothnessMap, w, h) : null; var pixels = new Color[w * h]; for (int i = 0; i < pixels.Length; i++) { float m = mPixels != null ? mPixels[i].r : 0; float s = sPixels != null ? sPixels[i].r : 0; if (invertMetallic) m = 1 - m; if (invertSmoothness) s = 1 - s; pixels[i] = new Color(m, 0, 0, s); } var output = new Texture2D(w, h, TextureFormat.RGBA32, false, true); output.SetPixels(pixels); output.Apply(); string refPath = AssetDatabase.GetAssetPath(reference); string dir = Path.GetDirectoryName(refPath); string basename = Path.GetFileNameWithoutExtension(refPath); string outputPath = Path.Combine(dir, basename + "_metallic_gloss.png"); File.WriteAllBytes(outputPath, output.EncodeToPNG()); DestroyImmediate(output); AssetDatabase.ImportAsset(outputPath); EnforceSettings(outputPath); EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(outputPath)); } static Color[] ReadPixels(Texture2D tex, int w, int h) { var rt = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); Graphics.Blit(tex, rt); var prev = RenderTexture.active; RenderTexture.active = rt; var tmp = new Texture2D(w, h, TextureFormat.RGBA32, false, true); tmp.ReadPixels(new Rect(0, 0, w, h), 0, 0); tmp.Apply(); RenderTexture.active = prev; RenderTexture.ReleaseTemporary(rt); var pixels = tmp.GetPixels(); DestroyImmediate(tmp); return pixels; } }