// Alloy Physical Shader Framework // Copyright 2013-2017 RUST LLC. // http://www.alloy.rustltd.com/ using System.Collections.Generic; using System.Linq; using System.IO; using UnityEditor; using UnityEngine; public static class AlloyMigrationTools { #if H3VR_IMPORTED private const string keywordReportFilename = "/Alloy/Scripts/Material Report.txt"; [MenuItem(AlloyUtils.MenuItem + "Material Report", false, 11)] private static void MaterialReport() { var fileName = Application.dataPath + keywordReportFilename; var sr = File.CreateText(fileName); var materials = GetSceneMaterialsWithKeywords().OrderBy(m => m.name); var keywordList = materials .SelectMany(m => m.shaderKeywords) .Where(k => !string.IsNullOrEmpty(k)) .Distinct() .OrderBy(k => k); var keywordCount = keywordList.Count(); var materialShaderNames = new List(); sr.WriteLine(" "); sr.WriteLine("-----------------------------------------------------------------------"); sr.WriteLine(" Keywords: " + keywordCount); sr.WriteLine("-----------------------------------------------------------------------"); foreach (var keyword in keywordList) { sr.WriteLine("\"" + keyword + "\","); } sr.WriteLine(" "); sr.WriteLine("-----------------------------------------------------------------------"); sr.WriteLine(" Keywords -> Materials: " + keywordCount); sr.WriteLine("-----------------------------------------------------------------------"); foreach (var keyword in keywordList) { sr.WriteLine("\"" + keyword + "\","); foreach (var material in materials) { var shaderKeywords = material.shaderKeywords; if (shaderKeywords.Contains(keyword)) { sr.WriteLine(" " + material.name); } } sr.WriteLine(" "); } sr.WriteLine("-----------------------------------------------------------------------"); sr.WriteLine(" Materials -> Keywords: " + materials.Count()); sr.WriteLine("-----------------------------------------------------------------------"); foreach (var material in materials) { var shaderKeywords = material.shaderKeywords.OrderBy(k => k); sr.WriteLine(material.name); foreach (var keyword in shaderKeywords) { if (!string.IsNullOrEmpty(keyword)) { sr.WriteLine(" \"" + keyword + "\","); } } sr.WriteLine(" "); materialShaderNames.Add(material.shader.name); } var shaderNames = materialShaderNames.Distinct().OrderBy(s => s); sr.WriteLine("-----------------------------------------------------------------------"); sr.WriteLine(" Shaders -> Materials: " + shaderNames.Count()); sr.WriteLine("-----------------------------------------------------------------------"); foreach (var shaderName in shaderNames) { var shaderMaterials = materials.Where(m => m.shader.name == shaderName).Select(m => m.name); sr.WriteLine("\"" + shaderName + "\""); foreach (var materialName in shaderMaterials) { if (!string.IsNullOrEmpty(materialName)) { sr.WriteLine(" " + materialName); } } sr.WriteLine(" "); } sr.Close(); System.Diagnostics.Process.Start(fileName); } // [MenuItem(AlloyUtils.MenuItem + "Material Migrator", false, 11)] // private static void MaterialMigrator() { // var window = ScriptableObject.CreateInstance(); // var dimensions = new Vector2(350, 100); // // window.position = new Rect(Screen.width / 2, Screen.height / 2, 0, 0); // window.minSize = dimensions; // window.maxSize = dimensions; // window.ShowUtility(); // } [MenuItem(AlloyUtils.MenuItem + "Light Converter", false, 11)] private static void LightConverter() { var lights = Resources.FindObjectsOfTypeAll(); var lightsLength = lights.Length; for (int i = 0; i < lightsLength; i++) { var light = lights[i]; EditorUtility.DisplayProgressBar( "Converting lights...", string.Format("Light {0} / {1}.", i + 1, lightsLength), i / (lightsLength - 1.0f)); // Skip Unity baked Area Lights & Prefabs. if (light.type != LightType.Area && !EditorUtility.IsPersistent(light)) { var area = light.GetComponent(); if (area == null) { Undo.RecordObject(light.gameObject, "Convert to Alloy area lights."); area = Undo.AddComponent(light.gameObject); } Undo.RecordObject(light, "Set default light cookie"); area.UpdateBinding(); } } EditorUtility.ClearProgressBar(); } private static IEnumerable GetSceneMaterialsWithKeywords() { return Resources.FindObjectsOfTypeAll().Where(m => m.shaderKeywords.Length > 0); } } public class AlloyMaterialMigratorPopup : EditorWindow { private const string messageFilename = "/Alloy/Scripts/Editor/MaterialMigratorWarning.txt"; private static string[] keywordsToRemove = new string[] { "_AO2MAPUV_UV0", "_AO2MAPUV_UV1", "_BLENDMAPUV_UV0", "_BLENDMAPUV_UV1", "_BUMPMODE_BUMP", "_BUMPMODE_PARALLAX", // Set by stupid KeywordEnum. "_BUMPMODE_SPOM", "_CARFLAKEMAPUV_UV0", "_CARFLAKEMAPUV_UV1", "_DECAL_OFF", "_DECALMODE_NONE", "_DECALTEXUV_UV0", "_DECALTEXUV_UV1", "_DETAIL_ON", // Replaced with _DETAIL_MULX2 "_DETAILALBEDOMAPUV_UV0", "_DETAILALBEDOMAPUV_UV1", "_DETAILMASKSSOURCE_TEXTURE", // From when I was trying that Masks channel picker idea. >_< "_DETAILMASKSOURCE_TEXTURE", // Discarded first attempt at name. "_DETAILMASKSOURCE_TEXTUREALPHA", // Set by stupid KeywordEnum. "_DETAILMASKSOURCE_VERTEXCOLORALPHA", // Replaced with _NORMALMAP "_DETAILMODE_MUL", "_DETAILMODE_MULX2", "_DIRECTIONALBLENDMODE_OBJECT", // Set by stupid KeywordEnum. "_DISSOLVETEXUV_UV0", "_DISSOLVETEXUV_UV1", "_EMISSION_ON", "_ENVIRONMENTMAPMODE_RSRM", "_ENVIRONMENTMAPMODE_SKYSHOP", "_ENVIRONMENTMAPMODE_SKYSHOPSH", "_INCANDESCENCEMAPUV_UV0", "_INCANDESCENCEMAPUV_UV1", "_INCANDESCENCEMAPUV2_UV0", "_INCANDESCENCEMAPUV2_UV1", "_MAINTEXTURESMODE_FULL", "_MAINTEXTURESMODE_LITE", "_MAINTEXTURESROUGHNESSSOURCE_BASECOLORALPHA", // Discarded first attempt at name. "_MAINTEXTURESROUGHNESSSOURCE_MATERIALALPHA", // Discarded first attempt at name. "_MAINROUGHNESSSOURCE_BASECOLORALPHA", // Replaced with _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A "_MAINROUGHNESSSOURCE_PACKEDMAPALPHA", // Set by stupid KeywordEnum. "_ORIENTEDROUGHNESSSOURCE_BASECOLORALPHA", // Replaced with _SPECGLOSSMAP "_ORIENTEDROUGHNESSSOURCE_PACKEDMAPALPHA", // Set by stupid KeywordEnum. "_ORIENTEDTEXTURESMODE_FULL", "_ORIENTEDTEXTURESMODE_LITE", "_ORIENTEDTEXTURESROUGHNESSSOURCE_BASECOLORALPHA", // Discarded first attempt at name. "_ORIENTEDTEXTURESROUGHNESSSOURCE_MATERIALALPHA", // Discarded first attempt at name. "_PARALLAX_ON", // Replaced with _PARALLAXMAP "_RIMTEXUV_UV0", "_RIMTEXUV_UV1", "_RIMTEXUV2_UV0", "_RIMTEXUV2_UV1", "_SECONDARYROUGHNESSSOURCE_BASECOLORALPHA", // Replaced with _METALLICGLOSSMAP "_SECONDARYROUGHNESSSOURCE_PACKEDMAPALPHA", // Set by stupid KeywordEnum. "_SECONDARYTEXTURESMODE_FULL", "_SECONDARYTEXTURESMODE_LITE", "_TESSELLATIONMODE_COMBINED", // Dropped this mode in favor of using two other modes keywords together. "_TRANSITIONTEXUV_UV0", "_TRANSITIONTEXUV_UV1", "_TRIPLANARMODE_OBJECT", // Set by stupid KeywordEnum. "_UVSEC_UV0", // Standard shader sets this. "_UVSEC_UV1", // Standard shader sets this. }; void OnGUI() { var message = File.ReadAllText(Application.dataPath + messageFilename); titleContent = new GUIContent("Migrate Materials?"); EditorGUILayout.LabelField(message, EditorStyles.wordWrappedLabel); GUILayout.Space(10); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Confirm")) { Close(); MigrateMaterials(); } if (GUILayout.Button("Cancel")) { Close(); } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } void MigrateMaterials() { try { var materialGuids = AssetDatabase.FindAssets("t:material"); var length = materialGuids.Length; for (int i = 0; i < length; i++) { var material = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(materialGuids[i]), typeof(Material)) as Material; var toRemove = material.shaderKeywords.Intersect(keywordsToRemove); var shaderName = material.shader.name; EditorUtility.DisplayProgressBar( "Migrating Materials...", string.Format("({0} / {1}) {2}", i, length, material.name), i / (float)(length - 1)); if (shaderName.Contains("Alloy")) { if (material.HasProperty("_HasBumpMap") && Mathf.Approximately(material.GetFloat("_HasBumpMap"), 1.0f)) { material.EnableKeyword("EFFECT_BUMP"); } foreach (var keyword in toRemove) { if (!string.IsNullOrEmpty(keyword)) { material.DisableKeyword(keyword); // Migrate to Unity keywords. switch (keyword) { case "_DETAIL_ON": material.EnableKeyword("_DETAIL_MULX2"); break; case "_DETAILMASKSOURCE_VERTEXCOLORALPHA": material.EnableKeyword("_NORMALMAP"); break; case "_MAINROUGHNESSSOURCE_BASECOLORALPHA": material.EnableKeyword("_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A"); break; case "_PARALLAX_ON": material.EnableKeyword("_PARALLAXMAP"); break; } } } EditorUtility.SetDirty(material); AssetDatabase.SaveAssets(); material = null; EditorUtility.UnloadUnusedAssetsImmediate(); } } } finally { EditorUtility.ClearProgressBar(); } } #endif }