public static ShaderParsedCombinations ParseShaderCombinations(Shader shader, bool usedBySceneOnly) { if (shader == null || !ShaderUtils.HasCodeSnippets(shader)) { return(null); } var assetPath = AssetDatabase.GetAssetPath(shader); var deps = AssetDatabase.GetDependencies(assetPath); long lastWriteTime = 0; for (int i = 0; i < deps.Length; ++i) { var fi = new FileInfo(deps[i]); if (fi.Exists) { if (fi.LastWriteTime.ToFileTime() > lastWriteTime) { lastWriteTime = fi.LastWriteTime.ToFileTime(); } } } ShaderParsedCombinationsItem item; if (s_ShaderParsedCombinationsCache.TryGetValue(shader, out item)) { if (item.lastWriteTime != lastWriteTime) { s_ShaderParsedCombinationsCache.Remove(shader); } else { return(item.data); } } ShaderParsedCombinations result = null; try { var fixedShaderName = shader.name.Replace('/', '-'); var combFilePath = String.Format("{0}/ParsedCombinations-{1}.shader", GetProjectUnityTempPath(), fixedShaderName); if (File.Exists(combFilePath)) { File.Delete(combFilePath); } Func <String, String[]> keywordsSpliter = src => { var srcKeywords = src.Split(' '); var dstKeywords = new List <String>(); for (int j = 0; j < srcKeywords.Length; ++j) { var x = srcKeywords[j].Trim(); if (!String.IsNullOrEmpty(x) && !dstKeywords.Contains(x)) { dstKeywords.Add(x); } } if (dstKeywords.Count > 0) { return(dstKeywords.ToArray()); } return(null); }; ShaderUtils.OpenShaderCombinations(shader, true); if (File.Exists(combFilePath)) { var lines = File.ReadAllLines(combFilePath); ShaderParsedCombinations.Snippet curSnippet = null; for (int i = 0; i < lines.Length; ++i) { var line = lines[i]; if (String.IsNullOrEmpty(line) || Char.IsWhiteSpace(line[0])) { continue; } Match match = ShaderParsedCombinations.REG_FILE_HEADER.Match(line); if (match.Success) { if (match.Groups.Count > 1) { int num; if (int.TryParse(match.Groups[1].Value, out num) && num > 0) { result = new ShaderParsedCombinations(); result.shader = shader; result.snippets = new List <ShaderParsedCombinations.Snippet>(num); } } } else if (result != null && (match = ShaderParsedCombinations.REG_SNIPPET_ID.Match(line)).Success) { if (match.Groups.Count > 2) { int id; if (int.TryParse(match.Groups[1].Value, out id)) { int bits; if (int.TryParse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber, null, out bits)) { var snippet = new ShaderParsedCombinations.Snippet(); curSnippet = snippet; snippet.id = id; snippet.platformBits = bits; result.snippets.Add(snippet); } } } } else if (curSnippet != null && (match = ShaderParsedCombinations.REG_SHADER_FEATURE_KEYWORDS.Match(line)).Success) { if (match.Groups.Count > 1) { var keywords = keywordsSpliter(match.Groups[1].Value); if (keywords != null) { curSnippet.shader_features = keywords; } } } else if (curSnippet != null && (match = ShaderParsedCombinations.REG_MULTI_COMPILE_KEYWORDS.Match(line)).Success) { if (match.Groups.Count > 1) { var keywords = keywordsSpliter(match.Groups[1].Value); if (keywords != null) { curSnippet.multi_compiles = keywords; } } } else if (curSnippet != null && (match = ShaderParsedCombinations.REG_BUILTIN_KEYWORDS.Match(line)).Success) { if (match.Groups.Count > 1) { var keywords = keywordsSpliter(match.Groups[1].Value); if (keywords != null) { curSnippet.builtins = keywords; } } } else if (curSnippet != null && (match = ShaderParsedCombinations.REG_VARIANTS_NUM.Match(line)).Success) { if (match.Groups.Count > 1) { int num; if (int.TryParse(match.Groups[1].Value, out num) && num > 0) { curSnippet.variants = new List <String[]>(num); } } } else if (curSnippet != null && line.StartsWith(ShaderParsedCombinations.TAG_NO_KEYWORDS_DEFINED)) { if (curSnippet.variants != null) { curSnippet.variants = null; } } else if (curSnippet != null && curSnippet.variants != null) { var keywords = keywordsSpliter(line); if (keywords != null) { curSnippet.variants.Add(keywords); } } } } } catch (Exception e) { Debug.LogException(e); } s_ShaderParsedCombinationsCache.Add(shader, new ShaderParsedCombinationsItem { data = result, lastWriteTime = lastWriteTime }); return(result); }