暫無描述
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.

ShaderInput.cs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEditor.Graphing;
  4. using UnityEditor.ShaderGraph.Drawing;
  5. using UnityEditor.ShaderGraph.Serialization;
  6. using UnityEngine;
  7. namespace UnityEditor.ShaderGraph.Internal
  8. {
  9. public abstract class ShaderInput : JsonObject
  10. {
  11. [SerializeField]
  12. SerializableGuid m_Guid = new SerializableGuid();
  13. internal Guid guid => m_Guid.guid;
  14. internal void OverrideGuid(string namespaceId, string name) { m_Guid.guid = GenerateNamespaceUUID(namespaceId, name); }
  15. [SerializeField]
  16. string m_Name;
  17. public string displayName
  18. {
  19. get
  20. {
  21. if (string.IsNullOrEmpty(m_Name))
  22. return $"{concreteShaderValueType}_{objectId}";
  23. return m_Name;
  24. }
  25. set
  26. {
  27. // this is a raw set of the display name
  28. // if you want to a fully graph-connected set-and-sanitize-and-update,
  29. // call SetDisplayNameAndSanitizeForGraph() instead
  30. m_Name = value;
  31. }
  32. }
  33. internal void AddObserver(IShaderInputObserver observer)
  34. {
  35. m_InputObservers.Add(observer);
  36. }
  37. internal void RemoveObserver(IShaderInputObserver observer)
  38. {
  39. m_InputObservers.Remove(observer);
  40. }
  41. internal void ClearObservers()
  42. {
  43. m_InputObservers.Clear();
  44. }
  45. internal HashSet<IShaderInputObserver> InputObservers => m_InputObservers;
  46. HashSet<IShaderInputObserver> m_InputObservers = new();
  47. // sanitizes the desired name according to the current graph, and assigns it as the display name
  48. // also calls the update trigger to update other bits of the graph UI that use the name
  49. internal void SetDisplayNameAndSanitizeForGraph(GraphData graphData, string desiredName = null)
  50. {
  51. string originalDisplayName = displayName;
  52. // if no desired name passed in, sanitize the current name
  53. if (desiredName == null)
  54. desiredName = originalDisplayName;
  55. var sanitizedName = graphData.SanitizeGraphInputName(this, desiredName);
  56. bool changed = (originalDisplayName != sanitizedName);
  57. // only assign if it was changed
  58. if (changed)
  59. m_Name = sanitizedName;
  60. // update the default reference name
  61. UpdateDefaultReferenceName(graphData);
  62. }
  63. internal void SetReferenceNameAndSanitizeForGraph(GraphData graphData, string desiredRefName = null)
  64. {
  65. string originalRefName = referenceName;
  66. // if no desired ref name, use the current name
  67. if (string.IsNullOrEmpty(desiredRefName))
  68. desiredRefName = originalRefName;
  69. // sanitize and deduplicate the desired name
  70. var sanitizedRefName = graphData.SanitizeGraphInputReferenceName(this, desiredRefName);
  71. // check if the final result is different from the current name
  72. bool changed = (originalRefName != sanitizedRefName);
  73. // if changed, then set the new name up as an override
  74. if (changed)
  75. overrideReferenceName = sanitizedRefName;
  76. }
  77. // resets the reference name to a "default" value (deduplicated against existing reference names)
  78. // returns the new default reference name
  79. internal string ResetReferenceName(GraphData graphData)
  80. {
  81. overrideReferenceName = null;
  82. // because we are clearing an override, we must force a sanitization pass on the default ref name
  83. // as there may now be collisions that didn't previously exist
  84. UpdateDefaultReferenceName(graphData, true);
  85. return referenceName;
  86. }
  87. internal void UpdateDefaultReferenceName(GraphData graphData, bool forceSanitize = false)
  88. {
  89. if (m_DefaultRefNameVersion <= 0)
  90. return; // old version is updated in the getter
  91. if (forceSanitize ||
  92. string.IsNullOrEmpty(m_DefaultReferenceName) ||
  93. (m_RefNameGeneratedByDisplayName != displayName))
  94. {
  95. // Make sure all reference names are consistently auto-generated with a pre-pended underscore (if they can be renamed)
  96. var targetRefName = displayName;
  97. if (this.isReferenceRenamable && !targetRefName.StartsWith("_"))
  98. targetRefName = "_" + targetRefName;
  99. m_DefaultReferenceName = graphData.SanitizeGraphInputReferenceName(this, targetRefName);
  100. m_RefNameGeneratedByDisplayName = displayName;
  101. }
  102. }
  103. const int k_LatestDefaultRefNameVersion = 1;
  104. // this is used to know whether this shader input is using:
  105. // 0) the "old" default reference naming scheme (type + GUID)
  106. // 1) the new default reference naming scheme (make it similar to the display name)
  107. [SerializeField]
  108. int m_DefaultRefNameVersion = k_LatestDefaultRefNameVersion;
  109. [SerializeField]
  110. string m_RefNameGeneratedByDisplayName; // used to tell what was the display name used to generate the default reference name
  111. [SerializeField]
  112. string m_DefaultReferenceName; // NOTE: this can be NULL for old graphs, or newly created properties
  113. public string referenceName
  114. {
  115. get
  116. {
  117. if (string.IsNullOrEmpty(overrideReferenceName))
  118. {
  119. if (m_DefaultRefNameVersion == 0)
  120. {
  121. if (string.IsNullOrEmpty(m_DefaultReferenceName))
  122. m_DefaultReferenceName = GetOldDefaultReferenceName();
  123. return m_DefaultReferenceName;
  124. }
  125. else // version 1
  126. {
  127. // default reference name is updated elsewhere in the new naming scheme
  128. return m_DefaultReferenceName;
  129. }
  130. }
  131. return overrideReferenceName;
  132. }
  133. }
  134. public virtual string referenceNameForEditing => referenceName;
  135. public override void OnBeforeDeserialize()
  136. {
  137. // if serialization doesn't write to m_DefaultRefNameVersion, then it is an old shader input, and should use the old default naming scheme
  138. m_DefaultRefNameVersion = 0;
  139. base.OnBeforeDeserialize();
  140. }
  141. // This is required to handle Material data serialized with "_Color_GUID" reference names
  142. // m_DefaultReferenceName expects to match the material data and previously used PropertyType
  143. // ColorShaderProperty is the only case where PropertyType doesn't match ConcreteSlotValueType
  144. public virtual string GetOldDefaultReferenceName()
  145. {
  146. return $"{concreteShaderValueType.ToString()}_{objectId}";
  147. }
  148. // returns true if this shader input is CURRENTLY using the old default reference name
  149. public bool IsUsingOldDefaultRefName()
  150. {
  151. return string.IsNullOrEmpty(overrideReferenceName) && (m_DefaultRefNameVersion == 0);
  152. }
  153. // returns true if this shader input is CURRENTLY using the new default reference name
  154. public bool IsUsingNewDefaultRefName()
  155. {
  156. return string.IsNullOrEmpty(overrideReferenceName) && (m_DefaultRefNameVersion >= 1);
  157. }
  158. // upgrades the default reference name to use the new naming scheme
  159. internal string UpgradeDefaultReferenceName(GraphData graphData)
  160. {
  161. m_DefaultRefNameVersion = k_LatestDefaultRefNameVersion;
  162. m_DefaultReferenceName = null;
  163. m_RefNameGeneratedByDisplayName = null;
  164. UpdateDefaultReferenceName(graphData, true); // make sure to sanitize the new default
  165. return referenceName;
  166. }
  167. [SerializeField]
  168. string m_OverrideReferenceName;
  169. internal string overrideReferenceName
  170. {
  171. get => m_OverrideReferenceName;
  172. set => m_OverrideReferenceName = value;
  173. }
  174. [SerializeField]
  175. bool m_GeneratePropertyBlock = true;
  176. internal bool generatePropertyBlock // this is basically the "exposed" toggle
  177. {
  178. get => m_GeneratePropertyBlock;
  179. set => m_GeneratePropertyBlock = value;
  180. }
  181. internal virtual bool isExposed => isExposable && generatePropertyBlock;
  182. public virtual bool allowedInSubGraph
  183. {
  184. get { return true; }
  185. }
  186. public virtual bool allowedInMainGraph
  187. {
  188. get { return true; }
  189. }
  190. internal abstract ConcreteSlotValueType concreteShaderValueType { get; }
  191. internal abstract bool isExposable { get; }
  192. internal virtual bool isAlwaysExposed => false;
  193. // this controls whether the UI allows the user to rename the display and reference names
  194. internal abstract bool isRenamable { get; }
  195. internal virtual bool isReferenceRenamable => isRenamable;
  196. internal virtual bool isCustomSlotAllowed => true;
  197. [SerializeField]
  198. bool m_UseCustomSlotLabel = false;
  199. [SerializeField]
  200. string m_CustomSlotLabel;
  201. internal bool useCustomSlotLabel
  202. {
  203. get => m_UseCustomSlotLabel;
  204. set => m_UseCustomSlotLabel = value;
  205. }
  206. internal string customSlotLabel
  207. {
  208. get => m_CustomSlotLabel;
  209. set => m_CustomSlotLabel = value;
  210. }
  211. [SerializeField]
  212. protected int m_DismissedVersion = 0;
  213. public int dismissedUpdateVersion { get => m_DismissedVersion; set => m_DismissedVersion = value; }
  214. internal bool isConnectionTestable
  215. {
  216. get => m_UseCustomSlotLabel;
  217. }
  218. static internal string GetConnectionStateVariableName(string variableName)
  219. {
  220. return variableName + "_IsConnected";
  221. }
  222. internal abstract ShaderInput Copy();
  223. internal virtual void OnBeforePasteIntoGraph(GraphData graph) { }
  224. }
  225. }