ShaderVariantCollectionManifest.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using UnityEngine;
  7. using UnityEngine.Rendering;
  8. using UnityEditor;
  9. namespace YooAsset.Editor
  10. {
  11. [Serializable]
  12. public class ShaderVariantCollectionManifest
  13. {
  14. [Serializable]
  15. public class ShaderVariantElement
  16. {
  17. /// <summary>
  18. /// Pass type to use in this variant.
  19. /// </summary>
  20. public PassType PassType;
  21. /// <summary>
  22. /// Array of shader keywords to use in this variant.
  23. /// </summary>
  24. public string[] Keywords;
  25. }
  26. [Serializable]
  27. public class ShaderVariantInfo
  28. {
  29. /// <summary>
  30. /// Shader asset path in editor.
  31. /// </summary>
  32. public string AssetPath;
  33. /// <summary>
  34. /// Shader name.
  35. /// </summary>
  36. public string ShaderName;
  37. /// <summary>
  38. /// Shader variants elements list.
  39. /// </summary>
  40. public List<ShaderVariantElement> ShaderVariantElements = new List<ShaderVariantElement>(1000);
  41. }
  42. /// <summary>
  43. /// Number of shaders in this collection
  44. /// </summary>
  45. public int ShaderTotalCount;
  46. /// <summary>
  47. /// Number of total varians in this collection
  48. /// </summary>
  49. public int VariantTotalCount;
  50. /// <summary>
  51. /// Shader variants info list.
  52. /// </summary>
  53. public List<ShaderVariantInfo> ShaderVariantInfos = new List<ShaderVariantInfo>(1000);
  54. /// <summary>
  55. /// 添加着色器变种信息
  56. /// </summary>
  57. public void AddShaderVariant(string assetPath, string shaderName, PassType passType, string[] keywords)
  58. {
  59. var info = GetOrCreateShaderVariantInfo(assetPath, shaderName);
  60. ShaderVariantElement element = new ShaderVariantElement();
  61. element.PassType = passType;
  62. element.Keywords = keywords;
  63. info.ShaderVariantElements.Add(element);
  64. }
  65. private ShaderVariantInfo GetOrCreateShaderVariantInfo(string assetPath, string shaderName)
  66. {
  67. var selectList = ShaderVariantInfos.Where(t => t.ShaderName == shaderName && t.AssetPath == assetPath).ToList();
  68. if (selectList.Count == 0)
  69. {
  70. ShaderVariantInfo newInfo = new ShaderVariantInfo();
  71. newInfo.AssetPath = assetPath;
  72. newInfo.ShaderName = shaderName;
  73. ShaderVariantInfos.Add(newInfo);
  74. return newInfo;
  75. }
  76. if (selectList.Count != 1)
  77. throw new Exception("Should never get here !");
  78. return selectList[0];
  79. }
  80. /// <summary>
  81. /// 解析SVC文件并将数据写入到清单
  82. /// </summary>
  83. public static ShaderVariantCollectionManifest Extract(ShaderVariantCollection svc)
  84. {
  85. var manifest = new ShaderVariantCollectionManifest();
  86. manifest.ShaderTotalCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionShaderCount();
  87. manifest.VariantTotalCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionVariantCount();
  88. using (var so = new SerializedObject(svc))
  89. {
  90. var shaderArray = so.FindProperty("m_Shaders.Array");
  91. if (shaderArray != null && shaderArray.isArray)
  92. {
  93. for (int i = 0; i < shaderArray.arraySize; ++i)
  94. {
  95. var shaderRef = shaderArray.FindPropertyRelative($"data[{i}].first");
  96. var shaderVariantsArray = shaderArray.FindPropertyRelative($"data[{i}].second.variants");
  97. if (shaderRef != null && shaderRef.propertyType == SerializedPropertyType.ObjectReference && shaderVariantsArray != null && shaderVariantsArray.isArray)
  98. {
  99. var shader = shaderRef.objectReferenceValue as Shader;
  100. if (shader == null)
  101. {
  102. throw new Exception("Invalid shader in ShaderVariantCollection file.");
  103. }
  104. string shaderAssetPath = AssetDatabase.GetAssetPath(shader);
  105. string shaderName = shader.name;
  106. // 添加变种信息
  107. for (int j = 0; j < shaderVariantsArray.arraySize; ++j)
  108. {
  109. var propKeywords = shaderVariantsArray.FindPropertyRelative($"Array.data[{j}].keywords");
  110. var propPassType = shaderVariantsArray.FindPropertyRelative($"Array.data[{j}].passType");
  111. if (propKeywords != null && propPassType != null && propKeywords.propertyType == SerializedPropertyType.String)
  112. {
  113. string[] keywords = propKeywords.stringValue.Split(' ');
  114. PassType pathType = (PassType)propPassType.intValue;
  115. manifest.AddShaderVariant(shaderAssetPath, shaderName, pathType, keywords);
  116. }
  117. }
  118. }
  119. }
  120. }
  121. }
  122. return manifest;
  123. }
  124. }
  125. }