コード例 #1
0
        private static void UnityLogFormat(LogType type, Object context, string tag, string format, params object[] args)
        {
            try
            {
                switch (type)
                {
                case LogType.Log:
                {
                    Debug.LogFormat(context, string.Concat(tag, ":", format), args);
                    break;
                }

                case LogType.Warning:
                {
                    Debug.LogWarningFormat(context, string.Concat(tag, ":", format), args);
                    break;
                }

                case LogType.Error:
                {
                    Debug.LogErrorFormat(context, string.Concat(tag, ":", format), args);
                    break;
                }

                case LogType.Assert:
                {
                    Debug.AssertFormat(context, string.Concat(tag, ":", format), args);
                    break;
                }

                default:
                {
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                DebugUtility.LogError(LoggerTags.Engine, "The formatting-string or argument is abnormal.");
                DebugUtility.LogException(ex);
            }
        }
コード例 #2
0
 public void MergeAllShaderKeywords()
 {
     if (combinations.snippets != null)
     {
         var count = combinations.snippets.Count;
         for (int i = 0; i < count; ++i)
         {
             var snippet = combinations.snippets[i];
             if (snippet.builtins != null)
             {
                 foreach (var k in snippet.builtins)
                 {
                     builtins = builtins ?? new HashSet <String>();
                     builtins.Add(k);
                 }
             }
             if (snippet.multi_compiles != null)
             {
                 foreach (var k in snippet.multi_compiles)
                 {
                     multi_compiles = multi_compiles ?? new HashSet <String>();
                     multi_compiles.Add(k);
                 }
             }
             if (snippet.shader_features != null)
             {
                 foreach (var k in snippet.shader_features)
                 {
                     shader_features = shader_features ?? new HashSet <String>();
                     shader_features.Add(k);
                 }
             }
             if (shader_features != null && multi_compiles != null)
             {
                 Debug.AssertFormat(!shader_features.Overlaps(multi_compiles),
                                    String.Format("shader_features.Overlaps( multi_compiles ) == false, {0}", combinations.shader.name));
             }
         }
     }
 }
コード例 #3
0
 public static void AssertFormat(bool condition, UnityObject context, string format, params object[] args)
 {
     UnityDebug.AssertFormat(condition, context, format, args);
 }
コード例 #4
0
        public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList <ShaderCompilerData> data)
        {
            if (snippet.passType == PassType.ForwardAdd ||
                snippet.passType == PassType.LightPrePassBase ||
                snippet.passType == PassType.LightPrePassFinal ||
                snippet.passType == PassType.Deferred ||
                snippet.passType == PassType.ScriptableRenderPipeline ||
                snippet.passType == PassType.ScriptableRenderPipelineDefaultUnlit ||
                snippet.passType == PassType.Meta ||
                snippet.passType == PassType.MotionVectors)
            {
                data.Clear();
                return;
            }
            var shaderPath = AssetDatabase.GetAssetPath(shader);

            if (EditorUtils.IsUnityDefaultResource(shaderPath))
            {
                return;
            }
            var checkPass  = false;
            var shaderData = ShaderUtil.GetShaderData(shader);

            for (int k = 0; k < shaderData.SubshaderCount; ++k)
            {
                var subShader = shaderData.GetSubshader(k);
                for (int i = 0; i < subShader.PassCount; ++i)
                {
                    var pass = subShader.GetPass(i);
                    if (String.Equals(pass.Name, snippet.passName))
                    {
                        checkPass = true;
                        goto END_PASSCHECK;
                    }
                }
            }
END_PASSCHECK:
            if (!checkPass)
            {
                // snippet 指的是一段可以被编译Shader代码
                // 传入的shader必然含有可编译代码,如果在当前Shader中未找到对应pass,跳过...
                Debug.AssertFormat(false, String.Format("snippet '{0}' is invalid for shader: {1}", snippet.passName, shader.name));
                return;
            }
            // Unity在编译Shader时,会编译出有效三倍变体量,在AB中,代码相同的可能Unity实现了复用机制来减少内存占用
            // 自带三档硬件等级适配:hw_tier00, hw_tier02, hw_tier01
            // 所以,我们收集到的变体个数 * 3 * pow( 2, multi_compile_num )
            // 在编译一个Shader时,会分类型分别多次调用编译管道,比如VS, PS, GS等等
            // 一个pass含有多个snippet

            // 我们收集到的变体只知道归属的PassType
            backupShaderCompilerData.Clear();
            backupShaderCompilerData.AddRange(data);
            var svcInfo = LoadShaderVariantInfo(shader, s_ShaderVariantCollections);

            if (svcInfo != null)
            {
                List <ShaderVariantCollectionHelper.ShaderVariant> rawVariants;
                if (!svcInfo.rawVariantCollection.TryGetValue(shader, out rawVariants))
                {
                    return;
                }
                if (lastProcessShader != shader)
                {
                    CheckLastShaderVariantCompleteness();
                    lastProcessShader            = shader;
                    lastProcessShaderVariantInfo = svcInfo;
                }
                var           removeCount      = 0;
                StringBuilder infoSB           = null;
                var           full_keywords    = new List <String>();
                var           feature_keywords = new HashSet <String>();

                // 通常这里拿到的是自定义multi_compiles,而builtin不在此列
                // 我们在Shader中通过编译器开关: multi_compile_fwdbase来引入builtin变体编译
                // 从字面上看multi_compile_fwdbase是属于multi_compiles,但实际上Unity有专门的优化
                // 从ShaderCompilerData中拿到的每一个ShaderKeyword是可以拿到ShaderKeywordType的
                // 有了精准的Keyword类型,实际上需要对Builtin类的Keywords再次进行归类:
                // 举一个简单例子: DIRECTIONAL LIGHTPROBE_SH VERTEXLIGHT_ON 这些是属于BuiltinDefault
                // 有些高级渲染效果属于BuiltinAutoStripped,这种是被Unity自动优化的keyword类型
                // 我认为可以对常用的Builtin Keywords可以也规划到multi_compiles中,这样可能会引入更多的变体
                // 但是光照效果适配会更多更安全,不会太激进

                // 在这里我们没做任何针对Builtin类型的Keyword做过多安全性保留,所以编译裁剪非常激进,安全性较低
                var multi_compiles = svcInfo.multi_compiles;

                // multi_compile_fwdbase:
                // DIRECTIONAL
                // DIRLIGHTMAP_COMBINED
                // DYNAMICLIGHTMAP_ON
                // LIGHTMAP_ON
                // LIGHTMAP_SHADOW_MIXING
                // LIGHTPROBE_SH
                // SHADOWS_SCREEN
                // SHADOWS_SHADOWMASK
                // VERTEXLIGHT_ON

                backupShaderCompilerData.RemoveAll(
                    _data => {
                    feature_keywords.Clear();
                    full_keywords.Clear();
                    var _keywords = _data.shaderKeywordSet.GetShaderKeywords();
                    // 只剔除有关键字的情形,减少代码复杂度
                    // 实际上,无关键字的变体也可能被丢弃不用,简单舍弃这次剔除操作并不会增加太多编译负担
                    if (_keywords.Length > 0)
                    {
                        for (int j = 0; j < _keywords.Length; ++j)
                        {
                            var name = _keywords[j].GetKeywordName();
                            full_keywords.Add(name);
                            // 如果有当前关键词属于multi_compiles,注意排除
                            if (multi_compiles != null && multi_compiles.Contains(name))
                            {
                                // 排除multi_compiles编译宏,这些是必须使用的,不能剔除
                                continue;
                            }
                            feature_keywords.Add(name);
                        }
                        if (feature_keywords.Count == 0)
                        {
                            return(false);
                        }
                        var matched = false;
                        // 遍历所有从项目中搜集到的变体
                        for (int n = 0; n < rawVariants.Count; ++n)
                        {
                            var variant = rawVariants[n];
                            if (feature_keywords.Count > variant.keywords.Length)
                            {
                                // feature_keywords 已经去掉了multi_compiles,而variant.keywords可能含有
                                // 从数量的差异就能提前能知道不可能匹配得上
                                continue;
                            }
                            var matchCount    = -1;
                            var mismatchCount = 0;
                            var skipCount     = 0;
                            if (variant.shader == shader && variant.passType == snippet.passType)
                            {
                                matchCount = 0;
                                for (var m = 0; m < variant.keywords.Length; ++m)
                                {
                                    var keyword = variant.keywords[m];
                                    if (multi_compiles == null || !multi_compiles.Contains(keyword))
                                    {
                                        // 不是multi_compiles的keyword
                                        if (feature_keywords.Contains(keyword))
                                        {
                                            ++matchCount;
                                        }
                                        else
                                        {
                                            ++mismatchCount;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        // 查找匹配的变体时,需要排除multi_compiles关键字
                                        ++skipCount;
                                    }
                                }
                            }
                            if (matchCount >= 0 && mismatchCount == 0 &&
                                matchCount == feature_keywords.Count &&
                                matchCount + skipCount == variant.keywords.Length)
                            {
                                matched = true;
                                break;
                            }
                        }
                        if (!matched)
                        {
                            ++removeCount;
                            // 把删除的先存这里,出错了回重新拿回来
                            data.Add(_data);
                            infoSB            = infoSB ?? new StringBuilder();
                            var _fullKeywords = String.Join(" ", full_keywords.ToArray());
                            infoSB.Append(_fullKeywords).AppendLine();
                            var info = String.Format("{0}\nRemove Shader ShaderVariant: {1}", shader.name, _fullKeywords);
                            Debug.Log(info);
                            return(true);
                        }
                    }
                    return(false);
                }
                    );
                data.Clear();
                backupShaderCompilerData.ForEach(e => data.Add(e));
                backupShaderCompilerData.Clear();
                if (removeCount > 0 && infoSB != null)
                {
                    var info = String.Format(
                        "{0}: {1}-'{2}', {3}, count = {4}\nRemove ShaderVariant Count: {5}\n{6}",
                        shader.name, snippet.shaderType, snippet.passName, snippet.passType, data.Count,
                        removeCount, infoSB.ToString()
                        );
                    Debug.Log(info);
                }
            }
        }
コード例 #5
0
 public static void AssertFormat(bool condition, string format, params object[] args)
 {
     Debug.AssertFormat(condition, format, args);
 }
コード例 #6
0
 public static void AssertFormat(bool condition, Object context, string onFailMsgFormat, params object[] args)
 {
     Debug.AssertFormat(condition, context, onFailMsgFormat, args);
 }