yum/3ner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum/3ner

yumAdd metallic gloss to decalsf186fd5

master
4.1 KiB113 linesraw
1using System.IO;
2using UnityEditor;
3using UnityEngine;
4
5public class MetallicGloss : EditorWindow
6{
7    Texture2D metallicMap;
8    Texture2D smoothnessMap;
9    bool invertMetallic;
10    bool invertSmoothness;
11
12    [MenuItem("Tools/yum_food/Metallic Gloss")]
13    static void ShowWindow()
14    {
15        var window = GetWindow<MetallicGloss>("Metallic Gloss");
16        window.minSize = new Vector2(300, 180);
17    }
18
19    void OnGUI()
20    {
21        EditorGUILayout.Space(5);
22
23        metallicMap = (Texture2D)EditorGUILayout.ObjectField("Metallic Map", metallicMap, typeof(Texture2D), false);
24        invertMetallic = EditorGUILayout.Toggle("Invert", invertMetallic);
25
26        EditorGUILayout.Space(5);
27
28        smoothnessMap = (Texture2D)EditorGUILayout.ObjectField("Smoothness Map", smoothnessMap, typeof(Texture2D), false);
29        invertSmoothness = EditorGUILayout.Toggle("Invert", invertSmoothness);
30
31        if (metallicMap != null) EnforceLinear(metallicMap);
32        if (smoothnessMap != null) EnforceLinear(smoothnessMap);
33
34        EditorGUILayout.Space(10);
35
36        using (new EditorGUI.DisabledScope(metallicMap == null && smoothnessMap == null))
37        {
38            if (GUILayout.Button("Merge"))
39                Merge();
40        }
41    }
42
43    static void EnforceLinear(Texture2D tex)
44    {
45        string path = AssetDatabase.GetAssetPath(tex);
46        if (!string.IsNullOrEmpty(path)) EnforceSettings(path);
47    }
48
49    static void EnforceSettings(string path)
50    {
51        var importer = AssetImporter.GetAtPath(path) as TextureImporter;
52        if (importer == null) return;
53        bool dirty = false;
54        if (importer.sRGBTexture) { importer.sRGBTexture = false; dirty = true; }
55        if (importer.textureType != TextureImporterType.Default) { importer.textureType = TextureImporterType.Default; dirty = true; }
56        if (importer.wrapMode != TextureWrapMode.Repeat) { importer.wrapMode = TextureWrapMode.Repeat; dirty = true; }
57        if (importer.filterMode != FilterMode.Trilinear) { importer.filterMode = FilterMode.Trilinear; dirty = true; }
58        if (importer.anisoLevel != 4) { importer.anisoLevel = 4; dirty = true; }
59        if (dirty) importer.SaveAndReimport();
60    }
61
62    void Merge()
63    {
64        Texture2D reference = metallicMap != null ? metallicMap : smoothnessMap;
65        int w = reference.width;
66        int h = reference.height;
67
68        Color[] mPixels = metallicMap != null ? ReadPixels(metallicMap, w, h) : null;
69        Color[] sPixels = smoothnessMap != null ? ReadPixels(smoothnessMap, w, h) : null;
70
71        var pixels = new Color[w * h];
72        for (int i = 0; i < pixels.Length; i++)
73        {
74            float m = mPixels != null ? mPixels[i].r : 0;
75            float s = sPixels != null ? sPixels[i].r : 0;
76            if (invertMetallic) m = 1 - m;
77            if (invertSmoothness) s = 1 - s;
78            pixels[i] = new Color(m, 0, 0, s);
79        }
80
81        var output = new Texture2D(w, h, TextureFormat.RGBA32, false, true);
82        output.SetPixels(pixels);
83        output.Apply();
84
85        string refPath = AssetDatabase.GetAssetPath(reference);
86        string dir = Path.GetDirectoryName(refPath);
87        string basename = Path.GetFileNameWithoutExtension(refPath);
88        string outputPath = Path.Combine(dir, basename + "_metallic_gloss.png");
89
90        File.WriteAllBytes(outputPath, output.EncodeToPNG());
91        DestroyImmediate(output);
92        AssetDatabase.ImportAsset(outputPath);
93
94        EnforceSettings(outputPath);
95        EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<Texture2D>(outputPath));
96    }
97
98    static Color[] ReadPixels(Texture2D tex, int w, int h)
99    {
100        var rt = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
101        Graphics.Blit(tex, rt);
102        var prev = RenderTexture.active;
103        RenderTexture.active = rt;
104        var tmp = new Texture2D(w, h, TextureFormat.RGBA32, false, true);
105        tmp.ReadPixels(new Rect(0, 0, w, h), 0, 0);
106        tmp.Apply();
107        RenderTexture.active = prev;
108        RenderTexture.ReleaseTemporary(rt);
109        var pixels = tmp.GetPixels();
110        DestroyImmediate(tmp);
111        return pixels;
112    }
113}