예제 #1
0
    public static void UpdateShader(ref StripShader shader)
    {
        if (shader.isReadOnly)
        {
            EditorUtility.DisplayDialog("Locked file", "Shader file " + shader.name + " is read-only.", "Ok");
            return;
        }
        try
        {
            // Create backup
            string backupPath = shader.path + BACKUP_SUFFIX;
            if (!File.Exists(backupPath))
            {
                AssetDatabase.CopyAsset(shader.path, backupPath);
                shader.hasBackup = true;
            }

            // Reads and updates shader from disk
            // string[] shaderLines = File.ReadAllLines(shader.path);
            //string[] separator = new string[] { " " };

            // Writes modified shader
            //File.WriteAllText(shader.path, sb.ToString());
            AssetDatabase.Refresh();
        }
        catch (Exception ex)
        {
            Debug.LogError("Unexpected exception caught while updating shader: " + ex.Message);
        }
    }
예제 #2
0
 public static void RestoreShader(ref StripShader shader)
 {
     try
     {
         string shaderBackupPath = shader.path + BACKUP_SUFFIX;
         if (!File.Exists(shaderBackupPath))
         {
             EditorUtility.DisplayDialog("Restore shader", "Shader backup is missing!", "OK");
             return;
         }
         File.Copy(shaderBackupPath, shader.path, true);
         File.Delete(shaderBackupPath);
         if (File.Exists(shaderBackupPath + ".meta"))
         {
             File.Delete(shaderBackupPath + ".meta");
         }
         AssetDatabase.Refresh();
     }
     catch (Exception ex)
     {
         Debug.LogError("Unexpected exception caught while restoring shader: " + ex.Message);
     }
 }
예제 #3
0
    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();
    }
예제 #4
0
    //解析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();
    }