/// <summary>
        /// 搜集keywords
        /// </summary>
        public ShaderVariantCollection CollectionKeywords(string[] matPaths, ShaderVariantCollection excludeCollection)
        {
            var shaderCollection = new ShaderVariantCollection();

            //遍历所有mat的KeyWords
            foreach (var path in matPaths)
            {
                //Material;
                var material = AssetDatabase.LoadAssetAtPath <Material>(path);
                //shader数据
                var ret = shaderDataMap.TryGetValue(material.shader, out var shaderData);
                if (!ret)
                {
                    shaderData = ShaderUtilImpl.GetShaderVariantEntriesFilteredInternal(material.shader, 256, new string[] { }, excludeCollection);
                    shaderDataMap[material.shader] = shaderData;
                }

                //收集shaderVaraint
                var passTypes = shaderData.passTypes.Distinct();
                foreach (var pt in passTypes)
                {
                    var shaderVaraint = AddVariantOfPassTypeToCollection((PassType)pt, material);
                    shaderCollection.Add(shaderVaraint);
                }
                //SRP的搜集
                // AddVariantOfPassTypeToCollection(PassType.ScriptableRenderPipeline, material);
                // //ShadiwCast的keyword
                // if (material.FindPass("ShadowCaster") != -1)
                // {
                //     AddVariantOfPassTypeToCollection(PassType.ShadowCaster, material);
                // }
            }

            return(shaderCollection);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Collect shader variants from shader files which are under the given path.
        /// </summary>
        public void CollectShaderVariants()
        {
            if (folders.Length <= 0)
            {
                string msg = "Empty folders.\nSpecify folder where shader files are.\nNote the path should start with 'Assets/'.";
                EditorUtility.DisplayDialog("Error", msg, "OK");
                return;
            }

            var collection = new ShaderVariantCollection();

            var shaders = AssetDatabase.FindAssets("t:Shader", folders);

            try
            {
                foreach (var guid in shaders)
                {
                    var path    = AssetDatabase.GUIDToAssetPath(guid);
                    var shader  = AssetDatabase.LoadAssetAtPath <Shader>(path);
                    var variant = new ShaderVariantCollection.ShaderVariant(shader, passType, keywords);
                    collection.Add(variant);
                }
            }
            catch (Exception e)
            {
                // Throw an ArgumentException if shader is null,
                // pass type does not exist or variant with the passed keywords is not found.
                EditorUtility.DisplayDialog("Error", e.Message, "OK");
            }

            // save as asset.
            string assetPath = Path.Combine(outputPath, assetFileName + assetFileExt);

            AssetDatabase.CreateAsset(collection, assetPath);
        }
Exemplo n.º 3
0
        private static void CreateShaderVariantCollection(SerializedProperty shaderVariantProperty, string folderPath)
        {
            Shader             shader           = (Shader)shaderVariantProperty.FindPropertyRelative("first").objectReferenceValue;
            SerializedProperty variantsProperty = shaderVariantProperty.FindPropertyRelative("second.variants");

            if (shader == null || variantsProperty == null)
            {
                return;
            }

            var variantCollectionName          = shader.name.Replace('/', '-');
            ShaderVariantCollection collection = new ShaderVariantCollection();

            collection.name = variantCollectionName;

            for (int i = 0; i < variantsProperty.arraySize; i++)
            {
                SerializedProperty variantProperty = variantsProperty.GetArrayElementAtIndex(i);
                string             keywords        = variantProperty.FindPropertyRelative("keywords").stringValue;
                PassType           passType        = (PassType)variantProperty.FindPropertyRelative("passType").intValue;
                collection.Add(new ShaderVariantCollection.ShaderVariant(shader, passType, keywords.Split(' ')));
            }

            var filePath = folderPath + variantCollectionName + ".shadervariants";

            CreateOrReplaceAsset(collection, filePath);
        }
Exemplo n.º 4
0
    void AddKeywords(
        ShaderVariantCollection collection,
        Shader shader,
        PassType pass,
        string[] keywordList)
    {
        if (CheckKeywords(shader, pass, keywordList))
        {
            List <string> keywords = new List <string>(keywordList);
            // special case overrides
            if (shader.name != "Hidden/VideoDecodeAndroid" &&
                shader.name != "Oculus/Texture2D Blit" &&
                !keywords.Contains("SHADOWS_DEPTH"))
            {
                keywords.Add("STEREO_MULTIVIEW_ON");
            }

            ShaderVariantCollection.ShaderVariant variant =
                new ShaderVariantCollection.ShaderVariant();

            variant.shader   = shader;
            variant.passType = pass;
            variant.keywords = keywords.ToArray();
            collection.Add(variant);
        }
    }
        public void Process(AssetImporter importer, TextWriter writer)
        {
            if (Path.GetExtension(importer.assetPath) != ".mat")
            {
                return;
            }

            var material = AssetDatabase.LoadAssetAtPath <Material>(importer.assetPath);

            if (!material)
            {
                Debug.LogError($"Load material fail : {importer.assetPath}");
                return;
            }
            var shader     = material.shader;
            var shaderPath = AssetDatabase.GetAssetPath(shader);

            if (shaderPath.StartsWith("Packages"))
            {
                writer.WriteLine($"Material : {importer.assetPath} using in packages shader : {shaderPath}");
            }

            var materialKeywords = material.shaderKeywords;

            if (ShaderPreprocessor.AddInUsedShaderKeywords(shader, materialKeywords) &&
                m_shaderToGlobalKeywords.TryGetValue(shader, out var localGlobal))
            {
                List <string> filteredKeywords = new List <string>(materialKeywords);
                for (int i = filteredKeywords.Count - 1; i >= 0; i--)
                {
                    if (Array.IndexOf(localGlobal.Item2, filteredKeywords[i]) == -1)
                    {
                        filteredKeywords.RemoveAt(i);
                    }
                }

                foreach (var keyword in localGlobal.Item1)
                {
                    string[] keywords = new string[filteredKeywords.Count + 1];
                    filteredKeywords.CopyTo(0, keywords, 0, filteredKeywords.Count);
                    keywords[filteredKeywords.Count] = keyword;
                    m_collection.Add(new ShaderVariantCollection.ShaderVariant(shader, PassType.ScriptableRenderPipeline, keywords));
                }
                m_collection.Add(new ShaderVariantCollection.ShaderVariant(shader, PassType.ScriptableRenderPipeline, filteredKeywords.ToArray()));
            }
        }
Exemplo n.º 6
0
    public void UpdateShaderValues()
    {
        keywords.Clear();
        Shader.SetGlobalInt("Blocker_Samples", Blocker_SampleCount);
        Shader.SetGlobalInt("PCF_Samples", PCF_SampleCount);

        if (shadowRenderTexture)
        {
            if (shadowRenderTexture.format != format || shadowRenderTexture.antiAliasing != (int)MSAA)
            {
                CreateShadowRenderTexture();
            }
            else
            {
                shadowRenderTexture.filterMode = filterMode;
            }
        }

        Shader.SetGlobalFloat("Softness", Softness / 64f / Mathf.Sqrt(QualitySettings.shadowDistance));
        Shader.SetGlobalFloat("SoftnessFalloff", Mathf.Exp(SoftnessFalloff));
        SetFlag("USE_FALLOFF", SoftnessFalloff > Mathf.Epsilon);
        //Shader.SetGlobalFloat("NearPlane", NearPlane);

        Shader.SetGlobalFloat("RECEIVER_PLANE_MIN_FRACTIONAL_ERROR", MaxStaticGradientBias);
        Shader.SetGlobalFloat("Blocker_GradientBias", Blocker_GradientBias);
        Shader.SetGlobalFloat("PCF_GradientBias", PCF_GradientBias);

        SetFlag("USE_CASCADE_BLENDING", CascadeBlendDistance > 0);
        Shader.SetGlobalFloat("CascadeBlendDistance", CascadeBlendDistance);

        SetFlag("USE_STATIC_BIAS", MaxStaticGradientBias > 0);
        SetFlag("USE_BLOCKER_BIAS", Blocker_GradientBias > 0);
        SetFlag("USE_PCF_BIAS", PCF_GradientBias > 0);

        //        SetFlag("ROTATE_SAMPLES", RotateSamples);
        //        SetFlag("USE_NOISE_TEX", UseNoiseTexture);

        if (noiseTexture)
        {
            Shader.SetGlobalVector("NoiseCoords", new Vector4(1f / noiseTexture.width, 1f / noiseTexture.height, 0f, 0f));
            Shader.SetGlobalTexture("_NoiseTexture", noiseTexture);
        }

        SetFlag("ORTHOGRAPHIC_SUPPORTED", supportOrthographicProjection);

        int maxSamples = Mathf.Max(Blocker_SampleCount, PCF_SampleCount);

        SetFlag("POISSON_32", maxSamples < 33);
        SetFlag("POISSON_64", maxSamples > 33);

        if (shaderVariants)
        {
            shaderVariants.Add(new ShaderVariantCollection.ShaderVariant(shader, PassType.Normal, keywords.ToArray()));
        }
    }
Exemplo n.º 7
0
        void CombineShaderVariantCollections(string assetPath)
        {
            var shaderVariantType = typeof(ShaderVariantCollection.ShaderVariant).AsDynamicType();
            var validSvc          = new ShaderVariantCollection();

            foreach (var svc in m_Target.ShaderVariantCollections)
            {
                if (svc == null)
                {
                    continue;
                }

                var proxy   = svc.GetProxy();
                var shaders = proxy.Shaders;
                foreach (var shader in shaders)
                {
                    var variants = proxy.GetVariants(shader);
                    foreach (var variant in variants)
                    {
                        string message = shaderVariantType.CheckShaderVariant(shader, variant.passType, variant.keywords);
                        if (message.IsNullOrWhiteSpace())
                        {
                            validSvc.Add(new ShaderVariantCollection.ShaderVariant(shader, variant.passType, variant.keywords));
                        }
                        else
                        {
                            var validKeywords = variant.keywords.Where(x => ((string)shaderVariantType.CheckShaderVariant(shader, variant.passType, new[] { x })).IsNullOrWhiteSpace()).ToArray();
                            validSvc.Add(new ShaderVariantCollection.ShaderVariant(shader, variant.passType, validKeywords));
                        }
                    }
                }
            }

            AssetDatabase.CreateAsset(validSvc, assetPath);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            m_Target.ShaderVariantCollections.Clear();
            m_Target.ShaderVariantCollections.Add(validSvc);
            serializedObject.Update();
            GUIUtility.ExitGUI();
        }
Exemplo n.º 8
0
    private void OnMaterialProcess(Material mat)
    {
        var variant = CreateVariant(mat);

        if (!collection.Contains(variant))
        {
            collection.Add(variant);
            var keywordsString = JsonUtility.ToJson(variant.keywords, true);
            Debug.Log($"New variant found!\nShader: {variant.shader.name}\nKeywords:{keywordsString}");
        }
    }
        public override void Setup()
        {
            base.Setup();
            m_SegmentationShader = Shader.Find(k_SegmentationPassShaderName);
            var shaderVariantCollection = new ShaderVariantCollection();

            shaderVariantCollection.Add(new ShaderVariantCollection.ShaderVariant(m_SegmentationShader, PassType.ScriptableRenderPipeline));
            shaderVariantCollection.WarmUp();

            m_OverrideMaterial = new Material(m_SegmentationShader);
        }
Exemplo n.º 10
0
 private void AddShaderVariantFromShaderList(ShaderVariantCollection _svc, List <ShaderVariantCollection.ShaderVariant> svList)
 {
     foreach (var sv in svList)
     {
         if (!_svc.Contains(sv))
         {
             //存在しないので追加
             _svc.Add(sv);
         }
     }
 }
Exemplo n.º 11
0
        private void ReadSVCDataAndAdd(ShaderVariantCollection svc)
        {
            if (!File.Exists(m_txtPath))
            {
                return;
            }

            //计时开始
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();

            //StreamWriter第二个参数为false覆盖现有文件,为true则把文本追加到文件末尾
            using (StreamReader file = new StreamReader(m_txtPath))
            {
                Shader shader = null;

                //逐行读取文件处理至文件结束
                string str;
                while ((str = file.ReadLine()) != null)
                {
                    if (str.StartsWith("Shader: "))
                    {
                        shader = Shader.Find(str.Replace("Shader: ", ""));
                    }
                    else
                    {
                        if (shader == null)
                        {
                            continue;
                        }

                        //只搜索前4位
                        int      firstSpaceIndex = str.IndexOf(" ", 0, 4, StringComparison.Ordinal);
                        PassType passType        = (PassType)Convert.ToInt32(str.Substring(0, firstSpaceIndex));
                        string[] kws             = str.Remove(0, firstSpaceIndex + 1).Split(' ');

                        svc.Add(new ShaderVariantCollection.ShaderVariant(shader, passType, kws));
                    }
                }

                file.Close();
            }

            //计时结束
            stopwatch.Stop();
            TimeSpan timespan = stopwatch.Elapsed;

            ClearOutput();
            outputSB.AppendLine("创建完成,耗时: " + timespan.Hours + "h," + timespan.Minutes + "m," + timespan.Seconds + "s");
            ShowSVCInfo();
            AssetDatabase.SaveAssets();
        }
Exemplo n.º 12
0
        public virtual void AddShaderVariantToCollection(string shaderName, string extensionCode = null)
        {
            if (disableShaderVariantCollection)
            {
                return;
            }
#if UNITY_EDITOR
            if (!Application.isPlaying && shaderBindings != null && shaderVariantCollection != null && !string.IsNullOrEmpty(shaderName))
            {
                Shader instancedShader = shaderBindings.GetInstancedShader(shaderName, extensionCode);
                if (instancedShader != null)
                {
                    ShaderVariantCollection.ShaderVariant shaderVariant = new ShaderVariantCollection.ShaderVariant();
                    shaderVariant.shader = instancedShader;
                    //shaderVariant.passType = PassType.Normal;
                    shaderVariantCollection.Add(shaderVariant);
                    // To add only the shader without the passtype or keywords, remove the specific variant but the shader remains
                    shaderVariantCollection.Remove(shaderVariant);
                }
            }
#endif
        }
Exemplo n.º 13
0
 protected void KeywordsChanged() {
     foreach (PassType passType in GetPassTypes()) {
         try {
             ShaderVariantCollection.ShaderVariant shaderVariant =
                 new ShaderVariantCollection.ShaderVariant(GetShader(), passType, keywordsEnabled.ToArray());
             if (!shaderVariants.Contains(shaderVariant)) {
                 shaderVariants.Add(shaderVariant);
             }
         }
         catch (Exception _) {
             // ignored
         }
     }
 }
Exemplo n.º 14
0
    static void CollectShaderVariants()
    {
        var collection = new ShaderVariantCollection();
        var folders    = new string[] { "Assets/Shaders" };
        var shaders    = AssetDatabase.FindAssets("t:Shader", folders);

        foreach (var guid in shaders)
        {
            var path    = AssetDatabase.GUIDToAssetPath(guid);
            var shader  = AssetDatabase.LoadAssetAtPath <Shader>(path);
            var variant = new ShaderVariantCollection.ShaderVariant(shader, PassType.ForwardAdd, "DIRECTIONAL", "SHADOWS_OFF");
            collection.Add(variant);
        }
        AssetDatabase.CreateAsset(collection, "Assets/AutoGenerated.shadervariants");
    }
        public override void Setup()
        {
            base.Setup();
            m_ClassLabelingShader = Shader.Find(k_ShaderName);

            var shaderVariantCollection = new ShaderVariantCollection();

            if (shaderVariantCollection != null)
            {
                shaderVariantCollection.Add(new ShaderVariantCollection.ShaderVariant(m_ClassLabelingShader, PassType.ScriptableRenderPipeline));
            }

            m_OverrideMaterial = new Material(m_ClassLabelingShader);

            shaderVariantCollection.WarmUp();
        }
Exemplo n.º 16
0
 private void AddShaderVariantList(ShaderVariantCollection shaderVariantCollection, List <ShaderVariantCollection.ShaderVariant> list)
 {
     foreach (var variant in list)
     {
         try
         {
             if (!shaderVariantCollection.Contains(variant))
             {
                 shaderVariantCollection.Add(variant);
             }
         } catch (System.Exception e)
         {
             Debug.LogError(e);
         }
     }
 }
Exemplo n.º 17
0
        private void ApplyShaderVariantCollection()
        {
            shaderVariantCollection.Clear();

            foreach (var shaderInfo in shaderInfos)
            {
                if (!shaderInfo.add)
                {
                    continue;
                }

                shaderVariantCollection.Add(shaderInfo.shaderVariant);
            }

            EditorUtility.DisplayDialog("Result", "ShaderVariantCollection update complete.", "OK");
        }
    private void SplitShaderVariantCollection(ShaderVariantCollection svc)
    {
        var serializedObject = new SerializedObject(svc);
        var m_Shaders        = serializedObject.FindProperty("m_Shaders");

        if (m_Shaders != null)
        {
            for (var i = 0; i < m_Shaders.arraySize; ++i)
            {
                var entryProp = m_Shaders.GetArrayElementAtIndex(i);
                var shader    = (Shader)entryProp.FindPropertyRelative("first").objectReferenceValue;
                if (shader != null)
                {
                    Debug.Log(shader.name);
                    EditorUtility.DisplayProgressBar("Spliting SVC", "Shader -> " + shader.name, (i + 1) * 1.0f / m_Shaders.arraySize);

                    var newSVC = new ShaderVariantCollection();
                    // Variants for this shader
                    var variantsProp = entryProp.FindPropertyRelative("second.variants");
                    for (var j = 0; j < variantsProp.arraySize; ++j)
                    {
                        var      prop        = variantsProp.GetArrayElementAtIndex(j);
                        var      keywords    = prop.FindPropertyRelative("keywords").stringValue;
                        string[] keywordsArr = null;
                        if (!string.IsNullOrEmpty(keywords))
                        {
                            keywordsArr = keywords.Split(' ');
                        }
                        var passType = (UnityEngine.Rendering.PassType)prop.FindPropertyRelative("passType").intValue;
                        newSVC.Add(new ShaderVariantCollection.ShaderVariant(shader, passType, keywordsArr));
                    }

                    var path     = Path.GetDirectoryName(AssetDatabase.GetAssetPath(svc));
                    var filename = shader.name.Replace('/', '_').Replace(' ', '_') + ".shadervariants";
                    var output   = Path.Combine(path, filename);
                    AssetDatabase.CreateAsset(newSVC, output);
                    AssetDatabase.Refresh();
                }
                else
                {
                    Debug.LogWarning("has missing shader.");
                }
            }
            EditorUtility.ClearProgressBar();
        }
    }
        public override void Setup()
        {
            base.Setup();
            m_LensDistortionShader = Shader.Find(k_ShaderName);

            var shaderVariantCollection = new ShaderVariantCollection();

            if (shaderVariantCollection != null)
            {
                shaderVariantCollection.Add(new ShaderVariantCollection.ShaderVariant(m_LensDistortionShader, PassType.ScriptableRenderPipeline));
            }

            m_LensDistortionMaterial = new Material(m_LensDistortionShader);

            if (shaderVariantCollection != null)
            {
                shaderVariantCollection.WarmUp();
            }

            // Set up a new texture
            if (m_DistortedTexture == null || m_DistortedTexture.width != Screen.width || m_DistortedTexture.height != Screen.height)
            {
                if (m_DistortedTexture != null)
                {
                    m_DistortedTexture.Release();
                }

                m_DistortedTexture = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
                m_DistortedTexture.enableRandomWrite = true;
                m_DistortedTexture.filterMode        = FilterMode.Point;
                m_DistortedTexture.Create();
            }

            // Grab the lens distortion
#if HDRP_PRESENT
            // Grab the Lens Distortion from Perception Camera stack
            var hdCamera = HDCamera.GetOrCreate(targetCamera);
            var stack    = hdCamera.volumeStack;
            m_LensDistortion = stack.GetComponent <LensDistortion>();
#elif URP_PRESENT
            var stack = VolumeManager.instance.stack;
            m_LensDistortion = stack.GetComponent <LensDistortion>();
#endif
            m_Initialized = true;
        }
Exemplo n.º 20
0
        public void LoadShaders(Action initOK = null)
        {
            var list = new List <ShaderCollectionInfo>();

            resMgr.LoadAssetAsync <Shader>("Shaders", null, delegate(UnityEngine.Object[] objs)
            {
                foreach (var item in objs)
                {
                    var shader           = item as Shader;
                    var shaderVarList    = new ShaderVariantCollection();
                    var shaderVariant    = new ShaderVariantCollection.ShaderVariant();
                    shaderVariant.shader = shader;
                    shaderVarList.Add(shaderVariant);
                    list.Add(new ShaderCollectionInfo(shader.name, shaderVarList));

                    this.AddShader(shader.name, shader);
                }
                Utility.Util.StartCoroutine(InitShaderInternal(list, initOK));
            });
        }
Exemplo n.º 21
0
    public void CacheShadersFromPackage(string cahced_package_name)
    {
        //IL_002d: Unknown result type (might be due to invalid IL or missing references)
        //IL_0032: Expected O, but got Unknown
        //IL_00ac: Unknown result type (might be due to invalid IL or missing references)
        //IL_00b8: Unknown result type (might be due to invalid IL or missing references)
        //IL_00be: Unknown result type (might be due to invalid IL or missing references)
        PackageObject cachedPackage = GetCachedPackage(cahced_package_name);

        if (cachedPackage != null)
        {
            AssetBundle val = cachedPackage.obj as AssetBundle;
            if (val != null)
            {
                Shader[] array = val.LoadAllAssets <Shader>();
                ShaderVariantCollection val2 = new ShaderVariantCollection();
                int i = 0;
                for (int num = array.Length; i < num; i++)
                {
                    if (!array[i].get_isSupported())
                    {
                        Log.Error("no support shader : " + array[i].get_name());
                    }
                    string name = array[i].get_name();
                    shaderCaches.Add(name, array[i]);
                    if (name.StartsWith("EeL") || name.Contains("effect"))
                    {
                        ShaderVariant val3 = default(ShaderVariant);
                        val3.shader = array[i];
                        val2.Add(val3);
                    }
                }
                if (!val2.get_isWarmedUp())
                {
                    val2.WarmUp();
                }
            }
        }
    }
    private static void CreateSVC(string svcFileName, List <VariantInfo> variantInfos)
    {
        if (variantInfos == null || variantInfos.Count == 0)
        {
            return;
        }

        ShaderVariantCollection athenaSVC = new ShaderVariantCollection();

        for (int i = 0; i < variantInfos.Count; i++)
        {
            VariantInfo info = variantInfos[i];
            if (info == null || info.keywords == null)
            {
                continue;
            }

            for (int j = 0; j < info.keywords.Length; j++)
            {
                ShaderVariantCollection.ShaderVariant variant = new ShaderVariantCollection.ShaderVariant()
                {
                    shader = info.shader, keywords = new string[1] {
                        info.keywords[j]
                    }, passType = info.passType[j],
                };
                athenaSVC.Add(variant);
            }
        }

        // CreateAsset 的path参数要传 “Assets/Dir/file.postfix"  形式 //
        // 不能用 Application.dataPath + "/dIR/FILE.postfix" 形式 //

    #if UNITY_EDITOR
        AssetDatabase.CreateAsset(athenaSVC, "Assets/KeywordAndMultiCompile/" + svcFileName);
        AssetDatabase.Refresh();
    #endif
    }
        void OnGUI()
        {
            svc = (ShaderVariantCollection)EditorGUILayout.ObjectField("ShaderVariantCollection", svc, typeof(ShaderVariantCollection), false);

            if (svc)
            {
                if (GUILayout.Button("Add Select Shader"))
                {
                    Object[] objs = Selection.objects;
                    foreach (Object obj in objs)
                    {
                        Shader shader = obj as Shader;
                        if (shader == null)
                        {
                            continue;
                        }

                        ShaderVariantCollection.ShaderVariant sv = new ShaderVariantCollection.ShaderVariant();
                        sv.shader = shader;
                        svc.Add(sv);
                    }
                }
            }
        }
Exemplo n.º 24
0
        public override void Initialize()
        {
            ReplaceOverwrittenCollections();

            _tempExcludes.Clear();
            if (_allowVrVariants)
            {
                _tempExcludes.AddRange(VR_KEYWORDS);
            }
            if (_allowInstancedVariants)
            {
                _tempExcludes.AddRange(INSTANCING_KEYWORDS);
            }

            foreach (var c in _whitelistedCollections)
            {
                // Load asset YAML
                var file = new List <string>(System.IO.File.ReadAllLines(
                                                 (Application.dataPath + AssetDatabase.GetAssetPath(c)).Replace("AssetsAssets", "Assets")
                                                 ));

                #region Pre-process to get rid of mid-list line breaks
                var yaml = new List <string>();

                // Find shaders list
                int i = 0;
                for (; i < file.Count; ++i)
                {
                    if (YamlLineHasKey(file[i], "m_Shaders"))
                    {
                        break;
                    }
                }

                // Process and fill
                int indent = 0;
                for (; i < file.Count; ++i)
                {
                    string f        = file[i];
                    int    myIndent = GetYamlIndent(f);
                    if (myIndent > indent)
                    {
                        // If no "<key>: ", continuation of previous line
                        if (!f.EndsWith(":") && !f.Contains(": "))
                        {
                            yaml[yaml.Count - 1] += " " + f.Trim();
                            continue;
                        }
                    }

                    yaml.Add(f);
                    indent = myIndent;
                }
                #endregion

                #region Iterate over shaders
                for (i = 0; i < yaml.Count; ++i)
                {
                    string y = yaml[i];
                    if (yaml[i].Contains("first:"))
                    {
                        string guid = GetValueFromYaml(y, "guid");
                        Shader s    = AssetDatabase.LoadAssetAtPath <Shader>(AssetDatabase.GUIDToAssetPath(guid));

                        // Move to variants contents (skip current line, "second:" and "variants:")
                        i     += 3;
                        indent = GetYamlIndent(yaml[i]);
                        var sv = new ShaderVariantCollection.ShaderVariant();
                        for (; i < yaml.Count; ++i)
                        {
                            y = yaml[i];

                            // If indent changes, variants have ended
                            if (GetYamlIndent(y) != indent)
                            {
                                // Outer loop will increment, so counteract
                                i -= 1;
                                break;
                            }

                            if (IsYamlLineNewEntry(y))
                            {
                                // First entry will be a new entry but no variant info present yet, so skip
                                // Builtin shaders will also be null
                                if (sv.shader != null)
                                {
                                    Dictionary <PassType, List <ShaderVariantCollection.ShaderVariant> > variantsByPass = null;
                                    if (!_variantsByShader.TryGetValue(sv.shader, out variantsByPass))
                                    {
                                        variantsByPass = new Dictionary <PassType, List <ShaderVariantCollection.ShaderVariant> >();
                                        _variantsByShader.Add(sv.shader, variantsByPass);
                                    }
                                    List <ShaderVariantCollection.ShaderVariant> variants = null;
                                    if (!variantsByPass.TryGetValue(sv.passType, out variants))
                                    {
                                        variants = new List <ShaderVariantCollection.ShaderVariant>();
                                        variantsByPass.Add(sv.passType, variants);
                                    }
                                    bool dupe = false;
                                    foreach (var existing in variants)
                                    {
                                        if (ShaderVariantsEqual(existing, sv))
                                        {
                                            dupe = true;
                                            break;
                                        }
                                    }
                                    if (!dupe)
                                    {
                                        variants.Add(sv);
                                    }
                                }
                                sv        = new ShaderVariantCollection.ShaderVariant();
                                sv.shader = s;
                            }

                            // Get contents
                            if (YamlLineHasKey(y, "passType"))
                            {
                                sv.passType = (PassType)int.Parse(GetValueFromYaml(y, "passType"));
                            }
                            if (YamlLineHasKey(y, "keywords"))
                            {
                                sv.keywords = GetValuesFromYaml(y, "keywords", _tempExcludes);
                            }
                        }
                        // Get final variant
                        if (sv.shader != null)
                        {
                            Dictionary <PassType, List <ShaderVariantCollection.ShaderVariant> > variantsByPass = null;
                            if (!_variantsByShader.TryGetValue(sv.shader, out variantsByPass))
                            {
                                variantsByPass = new Dictionary <PassType, List <ShaderVariantCollection.ShaderVariant> >();
                                _variantsByShader.Add(sv.shader, variantsByPass);
                            }
                            List <ShaderVariantCollection.ShaderVariant> variants = null;
                            if (!variantsByPass.TryGetValue(sv.passType, out variants))
                            {
                                variants = new List <ShaderVariantCollection.ShaderVariant>();
                                variantsByPass.Add(sv.passType, variants);
                            }
                            bool dupe = false;
                            foreach (var existing in variants)
                            {
                                if (ShaderVariantsEqual(existing, sv))
                                {
                                    dupe = true;
                                    break;
                                }
                            }
                            if (!dupe)
                            {
                                variants.Add(sv);
                            }
                        }
                    }
                }
                #endregion

                LogMessage(this, "Parsing ShaderVariantCollection " + c.name);
                // Loop over shaders
                foreach (var s in _variantsByShader)
                {
                    string log = "Shader: " + s.Key.name;
                    // Loop over passes
                    foreach (var p in s.Value)
                    {
                        log += string.Format("\n   Pass: ({1:00}){0}", p.Key, (int)p.Key);
                        // Loop over variants
                        for (int v = 0; v < p.Value.Count; ++v)
                        {
                            log += string.Format("\n      Variant [{0}]:\t", v);
                            // Loop over keywords
                            var ks = p.Value[v].keywords;
                            if (ks != null && ks.Length != 0)
                            {
                                bool first = true;
                                foreach (var k in ks)
                                {
                                    if (!first)
                                    {
                                        log += ", ";
                                    }
                                    log  += k;
                                    first = false;
                                }
                            }
                            else
                            {
                                log += "<no keywords>";
                            }
                        }
                    }
                    LogMessage(this, log);
                }
            }

            // Merge collections
            if (!string.IsNullOrEmpty(_mergeToFile) && _whitelistedCollections.Count > 1)
            {
                var svc = new ShaderVariantCollection();
                foreach (var a in _variantsByShader)
                {
                    foreach (var b in a.Value)
                    {
                        foreach (var s in b.Value)
                        {
                            svc.Add(s);
                        }
                    }
                }
                try {
                    string file = _mergeToFile + ".shadervariants";
                    string log  = string.Format("Merged following ShaderVariantCollections into {0}:\n", file);
                    foreach (var s in _whitelistedCollections)
                    {
                        log += "    " + s.name + "\n";
                    }

                    if (AssetDatabase.LoadAssetAtPath <ShaderVariantCollection>(file) != null)
                    {
                        AssetDatabase.DeleteAsset(file);
                    }
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh();
                    AssetDatabase.CreateAsset(svc, file);
                    AssetDatabase.SaveAssets();
                    AssetDatabase.Refresh();

                    Debug.Log(log, AssetDatabase.LoadAssetAtPath <ShaderVariantCollection>(file));
                } catch (System.Exception ex) {
                    Debug.LogError("Error merging ShaderVariantCollections. Exception follows.");
                    throw;
                }
            }

            _valid = (_variantsByShader != null && _variantsByShader.Count > 0);
        }
Exemplo n.º 25
0
        public static void SimpleGenShaderVariant()
        {
            //先搜集所有keyword到工具类SVC
            toolSVC = new ShaderVariantCollection();
            var shaders = AssetDatabase.FindAssets("t:Shader", new string[] { "Assets", "Packages" }).ToList();

            foreach (var shader in shaders)
            {
                ShaderVariantCollection.ShaderVariant sv = new ShaderVariantCollection.ShaderVariant();
                var shaderPath = AssetDatabase.GUIDToAssetPath(shader);
                sv.shader = AssetDatabase.LoadAssetAtPath <Shader>(shaderPath);
                toolSVC.Add(sv);
                //
                allShaderNameList.Add(shaderPath);
            }

            var toolsSVCpath = "Assets/Resource/Shaders/Tools.shadervariants";

            //防空
            FileHelper.WriteAllText(toolsSVCpath, "");
            AssetDatabase.DeleteAsset(toolsSVCpath);
            AssetDatabase.CreateAsset(toolSVC, toolsSVCpath);


            //搜索所有Mat
            var paths   = BDApplication.GetAllRuntimeDirects().ToArray();
            var assets  = AssetDatabase.FindAssets("t:Prefab", paths).ToList();
            var assets2 = AssetDatabase.FindAssets("t:Material", paths);

            assets.AddRange(assets2);
            List <string> allMats = new List <string>();

            //GUID to assetPath
            for (int i = 0; i < assets.Count; i++)
            {
                var p = AssetDatabase.GUIDToAssetPath(assets[i]);
                //获取依赖中的mat
                var dependenciesPath = AssetDatabase.GetDependencies(p, true);
                var mats             = dependenciesPath.ToList().FindAll((dp) => dp.EndsWith(".mat"));
                allMats.AddRange(mats);
            }

            //处理所有的 material
            allMats = allMats.Distinct().ToList();


            float count = 1;

            foreach (var mat in allMats)
            {
                var obj = AssetDatabase.LoadMainAssetAtPath(mat);
                if (obj is Material)
                {
                    var _mat = obj as Material;
                    EditorUtility.DisplayProgressBar("处理mat", string.Format("处理:{0} - {1}", Path.GetFileName(mat), _mat.shader.name), count / allMats.Count);
                    AddToDict(_mat);
                }

                count++;
            }

            EditorUtility.ClearProgressBar();
            //所有的svc
            ShaderVariantCollection svc = new ShaderVariantCollection();

            foreach (var item in ShaderVariantDict)
            {
                foreach (var _sv in item.Value)
                {
                    svc.Add(_sv);
                }
            }

            AssetDatabase.DeleteAsset(ALL_SHADER_VARAINT_PATH);
            AssetDatabase.CreateAsset(svc, ALL_SHADER_VARAINT_PATH);
            AssetDatabase.Refresh();
        }
Exemplo n.º 26
0
    public static string  GenShaderVariant()
    {
        var path = "Assets/Resource/Runtime";

        var assets  = AssetDatabase.FindAssets("t:Prefab", new string[] { path }).ToList();
        var assets2 = AssetDatabase.FindAssets("t:Material", new string[] { path });

        assets.AddRange(assets2);


        List <string> allMats = new List <string>();

        //GUID to assetPath
        for (int i = 0; i < assets.Count; i++)
        {
            var p = AssetDatabase.GUIDToAssetPath(assets[i]);
            //获取依赖中的mat
            var dependenciesPath = AssetDatabase.GetDependencies(p, true);

            var mats = dependenciesPath.ToList().FindAll((dp) => dp.EndsWith(".mat"));
            allMats.AddRange(mats);
        }

        //处理所有的 material
        allMats = allMats.Distinct().ToList();


        float _i = 1;

        foreach (var mat in allMats)
        {
            //TODO 测试用
            if (mat.Contains("Material29"))
            {
                int i = 0;
            }

            var obj = AssetDatabase.LoadMainAssetAtPath(mat);
            if (obj is Material)
            {
                var _mat = obj as Material;
                EditorUtility.DisplayProgressBar("处理mat", string.Format("处理:{0} - {1}", Path.GetFileName(mat), _mat.shader.name), _i / allMats.Count);
                AddToDict(_mat);
            }
            _i++;
        }
        EditorUtility.ClearProgressBar();
        //所有的svc
        ShaderVariantCollection svc = new ShaderVariantCollection();

        foreach (var item in ShaderVariantDict)
        {
            foreach (var _sv in item.Value)
            {
                svc.Add(_sv);
            }
        }

        var _p = "Assets/Resource/Runtime/Shader/TheShaderVariantForAll.shadervariants";

        AssetDatabase.CreateAsset(svc, _p);
        AssetDatabase.Refresh();

        return(_p);
    }
Exemplo n.º 27
0
        /// <inheritdoc />
        public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList <ShaderCompilerData> data)
        {
            if (!ShaderVariantCollectionGenerator3.IsCreating)
            {
                return;
            }
#if DEBUG_ON
            Debug.Log("SVCG_ShaderPreprocessor.OnProcessShader(" + shader.name + ")");
#endif
            ShaderVariantCollection svc = ShaderVariantCollectionGenerator3.CurrentSVC;
            if (!ShaderVariantCollectionGenerator3.WillWriteToFile && svc == null)
            {
                return;
            }

            //处理剔除配置
            if (ShaderVariantCollectionGenerator3.CurrentConfig != null)
            {
                EditorUtility.DisplayProgressBar("正在执行剔除", $"Shader: {shader.name}", 0);
                ShaderKeywordConfig config = ShaderVariantCollectionGenerator3.CurrentConfig;
                if (DoExcludeShader(config, shader))
                {
                    return;
                }
                EditorUtility.DisplayProgressBar("正在执行剔除", $"Shader: {shader.name}", 0.3333f);
                if (DoExclude(config.GetGlobalConfig(), snippet, data))
                {
                    return;
                }
                EditorUtility.DisplayProgressBar("正在执行剔除", $"Shader: {shader.name}", 0.6666f);
                if (DoExclude(config.GetConfigOfShader(shader), snippet, data))
                {
                    return;
                }
                EditorUtility.DisplayProgressBar("正在执行剔除", $"Shader: {shader.name}", 1);
            }

            for (int i = 0; i < data.Count; i++)
            {
                EditorUtility.DisplayProgressBar("正在处理变体", $"Shader: {shader.name}, data: {i}/{data.Count}", (float)i / data.Count);

                ShaderKeyword[] kws = data[i].shaderKeywordSet.GetShaderKeywords();

                if (ShaderVariantCollectionGenerator3.WillWriteToFile)
                {
                    string[] strKWs = new string[kws.Length + 1];
                    strKWs[0] = ((int)snippet.passType).ToString();
                    for (int j = 1; j < kws.Length + 1; j++)
                    {
#if UNITY_2019_3_OR_NEWER
                        strKWs[j] = ShaderKeyword.GetKeywordName(shader, kws[j - 1]);
#else
                        strKWs[j] = kws[j - 1].GetKeywordName();
#endif
                    }

                    HashSet <string> d = null;
                    if (ShaderVariantCollectionGenerator3.DataDictionary.TryGetValue(shader, out d))
                    {
                        d.Add(DebugUtil.LogString(strKWs));
                    }
                    else
                    {
                        d = new HashSet <string>();
                        d.Add(DebugUtil.LogString(strKWs));
                        ShaderVariantCollectionGenerator3.DataDictionary.Add(shader, d);
                    }
#if DEBUG_ON
                    Debug.Log("file.Add(" + DebugUtil.LogString(strKWs) + ")");
#endif
                }
                else
                {
                    string[] strKWs = new string[kws.Length];
                    for (int j = 0; j < kws.Length; j++)
                    {
#if UNITY_2019_3_OR_NEWER
                        strKWs[j] = ShaderKeyword.GetKeywordName(shader, kws[j]);
#else
                        strKWs[j] = kws[j].GetKeywordName();
#endif
                    }
#if DEBUG_ON
                    Debug.Log("svc.Add(" + shader + ", " + snippet.passType + ", " + DebugUtil.LogString(strKWs) + ")");
#endif
                    if (ShaderVariantCollectionGenerator3.StopOnException)
                    {
                        svc.Add(new ShaderVariantCollection.ShaderVariant(shader, snippet.passType, strKWs));
                    }
                    else
                    {
                        //不使用构造函数可以避免调用 ShaderVariantCollection.ShaderVariant.CheckShaderVariant
                        //它将耗费大量时间来判断输入数据是否存在异常
                        ShaderVariantCollection.ShaderVariant sv = new ShaderVariantCollection.ShaderVariant();
                        sv.shader   = shader;
                        sv.passType = snippet.passType;
                        sv.keywords = strKWs;
                        svc.Add(sv);
                    }
                }
            }

            //实际打包时不编译shader变体,仅收集信息,大幅优化执行时间
            data.Clear();
        }
Exemplo n.º 28
0
    void CheckShaderVariant(ShaderVariantCollection collection, Shader source, int i, bool point = true, bool projector = false)
    {
        ShaderVariantList.Clear();


        int v  = i;
        int vc = 0;

        if (v >= 64)
        {
            if (!Full)
            {
                return;
            }
            ShaderVariantList.Add("FULL_ON"); v -= 64; vc++;
        }
        else
        {
            if (!LowRes)
            {
                return;
            }
        }
        if (v >= 32)
        {
            if (!Transparency)
            {
                return;
            }
            ShaderVariantList.Add("VTRANSPARENCY_ON"); v -= 32; vc++;
        }
        else
        {
            if (!TransparencyOff)
            {
                return;
            }
        }
        if (v >= 16)
        {
            if (!DensityParticles)
            {
                return;
            }
            ShaderVariantList.Add("DENSITYPARTICLES_ON"); v -= 16; vc++;
        }
        if (v >= 8)
        {
            if (!HeightFog)
            {
                return;
            }
            ShaderVariantList.Add("HEIGHTFOG_ON"); v -= 8; vc++;
        }
        else
        {
            if (!HeightFogOff)
            {
                return;
            }
        }
        if (v >= 4)
        {
            if (!Noise)
            {
                return;
            }
            ShaderVariantList.Add("NOISE_ON"); v -= 4; vc++;
        }
        else
        {
            if (!NoiseOff)
            {
                return;
            }
        }
        if (v >= 2)
        {
            if (point)
            {
                ShaderVariantList.Add("POINT_COOKIE"); vc++;
            }
            v -= 2;
        }
        if (v >= 1)
        {
            v -= 1;
        }
        else
        {
            if (!projector)
            {
                ShaderVariantList.Add("SHADOWS_OFF");
            }
            vc++;
        };


        string[] fv = new string[vc];
        ShaderVariantList.CopyTo(fv);
        Material m = new Material(source);

        m.name = "";
        EnableKeywordList(m);

        AssetDatabase.AddObjectToAsset(m, collection);

        //string final = source.name + " ";
        //for (int s = 0; s < fv.Length; s++)
        //{
        //    final += fv[s] + " ";
        //}
        // Debug.Log(final);
        ShaderVariantCollection.ShaderVariant varient = new ShaderVariantCollection.ShaderVariant(source, PassType.Normal, fv);
        if (!collection.Contains(varient))
        {
            collection.Add(varient);
        }
        //if (shadows && !point && !projector)
        //{
        //    ShaderVariantList.Add("SHADOWS_NATIVE");
        //    string[] fv2 = new string[vc + 1];
        //    ShaderVariantList.CopyTo(fv2);
        //
        //    ShaderVariantCollection.ShaderVariant varient2 = new ShaderVariantCollection.ShaderVariant(source, PassType.Normal, fv2);
        //    if (!collection.Contains(varient2)) { collection.Add(varient2); }
        //
        //    Material m2 = new Material(source);
        //    EnableKeywordList(m2);
        //    m2.name = "";
        //    AssetDatabase.AddObjectToAsset(m2, collection);
        //    ShaderVariantList.RemoveAt(ShaderVariantList.Count - 1);
        //
        //
        //}

        if (SinglePassStereo)
        {
            ShaderVariantList.Add("UNITY_SINGLE_PASS_STEREO");
            string[] fvssp2 = new string[vc + 1];
            ShaderVariantList.CopyTo(fvssp2);

            ShaderVariantCollection.ShaderVariant varientSP = new ShaderVariantCollection.ShaderVariant(source, PassType.Normal, fvssp2); //Hier zit een error maar ik heb geen idee wat dus de gene die dit heeft geschreven check het!
            if (!collection.Contains(varientSP))
            {
                collection.Add(varientSP);
            }

            Material m2 = new Material(source);
            EnableKeywordList(m2);
            m2.name = "";
            AssetDatabase.AddObjectToAsset(m2, collection);

            // if (shadows && !point && !projector)
            // {
            //     ShaderVariantList.Add("SHADOWS_NATIVE");
            //     string[] fv2 = new string[vc + 2];
            //     ShaderVariantList.CopyTo(fv2);
            //
            //     ShaderVariantCollection.ShaderVariant varient2 = new ShaderVariantCollection.ShaderVariant(source, PassType.Normal, fv2);
            //     if (!collection.Contains(varient2)) { collection.Add(varient2); }
            //
            //     Material m3 = new Material(source);
            //     EnableKeywordList(m3);
            //     m3.name = "";
            //     AssetDatabase.AddObjectToAsset(m3, collection);
            //
            // }
        }
    }
Exemplo n.º 29
0
        /// <summary>
        /// 简单收集
        /// </summary>
        public static void CollectShaderVariant()
        {
            //先搜集所有keyword到工具类SVC
            ToolSVC = new ShaderVariantCollection();
            var shaders = AssetDatabase.FindAssets("t:Shader", new string[] { "Assets", "Packages" }).ToList();

            foreach (var shader in shaders)
            {
                ShaderVariantCollection.ShaderVariant sv = new ShaderVariantCollection.ShaderVariant();
                var shaderPath = AssetDatabase.GUIDToAssetPath(shader);
                sv.shader = AssetDatabase.LoadAssetAtPath <Shader>(shaderPath);
                ToolSVC.Add(sv);
                //
                allShaderNameList.Add(shaderPath);
            }


            //防空
            var dirt = Path.GetDirectoryName(toolsSVCpath);

            if (!Directory.Exists(dirt))
            {
                Directory.CreateDirectory(dirt);
            }

            AssetDatabase.CreateAsset(ToolSVC, toolsSVCpath);


            var paths = BApplication.GetAllRuntimeDirects().ToArray();
            //搜索所有runtime中所有可能挂载mat的地方
            var scriptObjectAssets = AssetDatabase.FindAssets("t:ScriptableObject", paths).ToList(); //自定义序列化脚本中也有可能有依赖
            var prefabAssets       = AssetDatabase.FindAssets("t:Prefab", paths).ToList();
            var matAssets          = AssetDatabase.FindAssets("t:Material", paths).ToList();


            //ERROR: 添加runtime中独立的shader,没有mat 视为其没有Shader_Featrue变体
            var shadertAssets = AssetDatabase.FindAssets("t:Shader", paths); //自定义序列化脚本中也有可能有依赖

            foreach (var guid in shadertAssets)
            {
                var path = AssetDatabase.GUIDToAssetPath(guid);
                Debug.LogError("不建议将shader放在runtime中,没有mat信息 无法搜集变体! " + path);
            }

            //搜索mat
            var guidList = new List <string>();

            guidList.AddRange(prefabAssets);
            guidList.AddRange(matAssets);
            guidList.AddRange(scriptObjectAssets);
            List <string> allMatPaths = new List <string>();

            //GUID to assetPath
            for (int i = 0; i < guidList.Count; i++)
            {
                var path = AssetDatabase.GUIDToAssetPath(guidList[i]);
                //获取依赖中的mat
                var dependenciesPath = AssetDatabase.GetDependencies(path, true);
                foreach (var dp in dependenciesPath)
                {
                    if (Path.GetExtension(dp).Equals(".mat", StringComparison.OrdinalIgnoreCase))
                    {
                        allMatPaths.Add(dp);
                    }
                    else if (Path.GetExtension(dp).Equals(".asset", StringComparison.OrdinalIgnoreCase)) //依赖的ScripttableObject,会
                    {
                        scriptObjectAssets.Add(AssetDatabase.AssetPathToGUID(dp));
                    }
                }
            }

            //ScripttableObject 里面有可能存mat信息
            foreach (var asset in scriptObjectAssets)
            {
                var path = AssetDatabase.GUIDToAssetPath(asset);
                var mat  = AssetDatabase.LoadAssetAtPath <Material>(path);
                if (mat != null)
                {
                    allMatPaths.Add(path);
                }
            }

            //开始收集ShaderVaraint
            allMatPaths = allMatPaths.Distinct().ToList();
            ShaderVariantCollection allShaderVaraint = null;
            var tools = new ShaderVariantsCollectionTools();

            allShaderVaraint = tools.CollectionKeywords(allMatPaths.ToArray(), ToolSVC);


            //输出SVC文件
            var targetDir = Path.GetDirectoryName(BResources.ALL_SHADER_VARAINT_ASSET_PATH);

            if (!Directory.Exists(targetDir))
            {
                Directory.CreateDirectory(targetDir);
            }

            AssetDatabase.DeleteAsset(BResources.ALL_SHADER_VARAINT_ASSET_PATH);
            AssetDatabase.CreateAsset(allShaderVaraint, BResources.ALL_SHADER_VARAINT_ASSET_PATH);
            AssetDatabase.Refresh();

            Debug.Log("<color=red>shader_features收集完毕,multi_compiles默认全打包需要继承IPreprocessShaders.OnProcessShader自行剔除!</color>");
            // var dependencies = AssetDatabase.GetDependencies(BResources.ALL_SHADER_VARAINT_ASSET_PATH);
            // foreach (var guid in dependencies )
            // {
            //     Debug.Log("依赖shader:" + guid);
            // }
        }
Exemplo n.º 30
0
    private void OnGUI()
    {
        EditorGUILayout.BeginVertical();
        if (shaderVariantCollection == null)
        {
            if (shaderVariantCollection == null)
            {
                shaderVariantCollection = new ShaderVariantCollection();
            }
        }
        for (int i = 0, c = SelectedFolder.Count; i < c; i++)
        {
            SelectedFolder[i] = AssetDatabase.GetAssetPath(EditorGUILayout.ObjectField(AssetDatabase.LoadMainAssetAtPath(SelectedFolder[i]), typeof(Object)));
        }
        if (GUILayout.Button("Add"))
        {
            SelectedFolder.Add(string.Empty);
        }


        if (GUILayout.Button("Collect variants"))
        {
            Dictionary <string, List <string> > shaderKeywordSupport           = new Dictionary <string, List <string> >();
            Dictionary <string, UnityEngine.Rendering.PassType> shaderPassType = new Dictionary <string, UnityEngine.Rendering.PassType>();
            var materials = AssetDatabase.FindAssets("t:Material", SelectedFolder.ToArray());
            shaderVariantCollection.Clear();
            for (int i = 0, c = materials.Length; i < c; i++)
            {
                var mat    = AssetDatabase.LoadAssetAtPath <Material>(AssetDatabase.GUIDToAssetPath(materials[i]));
                var shader = mat.shader;
                //Shader shaderNew = Instantiate(shader);
                //shaderNew.name = "test123";
                //AssetDatabase.CreateAsset(shaderNew, "Assets/shader.asset");
                var shaderPath = AssetDatabase.GetAssetPath(shader);
                UnityEngine.Rendering.PassType passType = UnityEngine.Rendering.PassType.ForwardBase;
                if (shaderPath.StartsWith(builtInShaderSrcPath))
                {
                    var shaderGuid = AssetDatabase.AssetPathToGUID(shaderPath);
                    if (!shaderKeywordSupport.ContainsKey(shaderGuid))
                    {
                        shaderKeywordSupport[shaderGuid] = new List <string>();
                        UnityEditor.SerializedObject so = new SerializedObject(shader);
                        var parsedForm = so.FindProperty("m_ParsedForm");
                        var subShaders = parsedForm.FindPropertyRelative("m_SubShaders");
                        var passes     = subShaders.GetArrayElementAtIndex(0).FindPropertyRelative("m_Passes");
                        //passType= passes.GetArrayElementAtIndex(0).FindPropertyRelative("m_Type").intValue;
                        var firstTag = passes.GetArrayElementAtIndex(0).FindPropertyRelative("m_State").FindPropertyRelative("m_Tags").FindPropertyRelative("tags").
                                       GetArrayElementAtIndex(0);

                        var tagIt = firstTag.GetEnumerator();
                        tagIt.MoveNext();
                        bool isLightMode = (tagIt.Current as SerializedProperty).stringValue == "LIGHTMODE";
                        tagIt.MoveNext();
                        var lightMode = (tagIt.Current as SerializedProperty).stringValue;
                        lightMode = lightMode.ToUpper();
                        // Debug.Log(lightMode);
                        if (isLightMode)
                        {
                            if (lightMode == "FORWARDBASE")
                            {
                                passType = UnityEngine.Rendering.PassType.ForwardBase;
                            }
                            else if (lightMode == "DEFERRED")
                            {
                                passType = UnityEngine.Rendering.PassType.Deferred;
                            }
                            else if (lightMode == "FORWARDADD")
                            {
                                passType = UnityEngine.Rendering.PassType.ForwardAdd;
                            }
                            else if (lightMode == "SHADOWCASTER")
                            {
                                passType = UnityEngine.Rendering.PassType.ShadowCaster;
                            }
                            else if (lightMode == "META")
                            {
                                passType = UnityEngine.Rendering.PassType.Meta;
                            }
                            else
                            {
                                passType = UnityEngine.Rendering.PassType.ForwardBase;
                            }
                        }
                        else
                        {
                            passType = UnityEngine.Rendering.PassType.Normal;
                        }
                        //var passType = subShader.FindPropertyRelative("m_SubShaders").GetArrayElementAtIndex(0).GetArrayElementAtIndex(0).FindPropertyRelative("m_Type");
                        //if (passType != null)
                        //{
                        //    Debug.Log("passType:" + passType.intValue);
                        //}
                        var it = so.GetIterator();
                        while (it.Next(true))
                        {
                            var prop = it;
                            if (prop.name == "m_BuiltinKeywords")
                            {
                                if (prop.isArray)
                                {
                                    // Debug.Log(prop.stringValue);
                                    var keywords = prop.stringValue.Split(" ");
                                    shaderKeywordSupport[shaderGuid].AddRange(keywords);
                                    //Debug.Log("m_BuiltinKeywords");
                                }
                            }
                            if (prop.name == "m_NonStrippedUserKeywords")
                            {
                                if (prop.isArray)
                                {
                                    // Debug.Log(prop.stringValue);
                                    var keywords = prop.stringValue.Split(" ");
                                    shaderKeywordSupport[shaderGuid].AddRange(keywords);
                                }
                            }

                            if (prop.name == "m_VariantsUser0")
                            {
                                if (prop.isArray)
                                {
                                    for (int propIdx = 0, propC = prop.arraySize; propIdx < propC; propIdx++)
                                    {
                                        var propVariant = prop.GetArrayElementAtIndex(propIdx);
                                        if (propVariant.isArray)
                                        {
                                            for (int childPropIdx = 0, childPropC = propVariant.arraySize; childPropIdx < childPropC; childPropIdx++)
                                            {
                                                var variantName = propVariant.GetArrayElementAtIndex(childPropIdx).stringValue;
                                                // Debug.Log(variantName);
                                                shaderKeywordSupport[shaderGuid].Add(variantName);
                                            }
                                        }
                                    }
                                }
                            }
                            if (prop.name == "keywordName")
                            {
                                // Debug.Log(prop.stringValue);
                                shaderKeywordSupport[shaderGuid].Add(prop.stringValue);
                            }


                            //if (prop.name == "m_CompileInfo")
                            //{
                            //    Debug.Log("m_CompileInfo");
                            //}
                        }
                        shaderPassType[shaderGuid] = passType;
                    }


                    List <string> matKeywords = new List <string>();
                    for (int matIdx = 0, matc = mat.shaderKeywords.Length; matIdx < matc; matIdx++)
                    {
                        var shaderMacro = mat.shaderKeywords[matIdx];
                        if (!string.IsNullOrEmpty(shaderMacro) && shaderKeywordSupport[shaderGuid].Contains(shaderMacro))
                        {
                            matKeywords.Add(shaderMacro);
                        }
                    }

                    if (matKeywords.Count > 0)
                    {
                        matKeywords.Add("DIRECTIONAL");
                    }
                    //matKeywords.Add(shaderPassType[shaderGuid].ToString());

                    foreach (var micro in matKeywords)
                    {
                        Debug.Log("$$ macro:" + micro);
                    }
                    ShaderVariantCollection.ShaderVariant shaderVariant = new ShaderVariantCollection.ShaderVariant(
                        shader, shaderPassType[shaderGuid], matKeywords.ToArray()
                        );

                    shaderVariantCollection.Add(shaderVariant);
                }
            }


            //Debug.Log(AssetDatabase.GetAssetPath(shaderVariantCollection));
            if (AssetDatabase.GetAssetPath(shaderVariantCollection) != "")
            {
                AssetDatabase.SaveAssets();
            }
            else
            {
                var filePath = UnityEditor.EditorUtility.SaveFilePanelInProject("save variant", "shaderVariantCollection", "asset", "Ok");
                AssetDatabase.CreateAsset(shaderVariantCollection, filePath);
            }
        }

        if (GUILayout.Button("Load"))
        {
            var filePath = UnityEditor.EditorUtility.OpenFilePanelWithFilters("load variant", "Assets", new string[] { "ShaderVariantCollection", "asset" });
            shaderVariantCollection = AssetDatabase.LoadAssetAtPath <ShaderVariantCollection>(filePath);
        }
        EditorGUILayout.EndVertical();
    }