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.

272 lines
7.0 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEditor;
  7. namespace AmplifyShaderEditor
  8. {
  9. [Serializable]
  10. public class TemplateNodeParent : ParentNode
  11. {
  12. protected const string ErrorMessageStr = "This node can only be used inside a Template category!";
  13. protected const string DataLabelStr = "Data";
  14. protected const string SubShaderStr = "SubShader";
  15. protected const string PassStr = "Pass";
  16. [SerializeField]
  17. private int m_subShaderIdx = 0;
  18. [SerializeField]
  19. private int m_passIdx = 0;
  20. [SerializeField]
  21. private int m_passLocalArrayIdx = 0;
  22. [SerializeField]
  23. protected bool m_multiPassMode = false;
  24. [SerializeField]
  25. protected string[] m_availableSubshaders;
  26. [SerializeField]
  27. protected string[] m_availablePassesLabels;
  28. [SerializeField]
  29. protected int[] m_availablePassesValues;
  30. [NonSerialized]
  31. protected TemplateMultiPass m_templateMPData = null;
  32. protected bool m_createAllOutputs = true;
  33. protected override void CommonInit( int uniqueId )
  34. {
  35. base.CommonInit( uniqueId );
  36. AddOutputPort( WirePortDataType.FLOAT, "Out" );
  37. if( m_createAllOutputs )
  38. {
  39. AddOutputPort( WirePortDataType.FLOAT, "X" );
  40. AddOutputPort( WirePortDataType.FLOAT, "Y" );
  41. AddOutputPort( WirePortDataType.FLOAT, "Z" );
  42. AddOutputPort( WirePortDataType.FLOAT, "W" );
  43. }
  44. m_textLabelWidth = 67;
  45. m_hasLeftDropdown = true;
  46. }
  47. public override void AfterCommonInit()
  48. {
  49. base.AfterCommonInit();
  50. if( PaddingTitleLeft == 0 )
  51. {
  52. PaddingTitleLeft = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin;
  53. if( PaddingTitleRight == 0 )
  54. PaddingTitleRight = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin;
  55. }
  56. }
  57. protected void ConfigurePorts()
  58. {
  59. switch( m_outputPorts[ 0 ].DataType )
  60. {
  61. default:
  62. {
  63. for( int i = 1; i < 5; i++ )
  64. {
  65. m_outputPorts[ i ].Visible = false;
  66. }
  67. }
  68. break;
  69. case WirePortDataType.FLOAT2:
  70. {
  71. for( int i = 1; i < 5; i++ )
  72. {
  73. m_outputPorts[ i ].Visible = ( i < 3 );
  74. if( m_outputPorts[ i ].Visible )
  75. {
  76. m_outputPorts[ i ].Name = Constants.ChannelNamesVector[ i - 1 ];
  77. }
  78. }
  79. }
  80. break;
  81. case WirePortDataType.FLOAT3:
  82. {
  83. for( int i = 1; i < 5; i++ )
  84. {
  85. m_outputPorts[ i ].Visible = ( i < 4 );
  86. if( m_outputPorts[ i ].Visible )
  87. {
  88. m_outputPorts[ i ].Name = Constants.ChannelNamesVector[ i - 1 ];
  89. }
  90. }
  91. }
  92. break;
  93. case WirePortDataType.FLOAT4:
  94. {
  95. for( int i = 1; i < 5; i++ )
  96. {
  97. m_outputPorts[ i ].Visible = true;
  98. m_outputPorts[ i ].Name = Constants.ChannelNamesVector[ i - 1 ];
  99. }
  100. }
  101. break;
  102. case WirePortDataType.COLOR:
  103. {
  104. for( int i = 1; i < 5; i++ )
  105. {
  106. m_outputPorts[ i ].Visible = true;
  107. m_outputPorts[ i ].Name = Constants.ChannelNamesColor[ i - 1 ];
  108. }
  109. }
  110. break;
  111. }
  112. m_sizeIsDirty = true;
  113. }
  114. protected virtual void OnSubShaderChange() { }
  115. protected virtual void OnPassChange() { }
  116. protected void DrawSubShaderUI()
  117. {
  118. EditorGUI.BeginChangeCheck();
  119. m_subShaderIdx = EditorGUILayoutPopup( SubShaderStr, m_subShaderIdx, m_availableSubshaders );
  120. if( EditorGUI.EndChangeCheck() )
  121. {
  122. //UpdateSubShaderAmount();
  123. UpdatePassAmount();
  124. OnSubShaderChange();
  125. }
  126. }
  127. protected void DrawPassUI()
  128. {
  129. EditorGUI.BeginChangeCheck();
  130. m_passLocalArrayIdx = EditorGUILayoutPopup( PassStr, m_passLocalArrayIdx, m_availablePassesLabels );
  131. if( EditorGUI.EndChangeCheck() )
  132. {
  133. m_passIdx = m_availablePassesValues[ m_passLocalArrayIdx ];
  134. //UpdatePassAmount();
  135. OnPassChange();
  136. }
  137. }
  138. virtual protected void CheckWarningState()
  139. {
  140. if( m_containerGraph.CurrentCanvasMode != NodeAvailability.TemplateShader )
  141. {
  142. ShowTab( NodeMessageType.Error, ErrorMessageStr );
  143. }
  144. else
  145. {
  146. m_showErrorMessage = false;
  147. }
  148. }
  149. protected void FetchMultiPassTemplate( MasterNode masterNode = null )
  150. {
  151. m_multiPassMode = m_containerGraph.MultiPassMasterNodes.NodesList.Count > 0;
  152. if( m_multiPassMode )
  153. {
  154. m_templateMPData = ( ( ( masterNode == null ) ? m_containerGraph.CurrentMasterNode : masterNode ) as TemplateMultiPassMasterNode ).CurrentTemplate;
  155. if( m_templateMPData != null )
  156. {
  157. UpdateSubShaderAmount();
  158. }
  159. }
  160. }
  161. protected void UpdateSubShaderAmount()
  162. {
  163. if( m_templateMPData == null )
  164. m_templateMPData = ( m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode ).CurrentTemplate;
  165. if( m_templateMPData != null )
  166. {
  167. int subShaderCount = m_templateMPData.SubShaders.Count;
  168. if( m_availableSubshaders == null || subShaderCount != m_availableSubshaders.Length )
  169. {
  170. m_availableSubshaders = new string[ subShaderCount ];
  171. for( int i = 0; i < subShaderCount; i++ )
  172. {
  173. m_availableSubshaders[ i ] = i.ToString();
  174. }
  175. }
  176. m_subShaderIdx = Mathf.Min( m_subShaderIdx, subShaderCount - 1 );
  177. UpdatePassAmount();
  178. }
  179. }
  180. protected virtual bool ValidatePass( int passIdx ) { return true; }
  181. protected void UpdatePassAmount()
  182. {
  183. if( !m_multiPassMode )
  184. return;
  185. if( m_templateMPData == null )
  186. m_templateMPData = ( m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode ).CurrentTemplate;
  187. List<string> passLabels = new List<string>();
  188. List<int> passValues = new List<int>();
  189. int minPassIdx = int.MaxValue;
  190. int passCount = m_templateMPData.SubShaders[ m_subShaderIdx ].Passes.Count;
  191. bool resetPassIdx = true;
  192. for( int i = 0; i < passCount; i++ )
  193. {
  194. if( ValidatePass( i ) )
  195. {
  196. passLabels.Add( i.ToString() );
  197. passValues.Add( i );
  198. minPassIdx = Mathf.Min( minPassIdx, i );
  199. if( m_passIdx == i )
  200. resetPassIdx = false;
  201. }
  202. }
  203. m_availablePassesLabels = passLabels.ToArray();
  204. m_availablePassesValues = passValues.ToArray();
  205. if( resetPassIdx )
  206. m_passIdx = minPassIdx;
  207. RefreshPassLocalArrayIdx();
  208. }
  209. void RefreshPassLocalArrayIdx( )
  210. {
  211. for( int i = 0; i < m_availablePassesValues.Length; i++ )
  212. {
  213. if( m_availablePassesValues[ i ] == m_passIdx )
  214. {
  215. m_passLocalArrayIdx = i;
  216. }
  217. }
  218. }
  219. public override void Destroy()
  220. {
  221. base.Destroy();
  222. m_templateMPData = null;
  223. }
  224. public override void ReadFromString( ref string[] nodeParams )
  225. {
  226. base.ReadFromString( ref nodeParams );
  227. if( UIUtils.CurrentShaderVersion() > TemplatesManager.MPShaderVersion )
  228. {
  229. m_subShaderIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  230. m_passIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  231. }
  232. }
  233. public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  234. {
  235. base.WriteToString( ref nodeInfo, ref connectionsInfo );
  236. IOUtils.AddFieldValueToString( ref nodeInfo, m_subShaderIdx );
  237. IOUtils.AddFieldValueToString( ref nodeInfo, m_passIdx );
  238. }
  239. public int SubShaderIdx { get { return m_subShaderIdx; } }
  240. public int PassIdx { get { return m_passIdx; } }
  241. }
  242. }