diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-02 18:02:20 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-03 18:10:32 -0800 |
| commit | f186fd5523b313e90da8f99ab752d40a0012cfca (patch) | |
| tree | b9178a6c0ac1b0c278de28eef29556c9eab94b10 /Scripts/Editor/MetallicGloss.cs | |
| parent | 6222291192d52d198ad8db9328c449493f43afac (diff) | |
Add metallic gloss to decals
Diffstat (limited to 'Scripts/Editor/MetallicGloss.cs')
| -rw-r--r-- | Scripts/Editor/MetallicGloss.cs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/Scripts/Editor/MetallicGloss.cs b/Scripts/Editor/MetallicGloss.cs new file mode 100644 index 0000000..d0b8895 --- /dev/null +++ b/Scripts/Editor/MetallicGloss.cs @@ -0,0 +1,113 @@ +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<MetallicGloss>("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<Texture2D>(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; + } +} |
