MasterNode.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor.Graphing;
  5. using UnityEditor.Graphing.Util;
  6. using UnityEngine;
  7. using UnityEngine.Rendering;
  8. using UnityEngine.UIElements;
  9. using UnityEditor.ShaderGraph.Drawing.Controls;
  10. namespace UnityEditor.ShaderGraph
  11. {
  12. abstract class MasterNode : AbstractMaterialNode, IMasterNode, IHasSettings
  13. {
  14. public override bool hasPreview
  15. {
  16. get { return false; }
  17. }
  18. public override bool allowedInSubGraph
  19. {
  20. get { return false; }
  21. }
  22. public override PreviewMode previewMode
  23. {
  24. get { return PreviewMode.Preview3D; }
  25. }
  26. [SerializeField]
  27. bool m_DOTSInstancing = false;
  28. public ToggleData dotsInstancing
  29. {
  30. get { return new ToggleData(m_DOTSInstancing); }
  31. set
  32. {
  33. if (m_DOTSInstancing == value.isOn)
  34. return;
  35. m_DOTSInstancing = value.isOn;
  36. Dirty(ModificationScope.Graph);
  37. }
  38. }
  39. public abstract string GetShader(GenerationMode mode, string outputName, out List<PropertyCollector.TextureInfo> configuredTextures, List<string> sourceAssetDependencyPaths = null);
  40. public abstract bool IsPipelineCompatible(RenderPipelineAsset renderPipelineAsset);
  41. public abstract int GetPreviewPassIndex();
  42. public VisualElement CreateSettingsElement()
  43. {
  44. var container = new VisualElement();
  45. var commonSettingsElement = CreateCommonSettingsElement();
  46. if (commonSettingsElement != null)
  47. container.Add(commonSettingsElement);
  48. return container;
  49. }
  50. protected virtual VisualElement CreateCommonSettingsElement()
  51. {
  52. return null;
  53. }
  54. public virtual object saveContext => null;
  55. public virtual void ProcessPreviewMaterial(Material Material) {}
  56. }
  57. [Serializable]
  58. abstract class MasterNode<T> : MasterNode
  59. where T : class, ISubShader
  60. {
  61. [NonSerialized]
  62. List<T> m_SubShaders = new List<T>();
  63. [SerializeField]
  64. List<SerializationHelper.JSONSerializedElement> m_SerializableSubShaders = new List<SerializationHelper.JSONSerializedElement>();
  65. public IEnumerable<T> subShaders => m_SubShaders;
  66. public void AddSubShader(T subshader)
  67. {
  68. if (m_SubShaders.Contains(subshader))
  69. return;
  70. m_SubShaders.Add(subshader);
  71. Dirty(ModificationScope.Graph);
  72. }
  73. public void RemoveSubShader(T subshader)
  74. {
  75. m_SubShaders.RemoveAll(x => x == subshader);
  76. Dirty(ModificationScope.Graph);
  77. }
  78. public ISubShader GetActiveSubShader()
  79. {
  80. foreach (var subShader in m_SubShaders)
  81. {
  82. if (subShader.IsPipelineCompatible(GraphicsSettings.renderPipelineAsset))
  83. return subShader;
  84. }
  85. return null;
  86. }
  87. public sealed override string GetShader(GenerationMode mode, string outputName, out List<PropertyCollector.TextureInfo> configuredTextures, List<string> sourceAssetDependencyPaths = null)
  88. {
  89. var activeNodeList = Graphing.ListPool<AbstractMaterialNode>.Get();
  90. NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this);
  91. var shaderProperties = new PropertyCollector();
  92. var shaderKeywords = new KeywordCollector();
  93. if (owner != null)
  94. {
  95. owner.CollectShaderProperties(shaderProperties, mode);
  96. owner.CollectShaderKeywords(shaderKeywords, mode);
  97. }
  98. if(owner.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit)
  99. {
  100. owner.AddValidationError(tempId, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error);
  101. configuredTextures = shaderProperties.GetConfiguredTexutres();
  102. return ShaderGraphImporter.k_ErrorShader;
  103. }
  104. foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
  105. activeNode.CollectShaderProperties(shaderProperties, mode);
  106. var finalShader = new ShaderStringBuilder();
  107. finalShader.AppendLine(@"Shader ""{0}""", outputName);
  108. using (finalShader.BlockScope())
  109. {
  110. SubShaderGenerator.GeneratePropertiesBlock(finalShader, shaderProperties, shaderKeywords, mode);
  111. foreach (var subShader in m_SubShaders)
  112. {
  113. if (mode != GenerationMode.Preview || subShader.IsPipelineCompatible(GraphicsSettings.renderPipelineAsset))
  114. finalShader.AppendLines(subShader.GetSubshader(this, mode, sourceAssetDependencyPaths));
  115. }
  116. finalShader.AppendLine(@"FallBack ""Hidden/Shader Graph/FallbackError""");
  117. }
  118. configuredTextures = shaderProperties.GetConfiguredTexutres();
  119. return finalShader.ToString();
  120. }
  121. public sealed override bool IsPipelineCompatible(RenderPipelineAsset renderPipelineAsset)
  122. {
  123. foreach (var subShader in m_SubShaders)
  124. {
  125. if (subShader.IsPipelineCompatible(GraphicsSettings.renderPipelineAsset))
  126. return true;
  127. }
  128. return false;
  129. }
  130. public sealed override int GetPreviewPassIndex()
  131. {
  132. return GetActiveSubShader()?.GetPreviewPassIndex() ?? 0;
  133. }
  134. public override void OnBeforeSerialize()
  135. {
  136. base.OnBeforeSerialize();
  137. m_SerializableSubShaders = SerializationHelper.Serialize<T>(m_SubShaders);
  138. }
  139. public override void OnAfterDeserialize()
  140. {
  141. m_SubShaders = SerializationHelper.Deserialize<T>(m_SerializableSubShaders, GraphUtil.GetLegacyTypeRemapping());
  142. m_SubShaders.RemoveAll(x => x == null);
  143. m_SerializableSubShaders = null;
  144. base.OnAfterDeserialize();
  145. }
  146. public override void UpdateNodeAfterDeserialization()
  147. {
  148. base.UpdateNodeAfterDeserialization();
  149. foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
  150. {
  151. foreach (var type in assembly.GetTypesOrNothing())
  152. {
  153. var isValid = !type.IsAbstract && !type.IsGenericType && type.IsClass && typeof(T).IsAssignableFrom(type);
  154. if (isValid && !subShaders.Any(s => s.GetType() == type))
  155. {
  156. try
  157. {
  158. var subShader = (T)Activator.CreateInstance(type);
  159. AddSubShader(subShader);
  160. }
  161. catch (Exception e)
  162. {
  163. Debug.LogException(e);
  164. }
  165. }
  166. }
  167. }
  168. }
  169. }
  170. }