summaryrefslogtreecommitdiffstats
path: root/Scripts
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-03-02 18:02:20 -0800
committeryum <yum.food.vr@gmail.com>2026-03-02 18:02:20 -0800
commit6222291192d52d198ad8db9328c449493f43afac (patch)
treedc06ef88a471d29925c8678a7e81e30f870ab853 /Scripts
parentfd5b8029a8303e6b0db0c9c7e309aa0075302935 (diff)
Add metallic gloss to decals
Diffstat (limited to 'Scripts')
-rw-r--r--Scripts/MetallicGloss.cs113
1 files changed, 113 insertions, 0 deletions
diff --git a/Scripts/MetallicGloss.cs b/Scripts/MetallicGloss.cs
new file mode 100644
index 0000000..d0b8895
--- /dev/null
+++ b/Scripts/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;
+ }
+}