#if UNITY_EDITOR using System; using System.Collections.Generic; using System.IO; using System.Text; using UnityEngine; using UnityEditor; using System.Reflection; using System.Text.RegularExpressions; #if UNITY_2020_2_OR_NEWER using UnityEditor.AssetImporters; #else using UnityEditor.Experimental.AssetImporters; #endif namespace lilToon { #if UNITY_2019_4_OR_NEWER [ScriptedImporter(0, "lilcontainer")] public class lilShaderContainerImporter : ScriptedImporter { public override void OnImportAsset(AssetImportContext ctx) { #if UNITY_2019_4_0 || UNITY_2019_4_1 || UNITY_2019_4_2 || UNITY_2019_4_3 || UNITY_2019_4_4 || UNITY_2019_4_5 || UNITY_2019_4_6 || UNITY_2019_4_7 || UNITY_2019_4_8 || UNITY_2019_4_9 || UNITY_2019_4_10 Shader shader = ShaderUtil.CreateShaderAsset(lilShaderContainer.UnpackContainer(ctx.assetPath, ctx), false); #else Shader shader = ShaderUtil.CreateShaderAsset(ctx, lilShaderContainer.UnpackContainer(ctx.assetPath, ctx), false); #endif ctx.AddObjectToAsset("main obj", shader); ctx.SetMainObject(shader); } } [CustomEditor(typeof(lilShaderContainerImporter))] public class lilShaderContainerImporterEditor : ScriptedImporterEditor { public override void OnInspectorGUI() { if(GUILayout.Button("Export Shader")) { string assetPath = AssetDatabase.GetAssetPath(target); string shaderText = lilShaderContainer.UnpackContainer(assetPath); string exportPath = EditorUtility.SaveFilePanel("Export Shader", Path.GetDirectoryName(assetPath), Path.GetFileNameWithoutExtension(assetPath), "shader"); if(string.IsNullOrEmpty(exportPath)) return; File.WriteAllText(exportPath, shaderText); } ApplyRevertGUI(); } } public class lilShaderContainerAssetPostprocessor : AssetPostprocessor { private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach(string path in importedAssets) { if(!path.EndsWith("lilcontainer", StringComparison.InvariantCultureIgnoreCase)) continue; var mainobj = AssetDatabase.LoadMainAssetAtPath(path); if(mainobj is Shader) ShaderUtil.RegisterShader((Shader)mainobj); foreach(var obj in AssetDatabase.LoadAllAssetRepresentationsAtPath(path)) { if(obj is Shader) ShaderUtil.RegisterShader((Shader)obj); } } } } #endif public class lilShaderContainer { private const string MULTI_COMPILE_FORWARD = "#pragma lil_multi_compile_forward"; private const string MULTI_COMPILE_FORWARDADD = "#pragma lil_multi_compile_forwardadd"; private const string MULTI_COMPILE_SHADOWCASTER = "#pragma lil_multi_compile_shadowcaster"; private const string MULTI_COMPILE_DEPTHONLY = "#pragma lil_multi_compile_depthonly"; private const string MULTI_COMPILE_DEPTHNORMALS = "#pragma lil_multi_compile_depthnormals"; private const string MULTI_COMPILE_MOTIONVECTORS = "#pragma lil_multi_compile_motionvectors"; private const string MULTI_COMPILE_SCENESELECTION = "#pragma lil_multi_compile_sceneselection"; private const string MULTI_COMPILE_META = "#pragma lil_multi_compile_meta"; private const string MULTI_COMPILE_INSTANCING = "#pragma multi_compile_instancing"; private const string SKIP_VARIANTS_SHADOWS = "#pragma lil_skip_variants_shadows"; private const string SKIP_VARIANTS_LIGHTMAPS = "#pragma lil_skip_variants_lightmaps"; private const string SKIP_VARIANTS_DECALS = "#pragma lil_skip_variants_decals"; private const string SKIP_VARIANTS_ADDLIGHT = "#pragma lil_skip_variants_addlight"; private const string SKIP_VARIANTS_ADDLIGHTSHADOWS = "#pragma lil_skip_variants_addlightshadows"; private const string SKIP_VARIANTS_PROBEVOLUMES = "#pragma lil_skip_variants_probevolumes"; private const string SKIP_VARIANTS_AO = "#pragma lil_skip_variants_ao"; private const string SKIP_VARIANTS_LIGHTLISTS = "#pragma lil_skip_variants_lightlists"; private const string SKIP_VARIANTS_REFLECTIONS = "#pragma lil_skip_variants_reflections"; private const string SKIP_VARIANTS_BASE_SHADOWS = "#pragma lil_skip_variants_base_shadows"; private const string SKIP_VARIANTS_OUTLINE_SHADOWS = "#pragma lil_skip_variants_outline_shadows"; private const string INCLUDE_BRP = "Includes/lil_pipeline_brp.hlsl\""; private const string INCLUDE_LWRP = "Includes/lil_pipeline_lwrp.hlsl\""; private const string INCLUDE_URP = "Includes/lil_pipeline_urp.hlsl\""; private const string INCLUDE_HDRP = "Includes/lil_pipeline_hdrp.hlsl\""; private const string LIL_SHADER_NAME = "*LIL_SHADER_NAME*"; private const string LIL_EDITOR_NAME = "*LIL_EDITOR_NAME*"; private const string LIL_SUBSHADER_INSERT = "*LIL_SUBSHADER_INSERT*"; private const string LIL_SUBSHADER_INSERT_POST = "*LIL_SUBSHADER_INSERT_POST*"; private const string LIL_SHADER_SETTING = "*LIL_SHADER_SETTING*"; private const string LIL_PASS_SHADER_NAME = "*LIL_PASS_SHADER_NAME*"; private const string LIL_SUBSHADER_TAGS = "*LIL_SUBSHADER_TAGS*"; private const string LIL_DOTS_SM_TAGS = "*LIL_DOTS_SM_TAGS*"; private const string LIL_DOTS_SM_4_5 = "*LIL_DOTS_SM_4_5*"; private const string LIL_DOTS_SM_4_5_OR_3_5 = "*LIL_DOTS_SM_4_5_OR_3_5*"; private const string LIL_INSERT_PASS_PRE = "*LIL_INSERT_PASS_PRE*"; private const string LIL_INSERT_PASS_POST = "*LIL_INSERT_PASS_POST*"; private const string LIL_INSERT_USEPASS_PRE = "*LIL_INSERT_USEPASS_PRE*"; private const string LIL_INSERT_USEPASS_POST = "*LIL_INSERT_USEPASS_POST*"; private const string LIL_LIGHTMODE_FORWARD_0 = "*LIL_LIGHTMODE_FORWARD_0*"; private const string LIL_LIGHTMODE_FORWARD_1 = "*LIL_LIGHTMODE_FORWARD_1*"; private const string LIL_LIGHTMODE_FORWARD_2 = "*LIL_LIGHTMODE_FORWARD_2*"; private const string LIL_LIGHTMODE_BRP_FORWARD_0 = "ForwardBase"; private const string LIL_LIGHTMODE_BRP_FORWARD_1 = "ForwardBase"; private const string LIL_LIGHTMODE_BRP_FORWARD_2 = "ForwardBase"; private const string LIL_LIGHTMODE_HDRP_FORWARD_0 = "ForwardOnly"; private const string LIL_LIGHTMODE_HDRP_FORWARD_1 = "Forward"; private const string LIL_LIGHTMODE_HDRP_FORWARD_2 = "SRPDefaultUnlit"; private const string LIL_LIGHTMODE_LWRP_FORWARD_0 = "LightweightForward"; private const string LIL_LIGHTMODE_LWRP_FORWARD_1 = "SRPDefaultUnlit"; private const string LIL_LIGHTMODE_LWRP_FORWARD_2 = "SRPDefaultUnlit"; private const string LIL_LIGHTMODE_URP_7_FORWARD_0 = "UniversalForward"; private const string LIL_LIGHTMODE_URP_7_FORWARD_1 = "LightweightForward"; private const string LIL_LIGHTMODE_URP_7_FORWARD_2 = "SRPDefaultUnlit"; private const string LIL_LIGHTMODE_URP_8_FORWARD_0 = "SRPDefaultUnlit"; private const string LIL_LIGHTMODE_URP_8_FORWARD_1 = "UniversalForward"; private const string LIL_LIGHTMODE_URP_8_FORWARD_2 = "LightweightForward"; private const string LIL_LIGHTMODE_URP_9_FORWARD_0 = "SRPDefaultUnlit"; private const string LIL_LIGHTMODE_URP_9_FORWARD_1 = "UniversalForward"; private const string LIL_LIGHTMODE_URP_9_FORWARD_2 = "UniversalForwardOnly"; private const string csdShaderNameTag = "ShaderName"; private const string csdEditorNameTag = "EditorName"; private const string csdReplaceTag = "Replace"; private const string csdInsertPassPreTag = "InsertPassPre"; private const string csdInsertPassPostTag = "InsertPassPost"; private const string csdInsertUsePassPreTag = "InsertUsePassPre"; private const string csdInsertUsePassPostTag = "InsertUsePassPost"; private static Dictionary replaces = new Dictionary(); private const string customShaderDataFile = "lilCustomShaderDatas.lilblock"; private const string customShaderResourcesFolderGUID = "1acd4e79a7d2c6c44aa8b97a1e33f20b"; // "Assets/lilToon/CustomShaderResources" private static string GetCustomShaderResourcesFolderPath() { return AssetDatabase.GUIDToAssetPath(customShaderResourcesFolderGUID); } private static string passShaderName = ""; private static string subShaderTags = ""; private static string insertText = ""; private static string insertPostText = ""; private static string shaderSettingText = ""; private static string resourcesFolderPath = ""; private static string assetFolderPath = ""; private static string shaderLibsPath = ""; private static string assetName = ""; private static string shaderName = ""; private static string editorName = ""; private static string origShaderName = ""; private static bool isOrigShaderNameLoaded = false; private static bool useBaseShadow = false; private static bool useOutlineShadow = false; private static string insertPassPre = ""; private static string insertPassPost = ""; private static string insertUsePassPre = ""; private static string insertUsePassPost = ""; private static PackageVersionInfos version = new PackageVersionInfos(); private static int indent = 12; public static string UnpackContainer(string assetPath, AssetImportContext ctx, bool doOptimize) { useBaseShadow = false; useOutlineShadow = false; passShaderName = ""; subShaderTags = ""; insertText = ""; insertPostText = ""; resourcesFolderPath = GetCustomShaderResourcesFolderPath() + "/"; assetFolderPath = Path.GetDirectoryName(assetPath) + "/"; shaderLibsPath = lilDirectoryManager.GetShaderFolderPath() + "/Includes"; assetName = Path.GetFileName(assetPath); shaderSettingText = BuildShaderSettingString(false, ref useBaseShadow, ref useOutlineShadow).Replace(Environment.NewLine, Environment.NewLine + " "); shaderName = ""; editorName = ""; origShaderName = ""; insertPassPre = ""; insertPassPost = ""; insertUsePassPre = ""; insertUsePassPost = ""; isOrigShaderNameLoaded = false; replaces = new Dictionary(); StringBuilder sb; version = lilRenderPipelineReader.GetRPInfos(); switch(version.RP) { case lilRenderPipeline.BRP: sb = ReadContainerFile(assetPath, "BRP", ctx, doOptimize); ReplaceMultiCompiles(ref sb, version, indent, false); RewriteForwardAdd(ref sb); RewriteForwardAddShadow(ref sb); break; case lilRenderPipeline.LWRP: sb = ReadContainerFile(assetPath, "LWRP", ctx, doOptimize); ReplaceMultiCompiles(ref sb, version, indent, false); break; case lilRenderPipeline.URP: sb = ReadContainerFile(assetPath, "URP", ctx, doOptimize); break; case lilRenderPipeline.HDRP: sb = ReadContainerFile(assetPath, "HDRP", ctx, doOptimize); ReplaceMultiCompiles(ref sb, version, indent, false); break; default: sb = ReadContainerFile(assetPath, "BRP", ctx, doOptimize); ReplaceMultiCompiles(ref sb, version, indent, false); break; } if(version.RP != lilRenderPipeline.BRP && version.Major > 0) { shaderSettingText += Environment.NewLine + " #define LIL_SRP_VERSION_MAJOR " + version.Major + Environment.NewLine + " #define LIL_SRP_VERSION_MINOR " + version.Minor + Environment.NewLine + " #define LIL_SRP_VERSION_PATCH " + version.Patch + Environment.NewLine; } ReadDataFile(ctx); ReplaceMultiCompiles(ref insertPassPre, version, indent, false); ReplaceMultiCompiles(ref insertPassPost, version, indent, false); ReplaceMultiCompiles(ref insertUsePassPre, version, indent, false); ReplaceMultiCompiles(ref insertUsePassPost, version, indent, false); sb.Replace(LIL_INSERT_PASS_PRE, insertPassPre); sb.Replace(LIL_INSERT_PASS_POST, insertPassPost); sb.Replace(LIL_INSERT_USEPASS_PRE, insertUsePassPre); sb.Replace(LIL_INSERT_USEPASS_POST, insertUsePassPost); if(ctx != null) sb.Replace("\"Includes", "\"" + shaderLibsPath); sb.Replace(LIL_SUBSHADER_INSERT, insertText); sb.Replace(LIL_SUBSHADER_INSERT_POST, insertPostText); sb.Replace(LIL_SHADER_SETTING, shaderSettingText); sb.Replace(LIL_PASS_SHADER_NAME, passShaderName); sb.Replace(LIL_SUBSHADER_TAGS, subShaderTags); sb.Replace(LIL_SHADER_NAME, shaderName); sb.Replace(LIL_EDITOR_NAME, editorName); if(useBaseShadow) sb.Replace(SKIP_VARIANTS_BASE_SHADOWS, ""); else sb.Replace(SKIP_VARIANTS_BASE_SHADOWS, SKIP_VARIANTS_SHADOWS); if(useOutlineShadow) sb.Replace(SKIP_VARIANTS_OUTLINE_SHADOWS, ""); else sb.Replace(SKIP_VARIANTS_OUTLINE_SHADOWS, SKIP_VARIANTS_SHADOWS); sb.Replace(SKIP_VARIANTS_SHADOWS, GetSkipVariantsShadows()); sb.Replace(SKIP_VARIANTS_LIGHTMAPS, GetSkipVariantsLightmaps()); sb.Replace(SKIP_VARIANTS_DECALS, GetSkipVariantsDecals()); sb.Replace(SKIP_VARIANTS_ADDLIGHTSHADOWS, GetSkipVariantsAddLightShadows()); sb.Replace(SKIP_VARIANTS_ADDLIGHT, GetSkipVariantsAddLight()); sb.Replace(SKIP_VARIANTS_PROBEVOLUMES, GetSkipVariantsProbeVolumes()); sb.Replace(SKIP_VARIANTS_AO, GetSkipVariantsAO()); sb.Replace(SKIP_VARIANTS_LIGHTLISTS, GetSkipVariantsLightLists()); sb.Replace(SKIP_VARIANTS_REFLECTIONS, GetSkipVariantsReflections()); sb.Replace("(\"Version\", Int) = 0", "(\"Version\", Int) = " + lilConstants.currentVersionValue.ToString()); LightModeOverride(ref sb, "FORWARD", GetStringField("mainLightModeName")); LightModeOverride(ref sb, "FORWARD_OUTLINE", GetStringField("outlineLightModeName")); LightModeOverride(ref sb, "FORWARD_BACK", GetStringField("preLightModeName")); LightModeOverride(ref sb, "FORWARD_FUR", GetStringField("furLightModeName")); LightModeOverride(ref sb, "FORWARD_FUR_PRE", GetStringField("furPreLightModeName")); LightModeOverride(ref sb, "FORWARD_PRE", GetStringField("gemPreLightModeName")); switch(version.RP) { case lilRenderPipeline.BRP: sb.Replace(LIL_LIGHTMODE_FORWARD_0, LIL_LIGHTMODE_BRP_FORWARD_0); sb.Replace(LIL_LIGHTMODE_FORWARD_1, LIL_LIGHTMODE_BRP_FORWARD_1); sb.Replace(LIL_LIGHTMODE_FORWARD_2, LIL_LIGHTMODE_BRP_FORWARD_2); break; case lilRenderPipeline.LWRP: sb.Replace(LIL_LIGHTMODE_FORWARD_0, LIL_LIGHTMODE_LWRP_FORWARD_0); sb.Replace(LIL_LIGHTMODE_FORWARD_1, LIL_LIGHTMODE_LWRP_FORWARD_1); sb.Replace(LIL_LIGHTMODE_FORWARD_2, LIL_LIGHTMODE_LWRP_FORWARD_2); break; case lilRenderPipeline.URP: if(version.Major == 8) { sb.Replace(LIL_LIGHTMODE_FORWARD_0, LIL_LIGHTMODE_URP_8_FORWARD_0); sb.Replace(LIL_LIGHTMODE_FORWARD_1, LIL_LIGHTMODE_URP_8_FORWARD_1); sb.Replace(LIL_LIGHTMODE_FORWARD_2, LIL_LIGHTMODE_URP_8_FORWARD_2); } else if(version.Major == 7) { sb.Replace(LIL_LIGHTMODE_FORWARD_0, LIL_LIGHTMODE_URP_7_FORWARD_0); sb.Replace(LIL_LIGHTMODE_FORWARD_1, LIL_LIGHTMODE_URP_7_FORWARD_1); sb.Replace(LIL_LIGHTMODE_FORWARD_2, LIL_LIGHTMODE_URP_7_FORWARD_2); } else { sb.Replace(LIL_LIGHTMODE_FORWARD_0, LIL_LIGHTMODE_URP_9_FORWARD_0); sb.Replace(LIL_LIGHTMODE_FORWARD_1, LIL_LIGHTMODE_URP_9_FORWARD_1); sb.Replace(LIL_LIGHTMODE_FORWARD_2, LIL_LIGHTMODE_URP_9_FORWARD_2); } break; case lilRenderPipeline.HDRP: if(sb.ToString().Contains(LIL_LIGHTMODE_FORWARD_2)) { sb.Replace(LIL_LIGHTMODE_FORWARD_0, LIL_LIGHTMODE_HDRP_FORWARD_0); sb.Replace(LIL_LIGHTMODE_FORWARD_1, LIL_LIGHTMODE_HDRP_FORWARD_1); sb.Replace(LIL_LIGHTMODE_FORWARD_2, LIL_LIGHTMODE_HDRP_FORWARD_2); } else { sb.Replace(LIL_LIGHTMODE_FORWARD_0, LIL_LIGHTMODE_HDRP_FORWARD_0); sb.Replace(LIL_LIGHTMODE_FORWARD_1, LIL_LIGHTMODE_HDRP_FORWARD_2); } sb.Replace("\"RenderType\" = \"Opaque\"", "\"RenderType\" = \"HDLitShader\""); sb.Replace("\"RenderType\" = \"Transparent\"", "\"RenderType\" = \"HDLitShader\""); sb.Replace("\"RenderType\" = \"TransparentCutout\"", "\"RenderType\" = \"HDLitShader\""); sb.Replace("\"Queue\" = \"AlphaTest+10\"", "\"Queue\" = \"Transparent\""); sb.Replace("\"Queue\" = \"AlphaTest+55\"", "\"Queue\" = \"Transparent\""); sb.Replace("\"Queue\" = \"Transparent-100\"", "\"Queue\" = \"Transparent\""); break; default: sb.Replace(LIL_LIGHTMODE_FORWARD_0, LIL_LIGHTMODE_BRP_FORWARD_0); sb.Replace(LIL_LIGHTMODE_FORWARD_1, LIL_LIGHTMODE_BRP_FORWARD_1); sb.Replace(LIL_LIGHTMODE_FORWARD_2, LIL_LIGHTMODE_BRP_FORWARD_2); break; } if(assetName.Contains("ltspass_tess_")) { sb.Replace( "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_domain _ FOG_LINEAR FOG_EXP FOG_EXP2" ); } if((assetName.Contains("lts_fur") && !assetName.Contains("cutout")) || assetName.Contains("trans") || assetName.Contains("overlay")) { sb.Replace( "(\"Alpha Cutoff\", Range(-0.001,1.001)) = 0.5", "(\"Alpha Cutoff\", Range(-0.001,1.001)) = 0.001" ); } foreach(KeyValuePair replace in replaces) { sb.Replace(FixNewlineCode(replace.Key), FixNewlineCode(replace.Value)); } FixIncludeForOldUnity(ref sb); if( doOptimize && !assetName.Contains("ltsmulti") && !assetName.Contains("ltspass_lite") && !assetName.Contains("ltsl") && File.Exists(lilDirectoryManager.postBuildTempPath) ) { string pathOpt = AssetDatabase.GUIDToAssetPath("571051a232e4af44a98389bda858df27"); if(!string.IsNullOrEmpty(pathOpt)) { StringBuilder sbInput = new StringBuilder(); sbInput.AppendLine(""); sbInput.AppendLine(" CBUFFER_START(UnityPerMaterial)"); sbInput.Append (" #include \""); sbInput.Append (pathOpt); sbInput.AppendLine("\""); sbInput.AppendLine(" #if defined(LIL_CUSTOM_PROPERTIES)"); sbInput.AppendLine(" LIL_CUSTOM_PROPERTIES"); sbInput.AppendLine(" #endif"); sbInput.Append(" CBUFFER_END"); string inputText = sbInput.ToString(); sb.Replace(INCLUDE_BRP , INCLUDE_BRP + inputText); sb.Replace(INCLUDE_LWRP, INCLUDE_LWRP + inputText); sb.Replace(INCLUDE_URP , INCLUDE_URP + inputText); sb.Replace(INCLUDE_HDRP, INCLUDE_HDRP + inputText); } } sb.Replace("\r\n", "\r"); sb.Replace("\n", "\r"); sb.Replace("\r", "\r\n"); sb.Replace("\r\n \r\n", "\r\n"); sb.Replace("\r\n \r\n", "\r\n"); sb.Replace("\r\n \r\n", "\r\n"); return sb.ToString(); } public static string UnpackContainer(string assetPath, AssetImportContext ctx = null) { bool doOptimize = File.Exists(lilDirectoryManager.postBuildTempPath); return UnpackContainer(assetPath, ctx, doOptimize); } private static void ReadDataFile(AssetImportContext ctx) { string path = assetFolderPath + customShaderDataFile; if(!File.Exists(path)) { Debug.LogWarning("[" + assetName + "] " + "File not found: " + path); return; } AddDependency(ctx, path); StreamReader sr = new StreamReader(path); string line; while ((line = sr.ReadLine()) != null) { if(line.Contains(csdShaderNameTag)) { shaderName = GetTags(line); origShaderName = origShaderName.Replace(LIL_SHADER_NAME, shaderName); continue; } if(line.Contains(csdEditorNameTag)) { editorName = GetTags(line); continue; } if(line.Contains(csdReplaceTag)) { GetReplaces(line); continue; } if(line.Contains("Insert")) { GetInsert(line, ctx); continue; } } sr.Close(); } private static string GetTags(string line) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); return line.Substring(first, second - first); } private static void GetReplaces(string line) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); int third = line.IndexOf('"', second + 1) + 1; int fourth = line.IndexOf('"', third); int fifth = line.IndexOf('"', fourth + 1) + 1; if(fifth > 1) { int sixth = line.IndexOf('"', fifth); string name = line.Substring(first, second - first); if(name.StartsWith("!")) { if(origShaderName.Contains(name.Substring(1))) { return; } } else if(!origShaderName.Contains(name)) { return; } string from = line.Substring(third, fourth - third); string to = line.Substring(fifth, sixth - fifth); replaces[from] = to; } else { string from = line.Substring(first, second - first); string to = line.Substring(third, fourth - third); replaces[from] = to; } } private static void GetInsert(string line, AssetImportContext ctx) { string rpname = "BRP"; if(version.RP == lilRenderPipeline.LWRP) rpname = "LWRP"; if(version.RP == lilRenderPipeline.URP) rpname = "URP"; if(version.RP == lilRenderPipeline.HDRP) rpname = "HDRP"; if(line.Contains(csdInsertPassPreTag)) { GetInsert(ref insertPassPre, line, rpname, ctx); } if(line.Contains(csdInsertPassPostTag)) { GetInsert(ref insertPassPost, line, rpname, ctx); } if(line.Contains(csdInsertUsePassPreTag)) { GetInsert(ref insertUsePassPre, line, rpname, ctx); } if(line.Contains(csdInsertUsePassPostTag)) { GetInsert(ref insertUsePassPost, line, rpname, ctx); } } private static void GetInsert(ref string insertPass, string line, string rpname, AssetImportContext ctx) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); int third = line.IndexOf('"', second + 1) + 1; string subpath; if (third > 1) { int fourth = line.IndexOf('"', third); string name = line.Substring(first, second - first); if (name.StartsWith("!")) { if (origShaderName.Contains(name.Substring(1))) { return; } } else if (!origShaderName.Contains(name)) { return; } subpath = line.Substring(third, fourth - third); } else { subpath = line.Substring(first, second - first); } // for render pipeline string pathForRP = assetFolderPath + Path.GetFileNameWithoutExtension(subpath) + rpname + Path.GetExtension(subpath); if(File.Exists(pathForRP)) { AddDependency(ctx, pathForRP); insertPass = ReadTextFile(pathForRP); return; } // normal subpath = assetFolderPath + subpath; if(!File.Exists(subpath)) { Debug.LogWarning("[" + assetName + "] " + "File not found: " + subpath); return; } AddDependency(ctx, subpath); insertPass = ReadTextFile(subpath); } private static StringBuilder ReadContainerFile(string path, string rpname, AssetImportContext ctx, bool doOptimize) { StringBuilder sb = new StringBuilder(); StreamReader sr = new StreamReader(path); string line; while ((line = sr.ReadLine()) != null) { if(!isOrigShaderNameLoaded && line.StartsWith("Shader")) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); if(line.Substring(0, first).Contains("//")) { sb.AppendLine(line); continue; } origShaderName = line.Substring(first, second - first); isOrigShaderNameLoaded = true; } if(line.Contains("lil")) { if(line.Contains("lilSkipSettings")) { if(line.Substring(0, line.IndexOf("lilSkipSettings") + 1).Contains("//")) { sb.AppendLine(line); continue; } shaderSettingText = ""; continue; } if(line.Contains("lilProperties")) { GetProperties(path, rpname, sb, line, ctx, doOptimize); continue; } if(line.Contains("lilSubShader")) { if(line.Contains(rpname)) { GetSubShader(path, rpname, sb, line, ctx); } else if(line.Contains("lilSubShaderInsertPost")) { GetSubShaderInsertPost(path, rpname, sb, line, ctx); } else if(line.Contains("lilSubShaderInsert")) { GetSubShaderInsert(path, rpname, sb, line, ctx); } else if(line.Contains("lilSubShaderTags")) { GetSubShaderTags(path, rpname, sb, line); } continue; } if(line.Contains("lilPassShaderName")) { GetPassShaderName(path, rpname, sb, line); continue; } } sb.AppendLine(line); } sr.Close(); return sb; } private static void GetSubShader(string path, string rpname, StringBuilder sb, string line, AssetImportContext ctx) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); if(line.Substring(0, first).Contains("//")) { sb.AppendLine(line); return; } string subpath = line.Substring(first, second - first); if(subpath.Contains("Default") && !subpath.Contains(".lilblock")) { subpath = resourcesFolderPath + rpname + "/" + subpath + ".lilblock"; } else { subpath = assetFolderPath + subpath; } if(!File.Exists(subpath)) { Debug.LogWarning("[" + assetName + "] " + "File not found: " + subpath); return; } AddDependency(ctx, subpath); if(rpname == "URP" && !subpath.Contains("UsePass")) { StringBuilder sb1 = new StringBuilder(ReadTextFile(subpath)); StringBuilder sb2 = new StringBuilder(sb1.ToString()); sb1.Replace(LIL_DOTS_SM_TAGS, " \"ShaderModel\" = \"4.5\""); //sb1.Replace(LIL_DOTS_SM_4_5, "#pragma target 4.5" + Environment.NewLine + " #pragma exclude_renderers gles gles3 glcore"); //sb1.Replace(LIL_DOTS_SM_4_5_OR_3_5, "#pragma target 4.5" + Environment.NewLine + " #pragma exclude_renderers gles gles3 glcore"); sb1.Replace(LIL_DOTS_SM_4_5, "#pragma target 4.5"); sb1.Replace(LIL_DOTS_SM_4_5_OR_3_5, "#pragma target 4.5"); ReplaceMultiCompiles(ref sb1, version, indent, true); sb.AppendLine(sb1.ToString()); sb.AppendLine(); sb2.Replace(LIL_DOTS_SM_TAGS, ""); //sb2.Replace(LIL_DOTS_SM_4_5, "#pragma only_renderers gles gles3 glcore d3d11"); //sb2.Replace(LIL_DOTS_SM_4_5_OR_3_5, "#pragma target 3.5" + Environment.NewLine + " #pragma only_renderers gles gles3 glcore d3d11"); sb2.Replace(LIL_DOTS_SM_4_5, ""); sb2.Replace(LIL_DOTS_SM_4_5_OR_3_5, "#pragma target 3.5"); ReplaceMultiCompiles(ref sb2, version, indent, false); sb.AppendLine(sb2.ToString()); } else { sb.AppendLine(ReadTextFile(subpath)); } } private static void GetSubShaderInsert(string path, string rpname, StringBuilder sb, string line, AssetImportContext ctx) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); if(line.Substring(0, first).Contains("//")) { sb.AppendLine(line); return; } string subpath = assetFolderPath + line.Substring(first, second - first); if(!File.Exists(subpath)) { Debug.LogWarning("[" + assetName + "] " + "File not found: " + subpath); return; } AddDependency(ctx, subpath); insertText = ReadTextFile(subpath); } private static void GetSubShaderInsertPost(string path, string rpname, StringBuilder sb, string line, AssetImportContext ctx) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); if(line.Substring(0, first).Contains("//")) { sb.AppendLine(line); return; } string subpath = assetFolderPath + line.Substring(first, second - first); if(!File.Exists(subpath)) { Debug.LogWarning("[" + assetName + "] " + "File not found: " + subpath); return; } AddDependency(ctx, subpath); insertPostText = ReadTextFile(subpath); } private static void GetProperties(string path, string rpname, StringBuilder sb, string line, AssetImportContext ctx, bool doOptimize) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); if(line.Substring(0, first).Contains("//")) { sb.AppendLine(line); return; } string subpath = line.Substring(first, second - first); if(subpath.Contains("Default") && !subpath.Contains(".lilblock")) { subpath = resourcesFolderPath + "Properties/" + subpath + ".lilblock"; } else { subpath = assetFolderPath + subpath; } if(!File.Exists(subpath)) { Debug.LogWarning("[" + assetName + "] " + "File not found: " + subpath); return; } AddDependency(ctx, subpath); string propText = ReadTextFile(subpath); if(doOptimize) { propText = Regex.Replace(propText, @"\(""[^""]*""", "(\"\""); // Display name propText = Regex.Replace(propText, @"\[lil[^\]]*\]", ""); // [lil*] propText = Regex.Replace(propText, @"\[Enum[^\]]*\]", ""); // [Enum(*)] propText = Regex.Replace(propText, @"\[PowerSlider[^\]]*\]", ""); // [PowerSlider(*)] propText = propText.Replace("[NoScaleOffset]", ""); propText = propText.Replace("[HideInInspector]", ""); propText = propText.Replace("[IntRange]", ""); } sb.AppendLine(propText); } private static void GetPassShaderName(string path, string rpname, StringBuilder sb, string line) { int first = line.IndexOf('"') + 1; int second = line.IndexOf('"', first); if(line.Substring(0, first).Contains("//")) { sb.AppendLine(line); return; } passShaderName = line.Substring(first, second - first); } private static void GetSubShaderTags(string path, string rpname, StringBuilder sb, string line) { int first = line.IndexOf('{') + 1; int second = line.IndexOf('}', first); if(line.Substring(0, first).Contains("//")) { sb.AppendLine(line); return; } subShaderTags = line.Substring(first, second - first); } private static string ReadTextFile(string path) { StreamReader sr = new StreamReader(path); string text = sr.ReadToEnd(); sr.Close(); return text; } private static string FixNewlineCode(string text) { return text.Replace("\\r", "\r").Replace("\\n", "\n"); } private static void FixIncludeForOldUnity(ref StringBuilder sb) { #if UNITY_2019_4_0 || UNITY_2019_4_1 || UNITY_2019_4_2 || UNITY_2019_4_3 || UNITY_2019_4_4 || UNITY_2019_4_5 || UNITY_2019_4_6 || UNITY_2019_4_7 || UNITY_2019_4_8 || UNITY_2019_4_9 || UNITY_2019_4_10 string additionalPath = assetFolderPath.Replace("\\", "/"); char[] escapes = Environment.NewLine.ToCharArray(); string[] text = sb.ToString().Split(escapes[0]); sb.Clear(); if(escapes.Length >= 1) { foreach(char escape in escapes) { string escapeStr = escape.ToString(); for(int i = 0; i < text.Length; i++) { text[i] = text[i].Replace(escapeStr, ""); } } } foreach(string line in text) { if(line.Contains("#include \"") && !line.Contains("\"Assets/") && !line.Contains("\"Packages/")) { sb.AppendLine(line.Replace("#include \"", "#include \"" + additionalPath)); } else { sb.AppendLine(line); } } #endif } //------------------------------------------------------------------------------------------------------------------------------ // Utils private static string GetIndent(int indent) { return new string(' ', indent); } private static string GenerateIndentText(int indent, params string[] texts) { string ind = Environment.NewLine + GetIndent(indent); return string.Join(ind, texts); } private static string GetRelativePath(string fromPath, string toPath) { Uri fromUri = new Uri(Path.GetFullPath(fromPath)); Uri toUri = new Uri(Path.GetFullPath(toPath)); string relativePath = Uri.UnescapeDataString(fromUri.MakeRelativeUri(toUri).ToString()); relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, '/'); return relativePath; } private static void LightModeOverride(ref StringBuilder sb, string passName, string lightModeName) { if(!string.IsNullOrEmpty(lightModeName)) { sb.Replace( " Name \"" + passName + "\"" + Environment.NewLine + " Tags {\"LightMode\" = \"" + LIL_LIGHTMODE_FORWARD_0 + "\"}", " Name \"" + passName + "\"" + Environment.NewLine + " Tags {\"LightMode\" = \"" + lightModeName + "\"}" ); sb.Replace( " Name \"" + passName + "\"" + Environment.NewLine + " Tags {\"LightMode\" = \"" + LIL_LIGHTMODE_FORWARD_1 + "\"}", " Name \"" + passName + "\"" + Environment.NewLine + " Tags {\"LightMode\" = \"" + lightModeName + "\"}" ); sb.Replace( " Name \"" + passName + "\"" + Environment.NewLine + " Tags {\"LightMode\" = \"" + LIL_LIGHTMODE_FORWARD_2 + "\"}", " Name \"" + passName + "\"" + Environment.NewLine + " Tags {\"LightMode\" = \"" + lightModeName + "\"}" ); } } //------------------------------------------------------------------------------------------------------------------------------ // ForwardAdd public static void RewriteForwardAdd(ref StringBuilder sb) { bool enable = GetBoolField("LIL_OPTIMIZE_USE_FORWARDADD", true); if(enable) { sb.Replace( " // ForwardAdd Start" + Environment.NewLine + " /*", " // ForwardAdd Start" + Environment.NewLine + " //"); sb.Replace( " */" + Environment.NewLine + " // ForwardAdd End", " //" + Environment.NewLine + " // ForwardAdd End"); } else { sb.Replace( " // ForwardAdd Start" + Environment.NewLine + " //", " // ForwardAdd Start" + Environment.NewLine + " /*"); sb.Replace( " //" + Environment.NewLine + " // ForwardAdd End", " */" + Environment.NewLine + " // ForwardAdd End"); } string[] lines = sb.ToString().Split('\n'); sb = new StringBuilder(); for(int i = 0; i < lines.Length; i++) { string line = lines[i]; line = line.Replace("\r", ""); if(line.Contains("UsePass") && line.Contains("FORWARD_ADD")) { if(enable) { line = line.Replace( " //UsePass", " UsePass"); } else { line = line.Replace( " UsePass", " //UsePass"); } } sb.AppendLine(line); } } public static void RewriteForwardAddShadow(ref StringBuilder sb) { bool enable = GetBoolField("LIL_OPTIMIZE_USE_FORWARDADD_SHADOW"); if(enable) { sb.Replace( "#pragma multi_compile_fragment POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE", "#pragma multi_compile_fwdadd_fullshadows"); } } //------------------------------------------------------------------------------------------------------------------------------ // Multi Compile private static void ReplaceMultiCompiles(ref StringBuilder sb, PackageVersionInfos version, int indent, bool isDots) { sb.Replace(MULTI_COMPILE_FORWARDADD, GetMultiCompileForwardAdd(version, indent)); sb.Replace(MULTI_COMPILE_FORWARD, GetMultiCompileForward(version, indent)); sb.Replace(MULTI_COMPILE_SHADOWCASTER, GetMultiCompileShadowCaster(version, indent)); sb.Replace(MULTI_COMPILE_DEPTHONLY, GetMultiCompileDepthOnly(version, indent)); sb.Replace(MULTI_COMPILE_DEPTHNORMALS, GetMultiCompileDepthNormals(version, indent)); sb.Replace(MULTI_COMPILE_MOTIONVECTORS, GetMultiCompileMotionVectors(version, indent)); sb.Replace(MULTI_COMPILE_SCENESELECTION, GetMultiCompileSceneSelection(version, indent)); sb.Replace(MULTI_COMPILE_META, GetMultiCompileMeta(version, indent)); sb.Replace(MULTI_COMPILE_INSTANCING, GetMultiCompileInstancingLayer(version, indent, isDots)); } private static void ReplaceMultiCompiles(ref string sb, PackageVersionInfos version, int indent, bool isDots) { sb = sb.Replace(MULTI_COMPILE_FORWARDADD, GetMultiCompileForwardAdd(version, indent)) .Replace(MULTI_COMPILE_FORWARD, GetMultiCompileForward(version, indent)) .Replace(MULTI_COMPILE_SHADOWCASTER, GetMultiCompileShadowCaster(version, indent)) .Replace(MULTI_COMPILE_DEPTHONLY, GetMultiCompileDepthOnly(version, indent)) .Replace(MULTI_COMPILE_DEPTHNORMALS, GetMultiCompileDepthNormals(version, indent)) .Replace(MULTI_COMPILE_MOTIONVECTORS, GetMultiCompileMotionVectors(version, indent)) .Replace(MULTI_COMPILE_SCENESELECTION, GetMultiCompileSceneSelection(version, indent)) .Replace(MULTI_COMPILE_META, GetMultiCompileMeta(version, indent)) .Replace(MULTI_COMPILE_INSTANCING, GetMultiCompileInstancingLayer(version, indent, isDots)); } private static string GetMultiCompileForward(PackageVersionInfos version, int indent) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS", "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE", "#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS", "#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS", "#pragma multi_compile_fragment _ _SHADOWS_SOFT", "#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARD"); } else if(version.RP == lilRenderPipeline.URP) { if(version.Major >= 14) { return GenerateIndentText(indent, "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN", "#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS", "#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS", "#pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING", "#pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION", "#pragma multi_compile_fragment _ _SHADOWS_SOFT", "#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION", "#pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3", "#pragma multi_compile _ _LIGHT_LAYERS", "#pragma multi_compile_fragment _ _LIGHT_COOKIES", "#pragma multi_compile _ _FORWARD_PLUS", "#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING", "#pragma multi_compile _ SHADOWS_SHADOWMASK", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile _ DYNAMICLIGHTMAP_ON", "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARD"); } if(version.Major >= 12) { return GenerateIndentText(indent, "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN", "#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS", "#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS", "#pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING", "#pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION", "#pragma multi_compile_fragment _ _SHADOWS_SOFT", "#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION", "#pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3", "#pragma multi_compile _ _LIGHT_LAYERS", "#pragma multi_compile_fragment _ _LIGHT_COOKIES", "#pragma multi_compile _ _CLUSTERED_RENDERING", "#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING", "#pragma multi_compile _ SHADOWS_SHADOWMASK", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile _ DYNAMICLIGHTMAP_ON", "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARD"); } if(version.Major >= 11) { return GenerateIndentText(indent, "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN", "#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS", "#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS", "#pragma multi_compile_fragment _ _SHADOWS_SOFT", "#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION", "#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING", "#pragma multi_compile _ SHADOWS_SHADOWMASK", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARD"); } if(version.Major >= 10) { return GenerateIndentText(indent, "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS", "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE", "#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS", "#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS", "#pragma multi_compile_fragment _ _SHADOWS_SOFT", "#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION", "#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING", "#pragma multi_compile _ SHADOWS_SHADOWMASK", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARD"); } else { return GenerateIndentText(indent, "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS", "#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE", "#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS", "#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS", "#pragma multi_compile_fragment _ _SHADOWS_SOFT", "#pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARD"); } } else if(version.RP == lilRenderPipeline.HDRP) { if(version.Major >= 12) { return GenerateIndentText(indent, "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ DYNAMICLIGHTMAP_ON", "#pragma multi_compile_fragment _ SHADOWS_SHADOWMASK", "#pragma multi_compile_fragment PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2", "#pragma multi_compile_fragment SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON", "#pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT", "#pragma multi_compile_fragment _ DECAL_SURFACE_GRADIENT", "#pragma multi_compile_fragment SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH SHADOW_VERY_HIGH", "#pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST", "#pragma multi_compile_instancing", "#define SHADERPASS SHADERPASS_FORWARD", "#define HAS_LIGHTLOOP", "#define LIL_PASS_FORWARD"); } if(version.Major >= 10) { return GenerateIndentText(indent, "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ DYNAMICLIGHTMAP_ON", "#pragma multi_compile_fragment _ SHADOWS_SHADOWMASK", "#pragma multi_compile_fragment SCREEN_SPACE_SHADOWS_OFF SCREEN_SPACE_SHADOWS_ON", "#pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT", "#pragma multi_compile_fragment SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH SHADOW_VERY_HIGH", "#pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST", "#pragma multi_compile_instancing", "#define SHADERPASS SHADERPASS_FORWARD", "#define HAS_LIGHTLOOP", "#define LIL_PASS_FORWARD"); } else { return GenerateIndentText(indent, "#pragma multi_compile _ LIGHTMAP_ON", "#pragma multi_compile _ DIRLIGHTMAP_COMBINED", "#pragma multi_compile _ DYNAMICLIGHTMAP_ON", "#pragma multi_compile_fragment _ SHADOWS_SHADOWMASK", "#pragma multi_compile_fragment DECALS_OFF DECALS_3RT DECALS_4RT", "#pragma multi_compile_fragment SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH SHADOW_VERY_HIGH", "#pragma multi_compile_fragment USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST", "#pragma multi_compile_instancing", "#define SHADERPASS SHADERPASS_FORWARD", "#define HAS_LIGHTLOOP", "#define LIL_PASS_FORWARD"); } } else { return GenerateIndentText(indent, "#pragma multi_compile_fwdbase", "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARD"); } } private static string GetMultiCompileForwardAdd(PackageVersionInfos version, int indent) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARDADD"); } else if(version.RP == lilRenderPipeline.URP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARDADD"); } else if(version.RP == lilRenderPipeline.HDRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARDADD"); } else { return GenerateIndentText(indent, "#pragma multi_compile_fragment POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE", "#pragma multi_compile_vertex _ FOG_LINEAR FOG_EXP FOG_EXP2", "#pragma multi_compile_instancing", "#define LIL_PASS_FORWARDADD"); } } private static string GetMultiCompileShadowCaster(PackageVersionInfos version, int indent) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_SHADOWCASTER"); } else if(version.RP == lilRenderPipeline.URP) { if(version.Major >= 11) { return GenerateIndentText(indent, "#pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW", "#pragma multi_compile_instancing", "#define LIL_PASS_SHADOWCASTER"); } else { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_SHADOWCASTER"); } } else if(version.RP == lilRenderPipeline.HDRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define SHADERPASS SHADERPASS_SHADOWS", "#define LIL_PASS_SHADOWCASTER"); } else { return GenerateIndentText(indent, "#pragma multi_compile_shadowcaster", "#pragma multi_compile_instancing", "#define LIL_PASS_SHADOWCASTER"); } } private static string GetMultiCompileDepthOnly(PackageVersionInfos version, int indent) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_DEPTHONLY"); } else if(version.RP == lilRenderPipeline.URP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_DEPTHONLY"); } else if(version.RP == lilRenderPipeline.HDRP) { if(version.Major >= 10) { return GenerateIndentText(indent, "#pragma multi_compile _ WRITE_NORMAL_BUFFER", "#pragma multi_compile_fragment _ WRITE_MSAA_DEPTH", "#pragma multi_compile _ WRITE_DECAL_BUFFER", "#pragma multi_compile_instancing", "#define SHADERPASS SHADERPASS_DEPTH_ONLY", "#define LIL_PASS_DEPTHONLY"); } else { return GenerateIndentText(indent, "#pragma multi_compile _ WRITE_NORMAL_BUFFER", "#pragma multi_compile_fragment _ WRITE_MSAA_DEPTH", "#pragma multi_compile_instancing", "#define SHADERPASS SHADERPASS_DEPTH_ONLY", "#define LIL_PASS_DEPTHONLY"); } } else { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_DEPTHONLY"); } } private static string GetMultiCompileDepthNormals(PackageVersionInfos version, int indent) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_DEPTHNORMALS"); } else if(version.RP == lilRenderPipeline.URP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_DEPTHNORMALS"); } else if(version.RP == lilRenderPipeline.HDRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_DEPTHNORMALS"); } else { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_DEPTHNORMALS"); } } private static string GetMultiCompileMotionVectors(PackageVersionInfos version, int indent) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_MOTIONVECTORS"); } else if(version.RP == lilRenderPipeline.URP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_MOTIONVECTORS"); } else if(version.RP == lilRenderPipeline.HDRP) { if(version.Major >= 10) { return GenerateIndentText(indent, "#pragma multi_compile _ WRITE_NORMAL_BUFFER", "#pragma multi_compile_fragment _ WRITE_MSAA_DEPTH", "#pragma multi_compile _ WRITE_DECAL_BUFFER", "#pragma multi_compile_instancing", "#define SHADERPASS SHADERPASS_MOTION_VECTORS", "#define LIL_PASS_MOTIONVECTORS"); } else { return GenerateIndentText(indent, "#pragma multi_compile _ WRITE_NORMAL_BUFFER", "#pragma multi_compile_fragment _ WRITE_MSAA_DEPTH", "#pragma multi_compile_instancing", "#define SHADERPASS SHADERPASS_MOTION_VECTORS", "#define LIL_PASS_MOTIONVECTORS"); } } else { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_MOTIONVECTORS"); } } private static string GetMultiCompileSceneSelection(PackageVersionInfos version, int indent) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_SCENESELECTION"); } else if(version.RP == lilRenderPipeline.URP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_SCENESELECTION"); } else if(version.RP == lilRenderPipeline.HDRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#pragma editor_sync_compilation", "#define SHADERPASS SHADERPASS_DEPTH_ONLY", "#define SCENESELECTIONPASS", "#define LIL_PASS_SCENESELECTION"); } else { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#define LIL_PASS_SCENESELECTION"); } } private static string GetMultiCompileMeta(PackageVersionInfos version, int indent) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma shader_feature EDITOR_VISUALIZATION", "#define LIL_PASS_META"); } else if(version.RP == lilRenderPipeline.URP) { return GenerateIndentText(indent, "#pragma shader_feature EDITOR_VISUALIZATION", "#define LIL_PASS_META"); } else if(version.RP == lilRenderPipeline.HDRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#pragma shader_feature EDITOR_VISUALIZATION", "#define SHADERPASS SHADERPASS_LIGHT_TRANSPORT", "#define LIL_PASS_META"); } else { return GenerateIndentText(indent, "#pragma shader_feature EDITOR_VISUALIZATION", "#define LIL_PASS_META"); } } private static string GetMultiCompileInstancingLayer(PackageVersionInfos version, int indent, bool isDots = false) { if(version.RP == lilRenderPipeline.LWRP) { return GenerateIndentText(indent, "#pragma multi_compile_instancing"); } else if(version.RP == lilRenderPipeline.URP) { if(version.Major >= 12) { if(isDots) { return GenerateIndentText(indent, "#pragma multi_compile _ DOTS_INSTANCING_ON", "#pragma multi_compile_instancing", "#pragma instancing_options renderinglayer"); } return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#pragma instancing_options renderinglayer"); } else if(version.Major >= 9) { if(isDots) { return GenerateIndentText(indent, "#pragma multi_compile _ DOTS_INSTANCING_ON", "#pragma multi_compile_instancing"); } return GenerateIndentText(indent, "#pragma multi_compile_instancing"); } else { return GenerateIndentText(indent, "#pragma multi_compile_instancing"); } } else if(version.RP == lilRenderPipeline.HDRP) { if(version.Major >= 9 && isDots) { return GenerateIndentText(indent, "#pragma multi_compile _ DOTS_INSTANCING_ON", "#pragma multi_compile_instancing", "#pragma instancing_options renderinglayer"); } return GenerateIndentText(indent, "#pragma multi_compile_instancing", "#pragma instancing_options renderinglayer"); } else { return GenerateIndentText(indent, "#pragma multi_compile_instancing"); } } //------------------------------------------------------------------------------------------------------------------------------ // Skip Variants private static string GetSkipVariantsShadows() { return "#pragma skip_variants SHADOWS_SCREEN _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN _ADDITIONAL_LIGHT_SHADOWS SCREEN_SPACE_SHADOWS_ON SHADOW_LOW SHADOW_MEDIUM SHADOW_HIGH SHADOW_VERY_HIGH"; } private static string GetSkipVariantsLightmaps() { return "#pragma skip_variants LIGHTMAP_ON DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK DIRLIGHTMAP_COMBINED _MIXED_LIGHTING_SUBTRACTIVE"; } private static string GetSkipVariantsDecals() { return "#pragma skip_variants DECALS_OFF DECALS_3RT DECALS_4RT DECAL_SURFACE_GRADIENT _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3"; } private static string GetSkipVariantsAddLight() { //return "#pragma skip_variants VERTEXLIGHT_ON LIGHTPROBE_SH _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS"; return "#pragma skip_variants VERTEXLIGHT_ON LIGHTPROBE_SH"; } private static string GetSkipVariantsAddLightShadows() { return "#pragma skip_variants _ADDITIONAL_LIGHT_SHADOWS"; } private static string GetSkipVariantsProbeVolumes() { return "#pragma skip_variants PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2"; } private static string GetSkipVariantsAO() { return "#pragma skip_variants _SCREEN_SPACE_OCCLUSION"; } private static string GetSkipVariantsLightLists() { return "#pragma skip_variants USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST"; } private static string GetSkipVariantsReflections() { return "#pragma skip_variants _REFLECTION_PROBE_BLENDING _REFLECTION_PROBE_BOX_PROJECTION"; } //------------------------------------------------------------------------------------------------------------------------------ // Avoid Errors public static string BuildShaderSettingString(bool isFile, ref bool useBaseShadow, ref bool useOutlineShadow) { Type type = typeof(lilToonSetting); var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach(var method in methods) { var methodParams = method.GetParameters(); if(method.Name != "BuildShaderSettingString" || methodParams.Length != 3 || methodParams[0].ParameterType != typeof(bool)) continue; var objs = new object[]{isFile,useBaseShadow,useOutlineShadow}; string outstr = (string)method.Invoke(null, objs); useBaseShadow = (bool)objs[1]; useOutlineShadow = (bool)objs[2]; return outstr; } return ""; } private static bool GetBoolField(string name, bool def = false) { var val = GetFieldValue(name); return val == null ? def : (bool)val; } private static string GetStringField(string name) { var val = GetFieldValue(name); return val == null ? "" : (string)val; } private static object GetFieldValue(string name) { Type type = typeof(lilToonSetting); var field = type.GetField(name); if(field == null) return null; lilToonSetting shaderSetting = InitSetting(); if(shaderSetting == null) return null; return field.GetValue(shaderSetting); } private static lilToonSetting InitSetting() { Type type = typeof(lilToonSetting); var method = type.GetMethod("InitializeShaderSetting", BindingFlags.Static | BindingFlags.NonPublic); if(method == null) return null; lilToonSetting shaderSetting = null; var objs = new object[]{shaderSetting}; method.Invoke(null, objs); return (lilToonSetting)objs[0]; } private static void AddDependency(AssetImportContext ctx, string path) { #if UNITY_2018_2_OR_NEWER if(ctx != null) ctx.DependsOnSourceAsset(path); #endif } } } #endif