public void UpdateVariantCount() { totalVariantCount = 0; actualBuildVariantCount = 0; passes.ForEach((SCShaderPass pass) => { int matCount = materials.Count; int passCount = 1; int passBuildCount = 1; for (int l = 0; l < pass.keywordLines.Count; l++) { SCKeywordLine line = pass.keywordLines[l]; int kLineEnabledCount = line.hasUnderscoreVariant ? 1 : 0; int kLineCount = kLineEnabledCount + line.keywords.Count; for (int k = 0; k < line.keywords.Count; k++) { SCKeyword keyword = line.keywords[k]; if (keyword.enabled) { // if this is a shader feature, check if there's at least one material using it if (line.pragmaType == PragmaType.FeatureGlobal || line.pragmaType == PragmaType.FeatureLocal) { for (int m = 0; m < matCount; m++) { if (materials[m].ContainsKeyword(keyword.name)) { kLineEnabledCount++; break; } } } else { kLineEnabledCount++; } } } if (kLineEnabledCount > 0) { passBuildCount *= kLineEnabledCount; } passCount *= kLineCount; } totalVariantCount += passCount; actualBuildVariantCount += passBuildCount; }); keywordEnabledCount = 0; int keywordCount = keywords.Count; for (int k = 0; k < keywordCount; k++) { if (keywords[k].enabled) { keywordEnabledCount++; } } }
void ScanShaderGraph(SCShader shader) { shader.editedByShaderControl = File.Exists(shader.path + BACKUP_SUFFIX); // Reads shader string shaderContents = File.ReadAllText(shader.path, Encoding.UTF8); shaderContents = shaderContents.Replace("UnityEditor.ShaderGraph.ShaderKeyword", "ShaderControl.SCWindow.SerializedKeyword"); ShaderGraphProxy graph = JsonUtility.FromJson <ShaderGraphProxy>(shaderContents); SCShaderPass currentPass = new SCShaderPass(); if (graph.m_SerializedKeywords != null) { for (int k = 0; k < graph.m_SerializedKeywords.Length; k++) { SerializedKeywordData skw = graph.m_SerializedKeywords[k]; if (string.IsNullOrEmpty(skw.JSONnodeData)) { continue; } SerializedKeywordProxy kw = JsonUtility.FromJson <SerializedKeywordProxy>(skw.JSONnodeData); PragmaType pragmaType = PragmaType.Unknown; if (kw.m_KeywordDefinition == SHADER_GRAPH_KEYWORD_DEFINITION_MULTI_COMPILE && kw.m_KeywordScope == SHADER_GRAPH_KEYWORD_SCOPE_GLOBAL) { pragmaType = PragmaType.MultiCompileGlobal; } else if (kw.m_KeywordDefinition == SHADER_GRAPH_KEYWORD_DEFINITION_MULTI_COMPILE && kw.m_KeywordScope == SHADER_GRAPH_KEYWORD_SCOPE_LOCAL) { pragmaType = PragmaType.MultiCompileLocal; } else if (kw.m_KeywordDefinition == SHADER_GRAPH_KEYWORD_DEFINITION_SHADER_FEATURE && kw.m_KeywordScope == SHADER_GRAPH_KEYWORD_SCOPE_GLOBAL) { pragmaType = PragmaType.FeatureGlobal; } else if (kw.m_KeywordDefinition == SHADER_GRAPH_KEYWORD_DEFINITION_SHADER_FEATURE && kw.m_KeywordScope == SHADER_GRAPH_KEYWORD_SCOPE_LOCAL) { pragmaType = PragmaType.FeatureLocal; } SCKeywordLine keywordLine = new SCKeywordLine(); keywordLine.pragmaType = pragmaType; SCKeyword keyword = new SCKeyword(kw.m_DefaultReferenceName, kw.m_Name); keywordLine.Add(keyword); currentPass.Add(keywordLine); } } shader.Add(currentPass); shader.UpdateVariantCount(); }
void UpdateKeywords() { passes.ForEach((SCShaderPass pass) => { for (int l = 0; l < pass.keywordLines.Count; l++) { SCKeywordLine line = pass.keywordLines [l]; for (int k = 0; k < line.keywords.Count; k++) { SCKeyword keyword = line.keywords [k]; if (!keywords.Contains(keyword)) { keywords.Add(keyword); } } } }); }
void UpdateShaderNonGraph(SCShader shader) { // Reads and updates shader from disk string[] shaderLines = File.ReadAllLines(shader.path); string[] separator = new string[] { " " }; StringBuilder sb = new StringBuilder(); int pragmaControl = 0; shader.editedByShaderControl = false; SCKeywordLine keywordLine = new SCKeywordLine(); bool blockComment = false; for (int k = 0; k < shaderLines.Length; k++) { int lineCommentIndex = shaderLines[k].IndexOf("//"); int blocCommentIndex = shaderLines[k].IndexOf("/*"); int endCommentIndex = shaderLines[k].IndexOf("*/"); if (blocCommentIndex > 0 && (lineCommentIndex > blocCommentIndex || lineCommentIndex < 0)) { blockComment = true; } if (endCommentIndex > blocCommentIndex && (lineCommentIndex > endCommentIndex || lineCommentIndex < 0)) { blockComment = false; } int j = -1; PragmaType pragmaType = PragmaType.Unknown; if (!blockComment) { j = shaderLines[k].IndexOf(PRAGMA_COMMENT_MARK); if (j >= 0) { pragmaControl = 1; } j = shaderLines[k].IndexOf(SCKeywordLine.PRAGMA_MULTICOMPILE_GLOBAL); if (j >= 0) { pragmaType = PragmaType.MultiCompileGlobal; } else { j = shaderLines[k].IndexOf(SCKeywordLine.PRAGMA_FEATURE_GLOBAL); if (j >= 0) { pragmaType = PragmaType.FeatureGlobal; } else { j = shaderLines[k].IndexOf(SCKeywordLine.PRAGMA_MULTICOMPILE_LOCAL); if (j >= 0) { pragmaType = PragmaType.MultiCompileLocal; } else { j = shaderLines[k].IndexOf(SCKeywordLine.PRAGMA_FEATURE_LOCAL); if (j >= 0) { pragmaType = PragmaType.FeatureLocal; } } } } if (pragmaControl != 1 && lineCommentIndex == 0 && shaderLines[k].IndexOf(PRAGMA_DISABLED_MARK) < 0) { // do not process a commented line j = -1; } } if (j >= 0) { if (pragmaControl != 2) { keywordLine.Clear(); } keywordLine.pragmaType = pragmaType; j = shaderLines[k].IndexOf(' ', j + 20) + 1; // first space after pragma declaration if (j >= shaderLines[k].Length) { continue; } // exclude potential comments inside the #pragma line int lastStringPos = shaderLines[k].IndexOf("//", j); if (lastStringPos < 0) { lastStringPos = shaderLines[k].Length; } int length = lastStringPos - j; string[] kk = shaderLines[k].Substring(j, length).Split(separator, StringSplitOptions.RemoveEmptyEntries); // Sanitize keywords for (int i = 0; i < kk.Length; i++) { kk[i] = kk[i].Trim(); } // Act on keywords switch (pragmaControl) { case 1: // Read original keywords for (int s = 0; s < kk.Length; s++) { SCKeyword keyword = shader.GetKeyword(kk[s]); keywordLine.Add(keyword); } pragmaControl = 2; break; case 0: case 2: if (pragmaControl == 0) { for (int s = 0; s < kk.Length; s++) { SCKeyword keyword = shader.GetKeyword(kk[s]); keywordLine.Add(keyword); } } int kCount = keywordLine.keywordCount; int kEnabledCount = keywordLine.keywordsEnabledCount; if (kEnabledCount < kCount) { // write original keywords if (kEnabledCount == 0) { sb.Append(PRAGMA_DISABLED_MARK); } else { sb.Append(PRAGMA_COMMENT_MARK); } shader.editedByShaderControl = true; sb.Append(keywordLine.GetPragma()); if (keywordLine.hasUnderscoreVariant) { sb.Append(PRAGMA_UNDERSCORE); } for (int s = 0; s < kCount; s++) { SCKeyword keyword = keywordLine.keywords[s]; sb.Append(keyword.name); if (s < kCount - 1) { sb.Append(" "); } } sb.AppendLine(); } if (kEnabledCount > 0) { // Write actual keywords sb.Append(keywordLine.GetPragma()); if (keywordLine.hasUnderscoreVariant) { sb.Append(PRAGMA_UNDERSCORE); } for (int s = 0; s < kCount; s++) { SCKeyword keyword = keywordLine.keywords[s]; if (keyword.enabled) { sb.Append(keyword.name); if (s < kCount - 1) { sb.Append(" "); } } } sb.AppendLine(); } pragmaControl = 0; break; } } else { sb.AppendLine(shaderLines[k]); } } // Writes modified shader File.WriteAllText(shader.path, sb.ToString()); AssetDatabase.Refresh(); }
void ScanShaderNonGraph(SCShader shader) { // Reads shader string[] shaderLines = File.ReadAllLines(shader.path); string[] separator = new string[] { " " }; SCShaderPass currentPass = new SCShaderPass(); SCShaderPass basePass = null; int pragmaControl = 0; int pass = -1; bool blockComment = false; SCKeywordLine keywordLine = new SCKeywordLine(); for (int k = 0; k < shaderLines.Length; k++) { string line = shaderLines[k].Trim(); if (line.Length == 0) { continue; } int lineCommentIndex = line.IndexOf("//"); int blocCommentIndex = line.IndexOf("/*"); int endCommentIndex = line.IndexOf("*/"); if (blocCommentIndex > 0 && (lineCommentIndex > blocCommentIndex || lineCommentIndex < 0)) { blockComment = true; } if (endCommentIndex > blocCommentIndex && (lineCommentIndex > endCommentIndex || lineCommentIndex < 0)) { blockComment = false; } if (blockComment) { continue; } string lineUPPER = line.ToUpper(); if (lineUPPER.Equals("PASS") || lineUPPER.StartsWith("PASS ")) { if (pass >= 0) { currentPass.pass = pass; if (basePass != null) { currentPass.Add(basePass.keywordLines); } shader.Add(currentPass); } else if (currentPass.keywordCount > 0) { basePass = currentPass; } currentPass = new SCShaderPass(); pass++; continue; } int j = line.IndexOf(PRAGMA_COMMENT_MARK); if (j >= 0) { pragmaControl = 1; } else { j = line.IndexOf(PRAGMA_DISABLED_MARK); if (j >= 0) { pragmaControl = 3; } } if (lineCommentIndex == 0 && pragmaControl != 1 && pragmaControl != 3) { continue; // do not process lines commented by user } PragmaType pragmaType = PragmaType.Unknown; int offset = 0; j = line.IndexOf(SCKeywordLine.PRAGMA_MULTICOMPILE_GLOBAL); if (j >= 0) { pragmaType = PragmaType.MultiCompileGlobal; offset = SCKeywordLine.PRAGMA_MULTICOMPILE_GLOBAL.Length; } else { j = line.IndexOf(SCKeywordLine.PRAGMA_FEATURE_GLOBAL); if (j >= 0) { pragmaType = PragmaType.FeatureGlobal; offset = SCKeywordLine.PRAGMA_FEATURE_GLOBAL.Length; } else { j = line.IndexOf(SCKeywordLine.PRAGMA_MULTICOMPILE_LOCAL); if (j >= 0) { pragmaType = PragmaType.MultiCompileLocal; offset = SCKeywordLine.PRAGMA_MULTICOMPILE_LOCAL.Length; } else { j = line.IndexOf(SCKeywordLine.PRAGMA_FEATURE_LOCAL); if (j >= 0) { pragmaType = PragmaType.FeatureLocal; offset = SCKeywordLine.PRAGMA_FEATURE_LOCAL.Length; } } } } if (j >= 0) { if (pragmaControl != 2) { keywordLine = new SCKeywordLine(); } keywordLine.pragmaType = pragmaType; // exclude potential comments inside the #pragma line int lastStringPos = line.IndexOf("//", j + offset); if (lastStringPos < 0) { lastStringPos = line.Length; } int length = lastStringPos - j - offset; string[] kk = line.Substring(j + offset, length).Split(separator, StringSplitOptions.RemoveEmptyEntries); // Sanitize keywords for (int i = 0; i < kk.Length; i++) { kk[i] = kk[i].Trim(); } // Act on keywords switch (pragmaControl) { case 1: // Edited by Shader Control line shader.editedByShaderControl = true; // Add original keywords to current line for (int s = 0; s < kk.Length; s++) { keywordLine.Add(shader.GetKeyword(kk[s])); } pragmaControl = 2; break; case 2: // check enabled keywords keywordLine.DisableKeywords(); for (int s = 0; s < kk.Length; s++) { SCKeyword keyword = keywordLine.GetKeyword(kk[s]); if (keyword != null) { keyword.enabled = true; } } currentPass.Add(keywordLine); pragmaControl = 0; break; case 3: // disabled by Shader Control line shader.editedByShaderControl = true; // Add original keywords to current line for (int s = 0; s < kk.Length; s++) { SCKeyword keyword = shader.GetKeyword(kk[s]); keyword.enabled = false; keywordLine.Add(keyword); } currentPass.Add(keywordLine); pragmaControl = 0; break; case 0: // Add keywords to current line for (int s = 0; s < kk.Length; s++) { keywordLine.Add(shader.GetKeyword(kk[s])); } currentPass.Add(keywordLine); break; } } } currentPass.pass = Mathf.Max(pass, 0); if (basePass != null) { currentPass.Add(basePass.keywordLines); } shader.Add(currentPass); shader.UpdateVariantCount(); }
public void Add(SCKeywordLine keywordLine) { keywordLines.Add(keywordLine); UpdateKeywordCount(); }
public void UpdateVariantCount() { totalVariantCount = 0; actualBuildVariantCount = 0; passes.ForEach((SCShaderPass pass) => { int matCount = materials.Count; int passCount = 1; int passBuildCount = 1; for (int l = 0; l < pass.keywordLines.Count; l++) { SCKeywordLine line = pass.keywordLines [l]; int kLineEnabledCount = line.hasUnderscoreVariant ? 1 : 0; int kLineCount = kLineEnabledCount + line.keywords.Count; for (int k = 0; k < line.keywords.Count; k++) { SCKeyword keyword = line.keywords [k]; if (keyword.enabled) { // if this is a shader feature, check if there's at least one material using it if (line.isFeature) { for (int m = 0; m < matCount; m++) { if (materials[m].ContainsKeyword(keyword.name)) { kLineEnabledCount++; break; } } } else { kLineEnabledCount++; } } } if (kLineEnabledCount > 0) { passBuildCount *= kLineEnabledCount; } passCount *= kLineCount; } totalVariantCount += passCount; actualBuildVariantCount += passBuildCount; }); keywordEnabledCount = 0; int keywordCount = keywords.Count; for (int k = 0; k < keywordCount; k++) { if (keywords [k].enabled) { keywordEnabledCount++; } } // add keywords from materials if there're any // HashSet<string>kk = new HashSet<string>(); // keywords.ForEach(kw => {kk.Add(kw.name);}); // int materialsCount = materials.Count; // for (int m=0;m<materialsCount;m++) { // SCMaterial material = materials[m]; // keywordCount = material.keywords.Count; // for (int k=0; k<keywordCount; k++) { // SCKeyword keyword = material.keywords[k]; // if (keyword.enabled && !kk.Contains(keyword.name)) { // kk.Add (keyword.name); // keywordEnabledCount++; // } // } // } }