No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SubGraphAsset.cs 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using System;
  2. using System.Collections.Generic;
  3. #if UNITY_2020_2_OR_NEWER
  4. using UnityEditor.AssetImporters;
  5. #else
  6. using UnityEditor.Experimental.AssetImporters;
  7. #endif
  8. using UnityEditor.Graphing;
  9. using UnityEditor.ShaderGraph.Internal;
  10. using UnityEditor.ShaderGraph.Serialization;
  11. using UnityEngine;
  12. namespace UnityEditor.ShaderGraph
  13. {
  14. [Serializable]
  15. struct FunctionPair
  16. {
  17. public string key; // aka function name
  18. public string value; // aka function code
  19. public int graphPrecisionFlags; // Flags<GraphPrecision> indicating which precision variants are requested by the subgraph
  20. public FunctionPair(string key, string value, int graphPrecisionFlags)
  21. {
  22. this.key = key;
  23. this.value = value;
  24. this.graphPrecisionFlags = graphPrecisionFlags;
  25. }
  26. }
  27. [Serializable]
  28. class SlotCapability
  29. {
  30. public string slotName;
  31. public ShaderStageCapability capabilities = ShaderStageCapability.All;
  32. }
  33. [Serializable]
  34. class SlotDependencyPair
  35. {
  36. public string inputSlotName;
  37. public string outputSlotName;
  38. }
  39. /// Cached run-time information for slot dependency tracking within a sub-graph
  40. class SlotDependencyInfo
  41. {
  42. internal string slotName;
  43. internal ShaderStageCapability capabilities = ShaderStageCapability.All;
  44. internal HashSet<string> dependencies = new HashSet<string>();
  45. internal void AddDepencencySlotName(string slotName)
  46. {
  47. dependencies.Add(slotName);
  48. }
  49. internal bool ContainsSlot(MaterialSlot slot)
  50. {
  51. return dependencies.Contains(slot.RawDisplayName());
  52. }
  53. }
  54. class SubGraphData : JsonObject
  55. {
  56. public List<JsonData<AbstractShaderProperty>> inputs = new List<JsonData<AbstractShaderProperty>>();
  57. public List<JsonData<ShaderKeyword>> keywords = new List<JsonData<ShaderKeyword>>();
  58. public List<JsonData<ShaderDropdown>> dropdowns = new List<JsonData<ShaderDropdown>>();
  59. public List<JsonData<AbstractShaderProperty>> nodeProperties = new List<JsonData<AbstractShaderProperty>>();
  60. public List<JsonData<MaterialSlot>> outputs = new List<JsonData<MaterialSlot>>();
  61. public List<JsonData<Target>> unsupportedTargets = new List<JsonData<Target>>();
  62. }
  63. class SubGraphAsset : ScriptableObject, ISerializationCallbackReceiver
  64. {
  65. public bool isValid;
  66. public long processedAt;
  67. public string functionName;
  68. public string inputStructName;
  69. public string hlslName;
  70. public string assetGuid;
  71. public ShaderGraphRequirements requirements;
  72. public string path;
  73. public List<FunctionPair> functions = new List<FunctionPair>();
  74. public IncludeCollection includes;
  75. public List<string> vtFeedbackVariables = new List<string>();
  76. private SubGraphData m_SubGraphData;
  77. [HideInInspector]
  78. [SerializeField]
  79. private SerializationHelper.JSONSerializedElement m_SerializedSubGraphData;
  80. public DataValueEnumerable<AbstractShaderProperty> inputs => m_SubGraphData.inputs.SelectValue();
  81. public DataValueEnumerable<ShaderKeyword> keywords => m_SubGraphData.keywords.SelectValue();
  82. public DataValueEnumerable<ShaderDropdown> dropdowns => m_SubGraphData.dropdowns.SelectValue();
  83. public DataValueEnumerable<AbstractShaderProperty> nodeProperties => m_SubGraphData.nodeProperties.SelectValue();
  84. public DataValueEnumerable<MaterialSlot> outputs => m_SubGraphData.outputs.SelectValue();
  85. public DataValueEnumerable<Target> unsupportedTargets => m_SubGraphData.unsupportedTargets.SelectValue();
  86. public List<string> children = new List<string>(); // guids of direct USED SUBGRAPH file dependencies
  87. public List<string> descendents = new List<string>(); // guids of ALL file dependencies at any level, SHOULD LIST EVEN MISSING DESCENDENTS
  88. public List<SlotCapability> inputCapabilities = new List<SlotCapability>();
  89. public List<SlotCapability> outputCapabilities = new List<SlotCapability>();
  90. // Every unique input/output dependency pair
  91. public List<SlotDependencyPair> slotDependencies = new List<SlotDependencyPair>();
  92. Dictionary<string, SlotDependencyInfo> m_InputDependencies = new Dictionary<string, SlotDependencyInfo>();
  93. Dictionary<string, SlotDependencyInfo> m_OutputDependencies = new Dictionary<string, SlotDependencyInfo>();
  94. public SlotDependencyInfo GetInputDependencies(string slotName)
  95. {
  96. m_InputDependencies.TryGetValue(slotName, out SlotDependencyInfo result);
  97. return result;
  98. }
  99. public SlotDependencyInfo GetOutputDependencies(string slotName)
  100. {
  101. m_OutputDependencies.TryGetValue(slotName, out SlotDependencyInfo result);
  102. return result;
  103. }
  104. // this is the precision that the entire subgraph is set to (indicates whether the graph is hard-coded or switchable)
  105. public GraphPrecision subGraphGraphPrecision;
  106. // this is the precision of the subgraph outputs
  107. // NOTE: this may not be the same as subGraphGraphPrecision
  108. // for example, a graph could allow switching precisions for internal calculations,
  109. // but the output of the graph is always full float
  110. // NOTE: we don't currently have a way to select the graph precision for EACH output
  111. // there's a single shared precision for all of them
  112. public GraphPrecision outputGraphPrecision;
  113. public PreviewMode previewMode;
  114. public void WriteData(IEnumerable<AbstractShaderProperty> inputs, IEnumerable<ShaderKeyword> keywords, IEnumerable<ShaderDropdown> dropdowns, IEnumerable<AbstractShaderProperty> nodeProperties, IEnumerable<MaterialSlot> outputs, IEnumerable<Target> unsupportedTargets)
  115. {
  116. if (m_SubGraphData == null)
  117. {
  118. m_SubGraphData = new SubGraphData();
  119. m_SubGraphData.OverrideObjectId(assetGuid, "_subGraphData");
  120. }
  121. m_SubGraphData.inputs.Clear();
  122. m_SubGraphData.keywords.Clear();
  123. m_SubGraphData.dropdowns.Clear();
  124. m_SubGraphData.nodeProperties.Clear();
  125. m_SubGraphData.outputs.Clear();
  126. m_SubGraphData.unsupportedTargets.Clear();
  127. foreach (var input in inputs)
  128. {
  129. m_SubGraphData.inputs.Add(input);
  130. }
  131. foreach (var keyword in keywords)
  132. {
  133. m_SubGraphData.keywords.Add(keyword);
  134. }
  135. foreach (var dropdown in dropdowns)
  136. {
  137. m_SubGraphData.dropdowns.Add(dropdown);
  138. }
  139. foreach (var nodeProperty in nodeProperties)
  140. {
  141. m_SubGraphData.nodeProperties.Add(nodeProperty);
  142. }
  143. foreach (var output in outputs)
  144. {
  145. m_SubGraphData.outputs.Add(output);
  146. }
  147. foreach (var unsupportedTarget in unsupportedTargets)
  148. {
  149. m_SubGraphData.unsupportedTargets.Add(unsupportedTarget);
  150. }
  151. var json = MultiJson.Serialize(m_SubGraphData);
  152. m_SerializedSubGraphData = new SerializationHelper.JSONSerializedElement() { JSONnodeData = json };
  153. m_SubGraphData = null;
  154. }
  155. public void OnBeforeSerialize()
  156. {
  157. }
  158. public void OnAfterDeserialize()
  159. {
  160. }
  161. public void LoadGraphData()
  162. {
  163. m_SubGraphData = new SubGraphData();
  164. if (!String.IsNullOrEmpty(m_SerializedSubGraphData.JSONnodeData))
  165. {
  166. MultiJson.Deserialize(m_SubGraphData, m_SerializedSubGraphData.JSONnodeData);
  167. }
  168. }
  169. internal void LoadDependencyData()
  170. {
  171. m_InputDependencies.Clear();
  172. m_OutputDependencies.Clear();
  173. foreach (var capabilityInfo in inputCapabilities)
  174. {
  175. var dependencyInfo = new SlotDependencyInfo();
  176. dependencyInfo.slotName = capabilityInfo.slotName;
  177. dependencyInfo.capabilities = capabilityInfo.capabilities;
  178. if (m_InputDependencies.ContainsKey(dependencyInfo.slotName))
  179. {
  180. Debug.LogWarning($"SubGraph '{hlslName}' has multiple input slots named '{dependencyInfo.slotName}', which is unsupported. Please assign the input slots unique names.");
  181. continue;
  182. }
  183. m_InputDependencies.Add(dependencyInfo.slotName, dependencyInfo);
  184. }
  185. foreach (var capabilityInfo in outputCapabilities)
  186. {
  187. var dependencyInfo = new SlotDependencyInfo();
  188. dependencyInfo.slotName = capabilityInfo.slotName;
  189. dependencyInfo.capabilities = capabilityInfo.capabilities;
  190. if (m_OutputDependencies.ContainsKey(dependencyInfo.slotName))
  191. {
  192. Debug.LogWarning($"SubGraph '{hlslName}' has multiple output slots named '{dependencyInfo.slotName}', which is unsupported. Please assign the output slots unique names.");
  193. continue;
  194. }
  195. m_OutputDependencies.Add(dependencyInfo.slotName, dependencyInfo);
  196. }
  197. foreach (var slotDependency in slotDependencies)
  198. {
  199. // This shouldn't fail since every input/output must be in the above lists...
  200. if (m_InputDependencies.ContainsKey(slotDependency.inputSlotName))
  201. m_InputDependencies[slotDependency.inputSlotName].AddDepencencySlotName(slotDependency.outputSlotName);
  202. if (m_OutputDependencies.ContainsKey(slotDependency.outputSlotName))
  203. m_OutputDependencies[slotDependency.outputSlotName].AddDepencencySlotName(slotDependency.inputSlotName);
  204. }
  205. }
  206. }
  207. }