/// <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); }
/// <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); }
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); }
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())); } }
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())); } }
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(); }
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); }
private void AddShaderVariantFromShaderList(ShaderVariantCollection _svc, List <ShaderVariantCollection.ShaderVariant> svList) { foreach (var sv in svList) { if (!_svc.Contains(sv)) { //存在しないので追加 _svc.Add(sv); } } }
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(); }
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 }
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 } } }
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(); }
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); } } }
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; }
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)); }); }
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); } } } }
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); }
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(); }
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); }
/// <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(); }
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); // // } } }
/// <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); // } }
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(); }