public void AddKeywordsByName(string[] names) { bool changes = false; for (int k = 0; k < names.Length; k++) { int kwCount = keywords.Count; bool repeated = false; for (int j = 0; j < kwCount; j++) { if (keywords[j].name.Equals(names[k])) { repeated = true; break; } } if (repeated) { continue; } StripKeyword keyword = new StripKeyword(names[k]); keywords.Add(keyword); changes = true; } if (changes) { keywords.Sort(delegate(StripKeyword k1, StripKeyword k2) { return(k1.name.CompareTo(k2.name)); }); } }
public void Add(StripKeyword keyword) { if (GetKeyword(keyword.name) != null) { return; } // 忽略下划线__ bool goodKeyword = false; for (int k = 0; k < keyword.name.Length; k++) { if (keyword.name[k] != '_') { goodKeyword = true; break; } } if (goodKeyword) { keywords.Add(keyword); } else { keyword.isUnderscoreKeyword = true; hasUnderStriporeVariant = true; } }
public override bool Equals(object obj) { if (obj is StripKeyword) { StripKeyword other = (StripKeyword)obj; return(name.Equals(other.name)); } return(false); }
public void SetKeywords(string[] names) { for (int k = 0; k < names.Length; k++) { if (!keywordSet.Contains(names[k])) { keywordSet.Add(names[k]); StripKeyword keyword = new StripKeyword(names[k]); keywords.Add(keyword); } } keywords.Sort(delegate(StripKeyword k1, StripKeyword k2) { return(k1.name.CompareTo(k2.name)); }); }
public StripKeyword GetKeyword(string name) { int kc = keywords.Count; for (int k = 0; k < kc; k++) { StripKeyword keyword = keywords[k]; if (keyword.name.Equals(name)) { return(keyword); } } return(null); }
public void RemoveKeyword(string name) { for (int k = 0; k < keywords.Count; k++) { StripKeyword keyword = keywords[k]; if (keyword.name.Equals(name)) { if (keyword.enabled) { keywordEnabledCount--; } keywords.Remove(keyword); return; } } }
void UpdateKeywords() { for (int i = 0; i < passes.Count; i++) { StripShaderPass pass = passes[i]; for (int l = 0; l < pass.keywordLines.Count; l++) { StripKeywordLine line = pass.keywordLines[l]; for (int k = 0; k < line.keywords.Count; k++) { StripKeyword keyword = line.keywords[k]; if (!keywords.Contains(keyword)) { keywords.Add(keyword); } } } } }
public static void ScanShader(ref StripShader shader) { //重置shader shader.passes.Clear(); shader.keywords.Clear(); shader.hasBackup = File.Exists(shader.path + BACKUP_SUFFIX); shader.pendingChanges = false; shader.editedByShaderControl = false; //读取shader文本 string[] shaderLines = File.ReadAllLines(shader.path); string[] separator = new string[] { " " }; StripShaderPass currentPass = new StripShaderPass(); StripShaderPass basePass = null; int pragmaControl = 0; int pass = -1; bool blockComment = false; StripKeywordLine keywordLine = new StripKeywordLine(); 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 StripShaderPass(); 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; // 跳过注释 } //添加 multicompile bool isShaderFeature = false; j = line.IndexOf(PRAGMA_MULTICOMPILE); if (j < 0) { j = line.IndexOf(PRAGMA_SHADER_FEATURE); isShaderFeature = (j >= 0); } if (j >= 0) { if (pragmaControl != 2) { keywordLine = new StripKeywordLine(); } keywordLine.isFeature = isShaderFeature; // 处理在#pragram行中潜在的注释 int lastStringPos = line.IndexOf("//", j + 22); if (lastStringPos < 0) { lastStringPos = line.Length; } int length = lastStringPos - j - 22; string[] kk = line.Substring(j + 22, length).Split(separator, StringSplitOptions.RemoveEmptyEntries); // 清理关键字 trim for (int i = 0; i < kk.Length; i++) { kk [i] = kk [i].Trim(); } // 操作关键字 switch (pragmaControl) { case 1: // 如果是被编辑器修改的 shader.editedByShaderControl = true; // 在这行添加原始关键字 for (int s = 0; s < kk.Length; s++) { keywordLine.Add(shader.GetKeyword(kk [s])); } pragmaControl = 2; break; case 2: // 检查使用的关键字 keywordLine.DisableKeywords(); for (int s = 0; s < kk.Length; s++) { StripKeyword keyword = keywordLine.GetKeyword(kk [s]); if (keyword != null) { keyword.enabled = true; } } currentPass.Add(keywordLine); pragmaControl = 0; break; case 3: // 被编辑器关闭的关键字 shader.editedByShaderControl = true; // // 在这行添加原始的关键字 for (int s = 0; s < kk.Length; s++) { StripKeyword keyword = shader.GetKeyword(kk [s]); keyword.enabled = false; keywordLine.Add(keyword); } currentPass.Add(keywordLine); pragmaControl = 0; break; case 0: // 在这行添加关键字 for (int s = 0; s < kk.Length; s++) { keywordLine.Add(shader.GetKeyword(kk [s])); } currentPass.Add(keywordLine); break; } } //PRAGMA_MULTI_COMPILE_FWDBASE j = line.IndexOf(PRAGMA_MULTI_COMPILE_FWDBASE_FULLSHADOWS); if (j >= 0) { } } currentPass.pass = Mathf.Max(pass, 0); if (basePass != null) { currentPass.Add(basePass.keywordLines); } shader.Add(currentPass); shader.UpdateVariantCount(); }
//更新变体数量 可以通过变体公式计算 另外是否可通过编译出的文件计算? public void UpdateVariantCount() { totalVariantCount = 0; actualBuildVariantCount = 0; //遍历pass for (int i = 0; i < passes.Count; i++) { StripShaderPass pass = passes[i]; int matCount = materials.Count; int pasStripCount = 1; int passBuildCount = 1; //遍历编译指令行 for (int l = 0; l < pass.keywordLines.Count; l++) { StripKeywordLine line = pass.keywordLines[l]; //kLineEnabledCount 所有enable的keyword 有没有 _ int kLineEnabledCount = line.hasUnderStriporeVariant ? 1 : 0; //line.keywords 里不包含 __ 有_ 关键字+1 int kLineCount = kLineEnabledCount; //如果是 缩写的关键字 if (ShaderHelper.IsBuiltinShortcut(line.shaderLineType)) { StripKeyword[] stripKeyword = null; if (pass.hasSkipKeyword) { stripKeyword = pass.skipKeywords.ToArray(); } kLineCount += ShaderHelper.GetShortcutVariantCount(line.shaderLineType, stripKeyword); } //multi_compile shader_fearure 要除去skip else if (ShaderHelper.IsInputShortcut(line.shaderLineType) && line.shaderLineType != ShaderLineType.SKIP_VARIANTS) { if (ShaderHelper.IsSahderFeature(line.shaderLineType) && line.keywords.Count == 1) { kLineCount += 2; } else { kLineCount += line.keywords.Count; } } for (int k = 0; k < line.keywords.Count; k++) { StripKeyword keyword = line.keywords[k]; if (keyword.enabled) { //如果是 shader feature检查是否有材质使用 if (ShaderHelper.IsBuiltinShortcut(line.shaderLineType) || ShaderHelper.IsSahderFeature(line.shaderLineType)) { for (int m = 0; m < matCount; m++) { //遍历关联的材质 if (materials[m].ContainsKeyword(keyword.name)) { kLineEnabledCount++; break; } } } else { kLineEnabledCount++; } } } //实际使用的关键字 if (kLineEnabledCount > 0) { //实际使用的参与编译的 指令行的指令乘积 passBuildCount *= kLineEnabledCount; } //全部编译指令行的指令乘积 包括没有使用的fearure pasStripCount *= kLineCount; } totalVariantCount += pasStripCount; actualBuildVariantCount += passBuildCount; } //计算enabed关键字数量 keywordEnabledCount = 0; int keywordCount = keywords.Count; for (int k = 0; k < keywordCount; k++) { if (keywords[k].enabled) { keywordEnabledCount++; } } }
//解析shader文本 public static void ScanShader(ref StripShader shader) { //重置shader shader.passes.Clear(); shader.keywords.Clear(); shader.hasBackup = File.Exists(shader.path + BACKUP_SUFFIX); shader.pendingChanges = false; shader.editedByShaderControl = false; //读取shader文本 string[] shaderLines = File.ReadAllLines(shader.path); string[] separator = new string[] { " " }; StripShaderPass currentPass = new StripShaderPass(); StripShaderPass basePass = null; int pass = -1; bool blockComment = false; StripKeywordLine keywordLine = new StripKeywordLine(); for (int k = 0; k < shaderLines.Length; k++) { //删除字符串头部和尾部的空格 string line = shaderLines[k].Trim(); if (line.Length == 0) { continue; } //是否是注释行 IsBlockCommentLine(line, ref blockComment); 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 StripShaderPass(); pass++; continue; } //第一个注释符号 //的位置 int lineCommentIndex = CommentLineIndex(line); //编辑器添加的语句行信息 EditorLineType editorLine = EditorLineType.NONE; int editorStartIndex = -1; int editorEndIndex = -1; ParseEditorLineType(line, ref editorLine, ref editorStartIndex, ref editorEndIndex); //该行是注释行 并且不是被主动编辑的 跳过 if (lineCommentIndex == 0 && editorLine == EditorLineType.NONE) { continue; // 跳过注释 } //shader关键字语句行信息 ShaderLineType shaderLine = ShaderLineType.NONE; int keyStartIndex = -1; int keyEndIndex = -1; ParseShaderLineType(line, ref shaderLine, ref keyStartIndex, ref keyEndIndex); //并非是被程序编辑过的 if (editorLine == EditorLineType.NONE) { //如果是手写输入的关键字 if (IsInputShortcut(shaderLine)) { keyStartIndex = Mathf.Max(0, keyStartIndex); keyEndIndex = Mathf.Max(0, keyEndIndex); //检查PRAGMA 关键字之后的字符串是否包含注释 int commentindex = CommentLineIndex(line, keyStartIndex + keyEndIndex); if (commentindex < 0) { commentindex = line.Length; } int length = commentindex - (keyStartIndex + keyEndIndex); //用空格分割 PRAGMA语句到//注释符号之间的语句 string[] splitedKeys = line.Substring(keyStartIndex + keyEndIndex, length).Split(separator, StringSplitOptions.RemoveEmptyEntries); if (splitedKeys.Length > 0) { keywordLine = new StripKeywordLine(); //是剔除字段 bool isSkip = shaderLine == ShaderLineType.SKIP_VARIANTS; currentPass.hasSkipKeyword = isSkip?isSkip:currentPass.hasSkipKeyword; //添加手写关键字 for (int i = 0; i < splitedKeys.Length; i++) { splitedKeys[i] = splitedKeys[i].Trim(); StripKeyword keyword = keywordLine.GetKeyword(splitedKeys[i]); if (keyword == null) { keyword = new StripKeyword(splitedKeys[i]); } keyword.enabled = true; keyword.isSkip = isSkip; keywordLine.Add(keyword); } keywordLine.editorLineType = editorLine; keywordLine.shaderLineType = shaderLine; currentPass.Add(keywordLine); } } else //添加缩写marco的内置关键字 if (IsBuiltinShortcut(shaderLine)) { keywordLine = new StripKeywordLine(); string[] buildinkeys = GetShortcutKeywords(shaderLine); for (int i = 0; i < buildinkeys.Length; i++) { StripKeyword keyword = keywordLine.GetKeyword(buildinkeys[i]); if (keyword == null) { keyword = new StripKeyword(buildinkeys[i]); } keyword.enabled = true; keyword.isSkip = false; keywordLine.Add(keyword); } keywordLine.editorLineType = editorLine; keywordLine.shaderLineType = shaderLine; currentPass.Add(keywordLine); } } } currentPass.pass = Mathf.Max(pass, 0); if (basePass != null) { currentPass.Add(basePass.keywordLines); } shader.Add(currentPass); shader.UpdateVariantCount(); }