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.

2112 lines
73 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. //#define SHOW_TEMPLATE_HELP_BOX
  4. #define SHOW_HD_SRP
  5. #define CUSTOM_OPTIONS_AVAILABLE
  6. using System;
  7. using System.Collections.Generic;
  8. using UnityEngine;
  9. using UnityEditor;
  10. namespace AmplifyShaderEditor
  11. {
  12. public enum HDSRPMaterialType
  13. {
  14. SubsurfaceScattering,
  15. Standard,
  16. Specular,
  17. Anisotropy,
  18. Iridescence,
  19. Translucent
  20. }
  21. [Serializable]
  22. [NodeAttributes( "Template Master Node", "Master", "Shader Generated according to template rules", null, KeyCode.None, false )]
  23. public sealed class TemplateMultiPassMasterNode : MasterNode
  24. {
  25. private const string SubTitleFormatterStr = "(SubShader {0} Pass {1})";
  26. private const string NoSubShaderPropertyStr = "No Sub-Shader properties available";
  27. private const string NoPassPropertyStr = "No Pass properties available";
  28. private const string WarningMessage = "Templates is a feature that is still heavily under development and users may experience some problems.\nPlease email support@amplify.pt if any issue occurs.";
  29. private const string OpenTemplateStr = "Edit Template";
  30. private const string ReloadTemplateStr = "Reload Template";
  31. private const string CommonPropertiesStr = "Common Properties ";
  32. private const string SubShaderModuleStr = "SubShader ";
  33. private const string PassModuleStr = "Pass ";
  34. private const string PassNameStr = "Name";
  35. private const string PassNameFormateStr = "Name \"{0}\"";
  36. private bool m_reRegisterTemplateData = false;
  37. private bool m_fireTemplateChange = false;
  38. private bool m_fetchMasterNodeCategory = false;
  39. [SerializeField]
  40. private string m_templateGUID = "4e1801f860093ba4f9eb58a4b556825b";
  41. [SerializeField]
  42. private int m_passIdx = 0;
  43. [SerializeField]
  44. private string m_passIdxStr = string.Empty;
  45. [SerializeField]
  46. private bool m_passFoldout = false;
  47. [SerializeField]
  48. private int m_subShaderIdx = 0;
  49. [SerializeField]
  50. private string m_subShaderIdxStr = string.Empty;
  51. [SerializeField]
  52. private bool m_subStringFoldout = false;
  53. [SerializeField]
  54. private int m_subShaderLOD = -1;
  55. [SerializeField]
  56. private string m_subShaderLODStr;
  57. //[SerializeField]
  58. //private bool m_mainMPMasterNode = false;
  59. [NonSerialized]
  60. private TemplateMultiPass m_templateMultiPass = null;
  61. [NonSerialized]
  62. private TemplateMultiPassMasterNode m_mainMasterNodeRef = null;
  63. [SerializeField]
  64. private TemplateModulesHelper m_subShaderModule = new TemplateModulesHelper();
  65. [SerializeField]
  66. private TemplateModulesHelper m_passModule = new TemplateModulesHelper();
  67. [SerializeField]
  68. private UsePassHelper m_usePass;
  69. [SerializeField]
  70. private string m_passName = string.Empty;
  71. [SerializeField]
  72. private string m_originalPassName = string.Empty;
  73. [SerializeField]
  74. private bool m_hasLinkPorts = false;
  75. [SerializeField]
  76. private bool m_isInvisible = false;
  77. [SerializeField]
  78. private int m_invisibleOptions = 0;
  79. [SerializeField]
  80. private bool m_invalidNode = false;
  81. [SerializeField]
  82. private FallbackPickerHelper m_fallbackHelper = null;
  83. [SerializeField]
  84. private DependenciesHelper m_dependenciesHelper = new DependenciesHelper();
  85. #if CUSTOM_OPTIONS_AVAILABLE
  86. private const string CustomOptionsLabel = " Custom Options";
  87. [SerializeField]
  88. private bool m_passCustomOptionsFoldout = false;
  89. [SerializeField]
  90. private string m_passCustomOptionsLabel = CustomOptionsLabel;
  91. [SerializeField]
  92. private int m_passCustomOptionsSizeCheck = 0;
  93. [SerializeField]
  94. private List<TemplateOptionUIItem> m_passCustomOptionsUI = new List<TemplateOptionUIItem>();
  95. [NonSerialized]
  96. private Dictionary<string, TemplateOptionUIItem> m_passCustomOptionsUIDict = new Dictionary<string, TemplateOptionUIItem>();
  97. [SerializeField]
  98. private List<TemplateOptionPortItem> m_passCustomOptionsPorts = new List<TemplateOptionPortItem>();
  99. #endif
  100. // HATE THIS BELOW, MUST REMOVE HD SPECIFIC CODE FROM GENERIC MASTER NODE
  101. private const string HDSRPMaterialTypeStr = "Material Type";
  102. private const string SRPMaterialSubsurfaceScatteringKeyword = "_MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1";
  103. private const string SRPMaterialTransmissionKeyword = "_MATERIAL_FEATURE_TRANSMISSION 1";
  104. private const string SRPHDMaterialSpecularKeyword = "_MATERIAL_FEATURE_SPECULAR_COLOR 1";
  105. private const string SRPLWMaterialSpecularKeyword = "_SPECULAR_SETUP 1";
  106. private const string SRPMaterialAnisotropyKeyword = "_MATERIAL_FEATURE_ANISOTROPY 1";
  107. private const string SRPMaterialIridiscenceKeyword = "_MATERIAL_FEATURE_IRIDESCENCE 1";
  108. private const string SRPMaterialNormalMapKeyword = "_NORMALMAP 1";
  109. private const string SRPMaterialAlphaTestKeyword = "_ALPHATEST_ON 1";
  110. private const string SRPMaterialBlendModeAlphaClipThresholdKeyword = "_AlphaClip 1";
  111. private const string SRPMaterialTransparentKeyword = "_SURFACE_TYPE_TRANSPARENT 1";
  112. private const string SRPMaterialBlendModeAddKeyword = "_BLENDMODE_ADD 1";
  113. private const string SRPMaterialBlendModeAlphaKeyword = "_BLENDMODE_ALPHA 1";
  114. private const string SRPMaterialClearCoatKeyword = "_MATERIAL_FEATURE_CLEAR_COAT";
  115. [NonSerialized]
  116. private bool m_fetchPorts = true;
  117. [NonSerialized]
  118. private InputPort m_specularPort;
  119. [NonSerialized]
  120. private InputPort m_metallicPort;
  121. [NonSerialized]
  122. private InputPort m_coatMaskPort;
  123. [NonSerialized]
  124. private InputPort m_diffusionProfilePort;
  125. [NonSerialized]
  126. private InputPort m_subsurfaceMaskPort;
  127. [NonSerialized]
  128. private InputPort m_thicknessPort;
  129. [NonSerialized]
  130. private InputPort m_anisotropyPort;
  131. [NonSerialized]
  132. private InputPort m_iridescenceThicknessPort;
  133. [NonSerialized]
  134. private InputPort m_iridescenceMaskPort;
  135. [NonSerialized]
  136. private InputPort m_indexOfRefractionPort;
  137. [NonSerialized]
  138. private InputPort m_transmittanceColorPort;
  139. [NonSerialized]
  140. private InputPort m_transmittanceAbsorptionDistancePort;
  141. [NonSerialized]
  142. private InputPort m_transmittanceMaskPort;
  143. [SerializeField]
  144. private HDSRPMaterialType m_hdSrpMaterialType = HDSRPMaterialType.Standard;
  145. //////////////////////////////////////////////////////////////////////////
  146. protected override void CommonInit( int uniqueId )
  147. {
  148. base.CommonInit( uniqueId );
  149. m_masterNodeCategory = 1;// First Template
  150. m_marginPreviewLeft = 20;
  151. m_shaderNameIsTitle = false;
  152. m_customInspectorName = string.Empty;
  153. }
  154. public override void ReleaseResources()
  155. {
  156. if( !m_isMainOutputNode )
  157. return;
  158. m_containerGraph.ClearInternalTemplateNodes();
  159. TemplateMultiPass template = ( m_templateMultiPass == null ) ? m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( m_templateGUID ) as TemplateMultiPass : m_templateMultiPass;
  160. if( template != null && template.AvailableShaderProperties != null )
  161. {
  162. // Unregister old template properties
  163. int oldPropertyCount = template.AvailableShaderProperties.Count;
  164. for( int i = 0; i < oldPropertyCount; i++ )
  165. {
  166. UIUtils.ReleaseUniformName( UniqueId, template.AvailableShaderProperties[ i ].PropertyName );
  167. }
  168. }
  169. }
  170. void RegisterProperties()
  171. {
  172. if( !m_isMainOutputNode )
  173. {
  174. m_reRegisterTemplateData = false;
  175. return;
  176. }
  177. if( m_templateMultiPass != null )
  178. {
  179. m_reRegisterTemplateData = false;
  180. // Register old template properties
  181. int newPropertyCount = m_templateMultiPass.AvailableShaderProperties.Count;
  182. for( int i = 0; i < newPropertyCount; i++ )
  183. {
  184. m_containerGraph.AddInternalTemplateNode( m_templateMultiPass.AvailableShaderProperties[ i ] );
  185. int nodeId = UIUtils.CheckUniformNameOwner( m_templateMultiPass.AvailableShaderProperties[ i ].PropertyName );
  186. if( nodeId > -1 )
  187. {
  188. if( UniqueId != nodeId )
  189. {
  190. ParentNode node = m_containerGraph.GetNode( nodeId );
  191. if( node != null )
  192. {
  193. UIUtils.ShowMessage( string.Format( "Template requires property name {0} which is currently being used by {1}. Please rename it and reload template.", m_templateMultiPass.AvailableShaderProperties[ i ].PropertyName, node.Attributes.Name ) );
  194. }
  195. else
  196. {
  197. UIUtils.ShowMessage( string.Format( "Template requires property name {0} which is currently being on your graph. Please rename it and reload template.", m_templateMultiPass.AvailableShaderProperties[ i ].PropertyName ) );
  198. }
  199. }
  200. }
  201. else
  202. {
  203. UIUtils.RegisterUniformName( UniqueId, m_templateMultiPass.AvailableShaderProperties[ i ].PropertyName );
  204. }
  205. }
  206. }
  207. }
  208. public override void OnEnable()
  209. {
  210. base.OnEnable();
  211. m_reRegisterTemplateData = true;
  212. if( m_usePass == null )
  213. {
  214. m_usePass = ScriptableObject.CreateInstance<UsePassHelper>();
  215. m_usePass.Init(" Additional Use Passes" );
  216. }
  217. if( m_fallbackHelper == null )
  218. {
  219. m_fallbackHelper = ScriptableObject.CreateInstance<FallbackPickerHelper>();
  220. m_fallbackHelper.Init();
  221. }
  222. }
  223. protected override void OnUniqueIDAssigned()
  224. {
  225. base.OnUniqueIDAssigned();
  226. if( UniqueId >= 0 )
  227. {
  228. m_containerGraph.MultiPassMasterNodes.AddNode( this );
  229. }
  230. }
  231. public void SetTemplate( TemplateMultiPass template, bool writeDefaultData, bool fetchMasterNodeCategory, int subShaderIdx, int passIdx )
  232. {
  233. if( subShaderIdx > -1 )
  234. m_subShaderIdx = subShaderIdx;
  235. if( passIdx > -1 )
  236. m_passIdx = passIdx;
  237. ReleaseResources();
  238. m_templateMultiPass = ( template == null ) ? m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( m_templateGUID ) as TemplateMultiPass : template;
  239. if( m_templateMultiPass != null )
  240. {
  241. m_containerGraph.CurrentSRPType = m_templateMultiPass.SRPtype;
  242. if( m_templateMultiPass.IsSinglePass )
  243. {
  244. SetAdditonalTitleText( string.Empty );
  245. }
  246. else
  247. {
  248. SetAdditonalTitleText( string.Format( SubTitleFormatterStr, m_subShaderIdx, m_passIdx ) );
  249. }
  250. m_invalidNode = false;
  251. if( m_subShaderIdx >= m_templateMultiPass.SubShaders.Count ||
  252. m_passIdx >= m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes.Count )
  253. {
  254. if( DebugConsoleWindow.DeveloperMode )
  255. Debug.LogFormat( "Inexisting pass {0}. Cancelling template fetch", m_originalPassName );
  256. return;
  257. }
  258. m_isMainOutputNode = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].IsMainPass;
  259. if( m_isMainOutputNode )
  260. {
  261. // We cannot use UIUtils.MasterNodeOnTexture.height since this method can be
  262. // called before UIUtils is initialized
  263. m_insideSize.y = 55;
  264. }
  265. else
  266. {
  267. m_insideSize.y = 0;
  268. }
  269. //IsMainOutputNode = m_mainMPMasterNode;
  270. m_isInvisible = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].IsInvisible;
  271. m_invisibleOptions = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].InvisibleOptions;
  272. m_originalPassName = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data;
  273. m_shaderNameIsTitle = ( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes.Count == 1 );
  274. if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Index > -1 )
  275. {
  276. m_subShaderLODStr = m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Id;
  277. m_subShaderLOD = Convert.ToInt32( m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Data );
  278. }
  279. else
  280. {
  281. m_subShaderLOD = -1;
  282. }
  283. m_fetchMasterNodeCategory = fetchMasterNodeCategory;
  284. m_templateGUID = m_templateMultiPass.GUID;
  285. UpdatePortInfo();
  286. RegisterProperties();
  287. // template is null when hot code reloading or loading from file so inspector name shouldn't be changed
  288. if( template != null )
  289. {
  290. m_customInspectorName = m_templateMultiPass.CustomInspectorContainer.Data;
  291. }
  292. #if CUSTOM_OPTIONS_AVAILABLE
  293. SetupCustomOptionsFromTemplate( template != null );
  294. #endif
  295. if( string.IsNullOrEmpty( m_fallbackHelper.RawFallbackShader ) )
  296. m_fallbackHelper.RawFallbackShader = m_templateMultiPass.FallbackContainer.Data;
  297. //bool updateInfofromTemplate = UpdatePortInfo();
  298. //if( updateInfofromTemplate )
  299. //{
  300. m_subShaderModule.FetchDataFromTemplate( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules );
  301. m_passModule.FetchDataFromTemplate( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules );
  302. //}
  303. //RegisterProperties();
  304. if( writeDefaultData )
  305. {
  306. ShaderName = m_templateMultiPass.DefaultShaderName;
  307. m_passName = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data;
  308. if( !m_templateMultiPass.IsSinglePass && !m_shaderNameIsTitle )
  309. {
  310. SetClippedTitle( m_passName );
  311. }
  312. }
  313. UpdateSubShaderPassStr();
  314. if( m_isMainOutputNode )
  315. m_fireTemplateChange = true;
  316. }
  317. else
  318. {
  319. m_invalidNode = true;
  320. }
  321. }
  322. public override void OnRefreshLinkedPortsComplete()
  323. {
  324. if( m_invalidNode )
  325. return;
  326. if( m_templateMultiPass.SubShaders[m_subShaderIdx].Passes[m_passIdx].Modules.SRPIsPBRHD )
  327. ConfigHDPorts();
  328. }
  329. bool UpdatePortInfo()
  330. {
  331. List<TemplateInputData> inputDataList = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].InputDataList;
  332. int count = inputDataList.Count;
  333. if( count != m_inputPorts.Count )
  334. {
  335. DeleteAllInputConnections( true );
  336. for( int i = 0; i < count; i++ )
  337. {
  338. InputPort port = AddInputPort( inputDataList[ i ].DataType, false, inputDataList[ i ].PortName, inputDataList[ i ].OrderId, inputDataList[ i ].PortCategory, inputDataList[ i ].PortUniqueId );
  339. port.ExternalLinkId = inputDataList[ i ].LinkId;
  340. m_hasLinkPorts = m_hasLinkPorts || !string.IsNullOrEmpty( inputDataList[ i ].LinkId );
  341. }
  342. return true;
  343. }
  344. else
  345. {
  346. for( int i = 0; i < count; i++ )
  347. {
  348. m_inputPorts[ i ].ChangeProperties( inputDataList[ i ].PortName, inputDataList[ i ].DataType, false );
  349. m_inputPorts[ i ].ExternalLinkId = inputDataList[ i ].LinkId;
  350. }
  351. return false;
  352. }
  353. }
  354. #if CUSTOM_OPTIONS_AVAILABLE
  355. void DrawCustomOptions()
  356. {
  357. for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )
  358. {
  359. m_passCustomOptionsUI[ i ].Draw( this );
  360. }
  361. EditorGUILayout.Space();
  362. }
  363. public void OnCustomOptionSelected( TemplateOptionUIItem uiItem, params TemplateActionItem[] validActions )
  364. {
  365. uiItem.CheckOnExecute = false;
  366. for( int i = 0; i < validActions.Length; i++ )
  367. {
  368. switch( validActions[ i ].ActionType )
  369. {
  370. case AseOptionsActionType.ShowOption:
  371. {
  372. TemplateOptionUIItem item = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( validActions[ i ].ActionData ) ) );
  373. if( item != null )
  374. {
  375. item.IsVisible = true;
  376. }
  377. }
  378. break;
  379. case AseOptionsActionType.HideOption:
  380. {
  381. TemplateOptionUIItem item = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( validActions[ i ].ActionData ) ) );
  382. if( item != null )
  383. {
  384. item.IsVisible = false;
  385. }
  386. }
  387. break;
  388. case AseOptionsActionType.HidePort:
  389. {
  390. InputPort port = m_inputPorts.Find( x => x.Name.Equals( validActions[ i ].ActionData ) );
  391. if( port != null )
  392. {
  393. port.Visible = false;
  394. m_sizeIsDirty = true;
  395. }
  396. }
  397. break;
  398. case AseOptionsActionType.ShowPort:
  399. {
  400. InputPort port = m_inputPorts.Find( x => x.Name.Equals( validActions[ i ].ActionData ) );
  401. if( port != null )
  402. {
  403. port.Visible = true;
  404. m_sizeIsDirty = true;
  405. }
  406. }
  407. break;
  408. case AseOptionsActionType.SetDefine:
  409. {
  410. uiItem.CheckOnExecute = true;
  411. }
  412. break;
  413. case AseOptionsActionType.UnsetDefine:
  414. {
  415. uiItem.CheckOnExecute = true;
  416. }
  417. break;
  418. case AseOptionsActionType.ExcludePass:
  419. {
  420. }
  421. break;
  422. }
  423. }
  424. }
  425. void SetupCustomOptionsFromTemplate( bool newTemplate )
  426. {
  427. TemplateOptionsContainer customOptionsContainer = Pass.CustomOptionsContainer;
  428. if( !newTemplate && customOptionsContainer.Body.Length == m_passCustomOptionsSizeCheck )
  429. {
  430. for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )
  431. {
  432. if( m_passCustomOptionsUI[ i ].EmptyEvent )
  433. {
  434. m_passCustomOptionsUI[ i ].OnActionPerformedEvt += OnCustomOptionSelected;
  435. }
  436. }
  437. return;
  438. }
  439. m_passCustomOptionsLabel = string.IsNullOrEmpty( customOptionsContainer.Name ) ? CustomOptionsLabel : " " + customOptionsContainer.Name;
  440. for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )
  441. {
  442. m_passCustomOptionsUI[ i ].Destroy();
  443. }
  444. m_passCustomOptionsUI.Clear();
  445. m_passCustomOptionsUIDict.Clear();
  446. m_passCustomOptionsPorts.Clear();
  447. if( customOptionsContainer.Enabled )
  448. {
  449. m_passCustomOptionsSizeCheck = customOptionsContainer.Body.Length;
  450. for( int i = 0; i < customOptionsContainer.Options.Length; i++ )
  451. {
  452. switch( customOptionsContainer.Options[ i ].Type )
  453. {
  454. case AseOptionsType.Option:
  455. {
  456. TemplateOptionUIItem item = new TemplateOptionUIItem( customOptionsContainer.Options[ i ] );
  457. item.OnActionPerformedEvt += OnCustomOptionSelected;
  458. m_passCustomOptionsUI.Add( item );
  459. m_passCustomOptionsUIDict.Add( customOptionsContainer.Options[ i ].Id, item );
  460. }
  461. break;
  462. case AseOptionsType.Port:
  463. {
  464. TemplateOptionPortItem item = new TemplateOptionPortItem( this, customOptionsContainer.Options[ i ] );
  465. m_passCustomOptionsPorts.Add( item );
  466. }
  467. break;
  468. }
  469. }
  470. }
  471. else
  472. {
  473. m_passCustomOptionsSizeCheck = 0;
  474. }
  475. }
  476. void SetCustomOptionsInfo( TemplateMultiPassMasterNode masterNode )
  477. {
  478. if( masterNode == null )
  479. return;
  480. for( int i = 0; i < masterNode.PassCustomOptionsUI.Count; i++ )
  481. {
  482. masterNode.PassCustomOptionsUI[ i ].FillDataCollector( ref m_currentDataCollector );
  483. }
  484. for( int i = 0; i < masterNode.PassCustomOptionsPorts.Count; i++ )
  485. {
  486. masterNode.PassCustomOptionsPorts[ i ].FillDataCollector( masterNode, ref m_currentDataCollector );
  487. }
  488. }
  489. void RefreshCustomOptionsDict()
  490. {
  491. if( m_passCustomOptionsUIDict.Count != m_passCustomOptionsUI.Count )
  492. {
  493. m_passCustomOptionsUIDict.Clear();
  494. int count = m_passCustomOptionsUI.Count;
  495. for( int i = 0; i < count; i++ )
  496. {
  497. m_passCustomOptionsUIDict.Add( m_passCustomOptionsUI[ i ].Options.Id, m_passCustomOptionsUI[ i ] );
  498. }
  499. }
  500. }
  501. #endif
  502. void SetCategoryIdxFromTemplate()
  503. {
  504. int templateCount = m_containerGraph.ParentWindow.TemplatesManagerInstance.TemplateCount;
  505. for( int i = 0; i < templateCount; i++ )
  506. {
  507. int idx = i + 1;
  508. TemplateMultiPass templateData = m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( i ) as TemplateMultiPass;
  509. if( templateData != null && m_templateMultiPass != null && m_templateMultiPass.GUID.Equals( templateData.GUID ) )
  510. m_masterNodeCategory = idx;
  511. }
  512. }
  513. void CheckTemplateChanges()
  514. {
  515. if( m_invalidNode )
  516. return;
  517. if( m_isMainOutputNode )
  518. {
  519. if( m_containerGraph.MultiPassMasterNodes.Count != m_templateMultiPass.MasterNodesRequired )
  520. {
  521. if( m_availableCategories == null )
  522. RefreshAvailableCategories();
  523. if( DebugConsoleWindow.DeveloperMode )
  524. Debug.Log( "Template Pass amount was changed. Rebuiling master nodes" );
  525. m_containerGraph.ParentWindow.ReplaceMasterNode( m_availableCategories[ m_masterNodeCategory ], true );
  526. }
  527. }
  528. }
  529. public override void OnNodeLogicUpdate( DrawInfo drawInfo )
  530. {
  531. base.OnNodeLogicUpdate( drawInfo );
  532. if( m_invalidNode )
  533. {
  534. return;
  535. }
  536. if( m_templateMultiPass == null )
  537. {
  538. // Hotcode reload has happened
  539. SetTemplate( null, false, true, m_subShaderIdx, m_passIdx );
  540. CheckTemplateChanges();
  541. }
  542. if( m_reRegisterTemplateData )
  543. {
  544. RegisterProperties();
  545. }
  546. if( m_fetchMasterNodeCategory )
  547. {
  548. if( m_availableCategories != null )
  549. {
  550. m_fetchMasterNodeCategory = false;
  551. SetCategoryIdxFromTemplate();
  552. }
  553. }
  554. if( m_fireTemplateChange )
  555. {
  556. m_fireTemplateChange = false;
  557. m_containerGraph.FireMasterNodeReplacedEvent();
  558. }
  559. if( m_subShaderModule.HasValidData )
  560. {
  561. m_subShaderModule.OnLogicUpdate( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules );
  562. }
  563. if( m_passModule.HasValidData )
  564. {
  565. m_passModule.OnLogicUpdate( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules );
  566. }
  567. }
  568. public override void Draw( DrawInfo drawInfo )
  569. {
  570. if( !m_isInvisible )
  571. {
  572. base.Draw( drawInfo );
  573. }
  574. }
  575. public override void OnNodeLayout( DrawInfo drawInfo )
  576. {
  577. if( m_invalidNode )
  578. {
  579. if( m_isMainOutputNode )
  580. {
  581. UIUtils.ShowMessage( "Invalid current template. Switching to Standard Surface", MessageSeverity.Error );
  582. m_shaderModelIdx = 0;
  583. m_masterNodeCategory = 0;
  584. m_containerGraph.ParentWindow.ReplaceMasterNode( new MasterNodeCategoriesData( AvailableShaderTypes.SurfaceShader, m_shaderName ), false );
  585. }
  586. return;
  587. }
  588. if( m_isInvisible )
  589. {
  590. return;
  591. }
  592. if( !IsMainOutputNode )
  593. {
  594. if( !IsInvisible && Docking )
  595. {
  596. m_useSquareNodeTitle = true;
  597. TemplateMultiPassMasterNode master = ContainerGraph.CurrentMasterNode as TemplateMultiPassMasterNode;
  598. m_position = master.TruePosition;
  599. m_position.height = 32;
  600. int masterIndex = ContainerGraph.MultiPassMasterNodes.NodesList.IndexOf( master );
  601. int index = ContainerGraph.MultiPassMasterNodes.GetNodeRegisterIdx( UniqueId );
  602. if( index > masterIndex )
  603. {
  604. int backTracking = 0;
  605. for( int i = index - 1; i > masterIndex; i-- )
  606. {
  607. if( !ContainerGraph.MultiPassMasterNodes.NodesList[ i ].IsInvisible && ContainerGraph.MultiPassMasterNodes.NodesList[ i ].Docking )
  608. backTracking++;
  609. }
  610. m_position.y = master.TruePosition.yMax + 1 + 33 * ( backTracking );// ContainerGraph.MultiPassMasterNodes.NodesList[ index - 1 ].TruePosition.yMax;
  611. base.OnNodeLayout( drawInfo );
  612. }
  613. else
  614. {
  615. int forwardTracking = 1;
  616. for( int i = index + 1; i < masterIndex; i++ )
  617. {
  618. if( !ContainerGraph.MultiPassMasterNodes.NodesList[ i ].IsInvisible && ContainerGraph.MultiPassMasterNodes.NodesList[ i ].Docking )
  619. forwardTracking++;
  620. }
  621. m_position.y = master.TruePosition.y - 33 * ( forwardTracking );// ContainerGraph.MultiPassMasterNodes.NodesList[ index - 1 ].TruePosition.yMax;
  622. base.OnNodeLayout( drawInfo );
  623. }
  624. }
  625. else
  626. {
  627. m_useSquareNodeTitle = false;
  628. base.OnNodeLayout( drawInfo );
  629. }
  630. }
  631. else
  632. {
  633. base.OnNodeLayout( drawInfo );
  634. }
  635. }
  636. public override void OnNodeRepaint( DrawInfo drawInfo )
  637. {
  638. base.OnNodeRepaint( drawInfo );
  639. if( m_invalidNode )
  640. return;
  641. if( !m_isInvisible )
  642. {
  643. if( m_containerGraph.IsInstancedShader )
  644. {
  645. DrawInstancedIcon( drawInfo );
  646. }
  647. }
  648. }
  649. public override void UpdateFromShader( Shader newShader )
  650. {
  651. if( m_currentMaterial != null && m_currentMaterial.shader != newShader )
  652. {
  653. m_currentMaterial.shader = newShader;
  654. }
  655. CurrentShader = newShader;
  656. }
  657. public override void UpdateMasterNodeMaterial( Material material )
  658. {
  659. m_currentMaterial = material;
  660. FireMaterialChangedEvt();
  661. }
  662. void DrawReloadButton()
  663. {
  664. if( GUILayout.Button( ReloadTemplateStr ) && m_templateMultiPass != null )
  665. {
  666. m_templateMultiPass.Reload();
  667. }
  668. }
  669. void DrawOpenTemplateButton()
  670. {
  671. GUILayout.BeginHorizontal();
  672. {
  673. if( GUILayout.Button( OpenTemplateStr ) && m_templateMultiPass != null )
  674. {
  675. try
  676. {
  677. string pathname = AssetDatabase.GUIDToAssetPath( m_templateMultiPass.GUID );
  678. if( !string.IsNullOrEmpty( pathname ) )
  679. {
  680. Shader selectedTemplate = AssetDatabase.LoadAssetAtPath<Shader>( pathname );
  681. if( selectedTemplate != null )
  682. {
  683. AssetDatabase.OpenAsset( selectedTemplate, 1 );
  684. }
  685. }
  686. }
  687. catch( Exception e )
  688. {
  689. Debug.LogException( e );
  690. }
  691. }
  692. if( GUILayout.Button( "\u25C4", GUILayout.Width( 18 ), GUILayout.Height( 18 ) ) && m_templateMultiPass != null )
  693. {
  694. try
  695. {
  696. string pathname = AssetDatabase.GUIDToAssetPath( m_templateMultiPass.GUID );
  697. if( !string.IsNullOrEmpty( pathname ) )
  698. {
  699. Shader selectedTemplate = AssetDatabase.LoadAssetAtPath<Shader>( pathname );
  700. if( selectedTemplate != null )
  701. {
  702. Event.current.Use();
  703. Selection.activeObject = selectedTemplate;
  704. EditorGUIUtility.PingObject( Selection.activeObject );
  705. }
  706. }
  707. }
  708. catch( Exception e )
  709. {
  710. Debug.LogException( e );
  711. }
  712. }
  713. }
  714. GUILayout.EndHorizontal();
  715. }
  716. public override void DrawProperties()
  717. {
  718. base.DrawProperties();
  719. if( m_invalidNode )
  720. return;
  721. NodeUtils.DrawPropertyGroup( ref m_propertiesFoldout, CommonPropertiesStr, DrawCommonProperties );
  722. NodeUtils.DrawPropertyGroup( ref m_subStringFoldout, SubShaderModuleStr, DrawSubShaderProperties );
  723. NodeUtils.DrawPropertyGroup( ref m_passFoldout, PassModuleStr, DrawPassProperties );
  724. DrawMaterialInputs( UIUtils.MenuItemToolbarStyle, false );
  725. if( m_propertyOrderChanged )
  726. {
  727. List<TemplateMultiPassMasterNode> mpNodes = UIUtils.CurrentWindow.CurrentGraph.MultiPassMasterNodes.NodesList;
  728. int count = mpNodes.Count;
  729. for( int i = 0; i < count; i++ )
  730. {
  731. if( mpNodes[ i ].UniqueId != UniqueId )
  732. {
  733. mpNodes[ i ].CopyPropertyListFrom( this );
  734. }
  735. }
  736. }
  737. #if SHOW_TEMPLATE_HELP_BOX
  738. EditorGUILayout.HelpBox( WarningMessage, MessageType.Warning );
  739. #endif
  740. }
  741. void AddHDKeywords()
  742. {
  743. if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType != TemplateSRPType.HD ||
  744. !m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[m_passIdx].Modules.SRPIsPBR )
  745. return;
  746. switch( m_hdSrpMaterialType )
  747. {
  748. case HDSRPMaterialType.SubsurfaceScattering:
  749. {
  750. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialSubsurfaceScatteringKeyword );
  751. if( m_thicknessPort != null && m_thicknessPort.HasOwnOrLinkConnection )
  752. {
  753. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransmissionKeyword );
  754. }
  755. }
  756. break;
  757. case HDSRPMaterialType.Standard:
  758. break;
  759. case HDSRPMaterialType.Specular:
  760. {
  761. m_currentDataCollector.AddToDefines( UniqueId, SRPHDMaterialSpecularKeyword );
  762. }
  763. break;
  764. case HDSRPMaterialType.Anisotropy:
  765. {
  766. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialAnisotropyKeyword );
  767. }
  768. break;
  769. case HDSRPMaterialType.Iridescence:
  770. {
  771. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialIridiscenceKeyword );
  772. }
  773. break;
  774. case HDSRPMaterialType.Translucent:
  775. {
  776. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransmissionKeyword );
  777. }
  778. break;
  779. }
  780. if( m_coatMaskPort != null && m_coatMaskPort.HasOwnOrLinkConnection )
  781. {
  782. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialClearCoatKeyword );
  783. }
  784. }
  785. void FetchHDPorts()
  786. {
  787. if( m_fetchPorts )
  788. {
  789. m_fetchPorts = false;
  790. if( m_inputPorts.Count > 4 )
  791. {
  792. m_specularPort = GetInputPortByUniqueId( 3 );
  793. m_metallicPort = GetInputPortByUniqueId( 4 );
  794. m_coatMaskPort = GetInputPortByUniqueId( 11 );
  795. m_diffusionProfilePort = GetInputPortByUniqueId( 12 );
  796. m_subsurfaceMaskPort = GetInputPortByUniqueId( 13 );
  797. m_thicknessPort = GetInputPortByUniqueId( 14 );
  798. m_anisotropyPort = GetInputPortByUniqueId( 15 );
  799. m_iridescenceThicknessPort = GetInputPortByUniqueId( 16 );
  800. m_iridescenceMaskPort = GetInputPortByUniqueId( 17 );
  801. m_indexOfRefractionPort = GetInputPortByUniqueId( 18 );
  802. m_transmittanceColorPort = GetInputPortByUniqueId( 19 );
  803. m_transmittanceAbsorptionDistancePort = GetInputPortByUniqueId( 20 );
  804. m_transmittanceMaskPort = GetInputPortByUniqueId( 21 );
  805. }
  806. }
  807. }
  808. void ConfigHDPorts()
  809. {
  810. if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType != TemplateSRPType.HD ||
  811. !m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.SRPIsPBR )
  812. return;
  813. FetchHDPorts();
  814. if( m_inputPorts.Count > 4 )
  815. {
  816. switch( m_hdSrpMaterialType )
  817. {
  818. case HDSRPMaterialType.SubsurfaceScattering:
  819. {
  820. m_specularPort.Visible = false;
  821. m_metallicPort.Visible = false;
  822. m_coatMaskPort.Visible = true;
  823. m_diffusionProfilePort.Visible = true;
  824. m_subsurfaceMaskPort.Visible = true;
  825. m_thicknessPort.Visible = true;
  826. m_anisotropyPort.Visible = false;
  827. m_iridescenceThicknessPort.Visible = false;
  828. m_iridescenceMaskPort.Visible = false;
  829. m_indexOfRefractionPort.Visible = false;
  830. m_transmittanceColorPort.Visible = false;
  831. m_transmittanceAbsorptionDistancePort.Visible = false;
  832. m_transmittanceMaskPort.Visible = false;
  833. }
  834. break;
  835. case HDSRPMaterialType.Standard:
  836. {
  837. m_specularPort.Visible = false;
  838. m_metallicPort.Visible = true;
  839. m_coatMaskPort.Visible = true;
  840. m_diffusionProfilePort.Visible = false;
  841. m_subsurfaceMaskPort.Visible = false;
  842. m_thicknessPort.Visible = false;
  843. m_anisotropyPort.Visible = false;
  844. m_iridescenceThicknessPort.Visible = false;
  845. m_iridescenceMaskPort.Visible = false;
  846. m_indexOfRefractionPort.Visible = false;
  847. m_transmittanceColorPort.Visible = false;
  848. m_transmittanceAbsorptionDistancePort.Visible = false;
  849. m_transmittanceMaskPort.Visible = false;
  850. }
  851. break;
  852. case HDSRPMaterialType.Specular:
  853. {
  854. m_specularPort.Visible = true;
  855. m_metallicPort.Visible = false;
  856. m_coatMaskPort.Visible = true;
  857. m_diffusionProfilePort.Visible = false;
  858. m_subsurfaceMaskPort.Visible = false;
  859. m_thicknessPort.Visible = false;
  860. m_anisotropyPort.Visible = false;
  861. m_iridescenceThicknessPort.Visible = false;
  862. m_iridescenceMaskPort.Visible = false;
  863. m_indexOfRefractionPort.Visible = false;
  864. m_transmittanceColorPort.Visible = false;
  865. m_transmittanceAbsorptionDistancePort.Visible = false;
  866. m_transmittanceMaskPort.Visible = false;
  867. }
  868. break;
  869. case HDSRPMaterialType.Anisotropy:
  870. {
  871. m_specularPort.Visible = false;
  872. m_metallicPort.Visible = true;
  873. m_coatMaskPort.Visible = true;
  874. m_diffusionProfilePort.Visible = false;
  875. m_subsurfaceMaskPort.Visible = false;
  876. m_thicknessPort.Visible = false;
  877. m_anisotropyPort.Visible = true;
  878. m_iridescenceThicknessPort.Visible = false;
  879. m_iridescenceMaskPort.Visible = false;
  880. m_indexOfRefractionPort.Visible = false;
  881. m_transmittanceColorPort.Visible = false;
  882. m_transmittanceAbsorptionDistancePort.Visible = false;
  883. m_transmittanceMaskPort.Visible = false;
  884. }
  885. break;
  886. case HDSRPMaterialType.Iridescence:
  887. {
  888. m_specularPort.Visible = false;
  889. m_metallicPort.Visible = true;
  890. m_coatMaskPort.Visible = true;
  891. m_diffusionProfilePort.Visible = false;
  892. m_subsurfaceMaskPort.Visible = false;
  893. m_thicknessPort.Visible = false;
  894. m_anisotropyPort.Visible = false;
  895. m_iridescenceThicknessPort.Visible = true;
  896. m_iridescenceMaskPort.Visible = true;
  897. m_indexOfRefractionPort.Visible = false;
  898. m_transmittanceColorPort.Visible = false;
  899. m_transmittanceAbsorptionDistancePort.Visible = false;
  900. m_transmittanceMaskPort.Visible = false;
  901. }
  902. break;
  903. case HDSRPMaterialType.Translucent:
  904. {
  905. m_specularPort.Visible = false;
  906. m_metallicPort.Visible = false;
  907. m_coatMaskPort.Visible = false;
  908. m_diffusionProfilePort.Visible = true;
  909. m_subsurfaceMaskPort.Visible = false;
  910. m_thicknessPort.Visible = true;
  911. m_anisotropyPort.Visible = false;
  912. m_iridescenceThicknessPort.Visible = false;
  913. m_iridescenceMaskPort.Visible = false;
  914. m_indexOfRefractionPort.Visible = false;
  915. m_transmittanceColorPort.Visible = false;
  916. m_transmittanceAbsorptionDistancePort.Visible = false;
  917. m_transmittanceMaskPort.Visible = false;
  918. }
  919. break;
  920. }
  921. }
  922. m_sizeIsDirty = !m_isInvisible;
  923. }
  924. void DrawCommonProperties()
  925. {
  926. if( m_isMainOutputNode )
  927. {
  928. DrawShaderName();
  929. DrawCurrentShaderType();
  930. #if SHOW_HD_SRP
  931. if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.SRPIsPBRHD )
  932. {
  933. EditorGUI.BeginChangeCheck();
  934. CurrentHDMaterialType = (HDSRPMaterialType)EditorGUILayoutEnumPopup( HDSRPMaterialTypeStr, m_hdSrpMaterialType );
  935. if( EditorGUI.EndChangeCheck() )
  936. ConfigHDPorts();
  937. }
  938. #endif
  939. EditorGUI.BeginChangeCheck();
  940. DrawPrecisionProperty();
  941. if( EditorGUI.EndChangeCheck() )
  942. ContainerGraph.CurrentPrecision = m_currentPrecisionType;
  943. m_fallbackHelper.Draw( this );
  944. DrawCustomInspector();
  945. m_dependenciesHelper.Draw( this, true );
  946. }
  947. EditorGUILayout.LabelField( m_subShaderIdxStr );
  948. EditorGUILayout.LabelField( m_passIdxStr );
  949. DrawOpenTemplateButton();
  950. if( DebugConsoleWindow.DeveloperMode )
  951. DrawReloadButton();
  952. }
  953. public void DrawSubShaderProperties()
  954. {
  955. if( !m_isMainOutputNode )
  956. {
  957. if( m_mainMasterNodeRef == null )
  958. {
  959. m_mainMasterNodeRef = m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode;
  960. }
  961. m_mainMasterNodeRef.DrawSubShaderProperties();
  962. return;
  963. }
  964. bool noValidData = true;
  965. if( m_subShaderLOD > -1 )
  966. {
  967. noValidData = false;
  968. EditorGUILayout.LabelField( m_subShaderLODStr );
  969. }
  970. if( m_subShaderModule.HasValidData )
  971. {
  972. noValidData = false;
  973. m_subShaderModule.Draw( this, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules );
  974. //if( m_subShaderModule.IsDirty )
  975. //{
  976. // List<TemplateMultiPassMasterNode> mpNodes = UIUtils.CurrentWindow.CurrentGraph.MultiPassMasterNodes.NodesList;
  977. // int count = mpNodes.Count;
  978. // for( int i = 0; i < count; i++ )
  979. // {
  980. // if( mpNodes[ i ].SubShaderIdx == m_subShaderIdx && mpNodes[ i ].UniqueId != UniqueId )
  981. // {
  982. // mpNodes[ i ].SubShaderModule.CopyFrom( m_subShaderModule );
  983. // }
  984. // }
  985. // m_subShaderModule.IsDirty = false;
  986. //}
  987. }
  988. if( noValidData )
  989. {
  990. EditorGUILayout.HelpBox( NoSubShaderPropertyStr, MessageType.Info );
  991. }
  992. }
  993. void DrawPassProperties()
  994. {
  995. EditorGUI.BeginChangeCheck();
  996. m_passName = EditorGUILayoutTextField( PassNameStr, m_passName );
  997. if( EditorGUI.EndChangeCheck() )
  998. {
  999. if( m_passName.Length > 0 )
  1000. {
  1001. m_passName = UIUtils.RemoveShaderInvalidCharacters( m_passName );
  1002. }
  1003. else
  1004. {
  1005. m_passName = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data;
  1006. }
  1007. if( !m_templateMultiPass.IsSinglePass )
  1008. SetClippedTitle( m_passName );
  1009. }
  1010. if( m_passModule.HasValidData )
  1011. {
  1012. m_passModule.Draw( this, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules, m_subShaderModule );
  1013. }
  1014. m_usePass.Draw( this, false );
  1015. #if CUSTOM_OPTIONS_AVAILABLE
  1016. if( m_passCustomOptionsSizeCheck > 0 )
  1017. {
  1018. NodeUtils.DrawNestedPropertyGroup( ref m_passCustomOptionsFoldout, m_passCustomOptionsLabel, DrawCustomOptions );
  1019. }
  1020. #endif
  1021. }
  1022. bool CreateInstructionsForList( TemplateData templateData, ref List<InputPort> ports, ref string shaderBody, ref List<string> vertexInstructions, ref List<string> fragmentInstructions )
  1023. {
  1024. if( ports.Count == 0 )
  1025. return true;
  1026. AddHDKeywords();
  1027. bool isValid = true;
  1028. //UIUtils.CurrentWindow.CurrentGraph.ResetNodesLocalVariables();
  1029. for( int i = 0; i < ports.Count; i++ )
  1030. {
  1031. TemplateInputData inputData = templateData.InputDataFromId( ports[ i ].PortId );
  1032. if( ports[ i ].HasOwnOrLinkConnection )
  1033. {
  1034. if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType == TemplateSRPType.Lightweight )
  1035. {
  1036. if( ports[ i ].Name.Contains( "Normal" ) )
  1037. {
  1038. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialNormalMapKeyword );
  1039. }
  1040. if( ports[ i ].Name.Contains( "Alpha Clip Threshold" ) )
  1041. {
  1042. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialBlendModeAlphaClipThresholdKeyword );
  1043. }
  1044. if( ports[ i ].Name.Contains( "Specular" ) )
  1045. {
  1046. m_currentDataCollector.AddToDefines( UniqueId, SRPLWMaterialSpecularKeyword );
  1047. }
  1048. }
  1049. else if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType == TemplateSRPType.HD )
  1050. {
  1051. if( ports[ i ].Name.Contains( "Normal" ) )
  1052. {
  1053. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialNormalMapKeyword );
  1054. }
  1055. if( ports[ i ].Name.Contains( "Alpha Clip Threshold" ) )
  1056. {
  1057. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialAlphaTestKeyword );
  1058. }
  1059. }
  1060. m_currentDataCollector.ResetInstructions();
  1061. m_currentDataCollector.ResetVertexInstructions();
  1062. m_currentDataCollector.PortCategory = ports[ i ].Category;
  1063. string newPortInstruction = ports[ i ].GeneratePortInstructions( ref m_currentDataCollector );
  1064. if( m_currentDataCollector.DirtySpecialLocalVariables )
  1065. {
  1066. string cleanVariables = m_currentDataCollector.SpecialLocalVariables.Replace( "\t", string.Empty );
  1067. m_currentDataCollector.AddInstructions( cleanVariables, false );
  1068. m_currentDataCollector.ClearSpecialLocalVariables();
  1069. }
  1070. if( m_currentDataCollector.DirtyVertexVariables )
  1071. {
  1072. string cleanVariables = m_currentDataCollector.VertexLocalVariables.Replace( "\t", string.Empty );
  1073. m_currentDataCollector.AddVertexInstruction( cleanVariables, UniqueId, false );
  1074. m_currentDataCollector.ClearVertexLocalVariables();
  1075. }
  1076. // fill functions
  1077. for( int j = 0; j < m_currentDataCollector.InstructionsList.Count; j++ )
  1078. {
  1079. fragmentInstructions.Add( m_currentDataCollector.InstructionsList[ j ].PropertyName );
  1080. }
  1081. for( int j = 0; j < m_currentDataCollector.VertexDataList.Count; j++ )
  1082. {
  1083. vertexInstructions.Add( m_currentDataCollector.VertexDataList[ j ].PropertyName );
  1084. }
  1085. m_templateMultiPass.SetPassInputData( m_subShaderIdx, m_passIdx, ports[ i ].PortId, newPortInstruction );
  1086. isValid = m_templateMultiPass.FillTemplateBody( m_subShaderIdx, m_passIdx, inputData.TagId, ref shaderBody, newPortInstruction ) && isValid;
  1087. }
  1088. else
  1089. {
  1090. m_templateMultiPass.SetPassInputData( m_subShaderIdx, m_passIdx, ports[ i ].PortId, inputData.DefaultValue );
  1091. isValid = m_templateMultiPass.FillTemplateBody( m_subShaderIdx, m_passIdx, inputData.TagId, ref shaderBody, inputData.DefaultValue ) && isValid;
  1092. }
  1093. }
  1094. return isValid;
  1095. }
  1096. public string BuildShaderBody()
  1097. {
  1098. List<TemplateMultiPassMasterNode> list = UIUtils.CurrentWindow.CurrentGraph.MultiPassMasterNodes.NodesList;
  1099. int currentSubshader = list[ 0 ].SubShaderIdx;
  1100. m_templateMultiPass.SetShaderName( string.Format( TemplatesManager.NameFormatter, m_shaderName ) );
  1101. if( string.IsNullOrEmpty( m_customInspectorName ) )
  1102. {
  1103. m_templateMultiPass.SetCustomInspector( string.Empty );
  1104. }
  1105. else
  1106. {
  1107. m_templateMultiPass.SetCustomInspector( CustomInspectorFormatted );
  1108. }
  1109. m_templateMultiPass.SetFallback( m_fallbackHelper.FallbackShader );
  1110. m_templateMultiPass.SetDependencies( m_dependenciesHelper.GenerateDependencies() );
  1111. MasterNodeDataCollector dataCollector = new MasterNodeDataCollector();
  1112. int count = list.Count;
  1113. for( int i = 0; i < count; i++ )
  1114. {
  1115. list[ i ].CollectData();
  1116. list[ i ].FillPassData( this );
  1117. if( list[ i ].SubShaderIdx == currentSubshader )
  1118. {
  1119. dataCollector.CopyPropertiesFromDataCollector( list[ i ].CurrentDataCollector );
  1120. }
  1121. else
  1122. {
  1123. list[ i - 1 ].FillPropertyData( dataCollector );
  1124. list[ i - 1 ].FillSubShaderData();
  1125. dataCollector.Destroy();
  1126. dataCollector = new MasterNodeDataCollector();
  1127. dataCollector.CopyPropertiesFromDataCollector( list[ i ].CurrentDataCollector );
  1128. currentSubshader = list[ i ].SubShaderIdx;
  1129. }
  1130. // Last element must the one filling subshader data
  1131. // as only there all properties are caught
  1132. if( i == ( count - 1 ) )
  1133. {
  1134. list[ i ].FillPropertyData( dataCollector );
  1135. }
  1136. if( list[ i ].IsMainOutputNode )
  1137. list[ i ].FillSubShaderData();
  1138. }
  1139. return list[ 0 ].CurrentTemplate.IdManager.BuildShader();
  1140. }
  1141. public override Shader Execute( string pathname, bool isFullPath )
  1142. {
  1143. m_templateMultiPass.ResetState();
  1144. ForceReordering();
  1145. base.Execute( pathname, isFullPath );
  1146. string shaderBody = BuildShaderBody();
  1147. UpdateShaderAsset( ref pathname, ref shaderBody, isFullPath );
  1148. return m_currentShader;
  1149. }
  1150. public void CollectData()
  1151. {
  1152. if( m_inputPorts.Count == 0 )
  1153. return;
  1154. ContainerGraph.ResetNodesLocalVariables();
  1155. m_currentDataCollector = new MasterNodeDataCollector( this );
  1156. m_currentDataCollector.TemplateDataCollectorInstance.SetMultipassInfo( m_templateMultiPass, m_subShaderIdx, m_passIdx, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType );
  1157. m_currentDataCollector.TemplateDataCollectorInstance.FillSpecialVariables( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ] );
  1158. SetupNodeCategories();
  1159. if( m_containerGraph.IsInstancedShader )
  1160. m_currentDataCollector.SetupInstancePropertiesBlock( UIUtils.RemoveInvalidCharacters( m_shaderName ) );
  1161. TemplateData templateData = m_templateMultiPass.CreateTemplateData( m_shaderName, string.Empty, m_subShaderIdx, m_passIdx );
  1162. m_currentDataCollector.TemplateDataCollectorInstance.BuildFromTemplateData( m_currentDataCollector, templateData );
  1163. if( m_currentDataCollector.TemplateDataCollectorInstance.InterpData.DynamicMax )
  1164. {
  1165. int interpolatorAmount = -1;
  1166. if( m_passModule.ShaderModelHelper.ValidData )
  1167. {
  1168. interpolatorAmount = m_passModule.ShaderModelHelper.InterpolatorAmount;
  1169. }
  1170. else
  1171. {
  1172. TemplateModulesHelper subShaderModule = IsMainOutputNode ? m_subShaderModule : ( m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode ).SubShaderModule;
  1173. if( subShaderModule.ShaderModelHelper.ValidData )
  1174. {
  1175. interpolatorAmount = subShaderModule.ShaderModelHelper.InterpolatorAmount;
  1176. }
  1177. }
  1178. if( interpolatorAmount > -1 )
  1179. {
  1180. m_currentDataCollector.TemplateDataCollectorInstance.InterpData.RecalculateAvailableInterpolators( interpolatorAmount );
  1181. }
  1182. }
  1183. //Copy Properties
  1184. {
  1185. int shaderPropertiesAmount = m_templateMultiPass.AvailableShaderProperties.Count;
  1186. for( int i = 0; i < shaderPropertiesAmount; i++ )
  1187. {
  1188. m_currentDataCollector.SoftRegisterUniform( m_templateMultiPass.AvailableShaderProperties[ i ] );
  1189. }
  1190. }
  1191. //Copy Globals from SubShader level
  1192. {
  1193. int subShaderGlobalAmount = m_templateMultiPass.SubShaders[ m_subShaderIdx ].AvailableShaderGlobals.Count;
  1194. for( int i = 0; i < subShaderGlobalAmount; i++ )
  1195. {
  1196. m_currentDataCollector.SoftRegisterUniform( m_templateMultiPass.SubShaders[ m_subShaderIdx ].AvailableShaderGlobals[ i ] );
  1197. }
  1198. }
  1199. //Copy Globals from Pass Level
  1200. {
  1201. int passGlobalAmount = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].AvailableShaderGlobals.Count;
  1202. for( int i = 0; i < passGlobalAmount; i++ )
  1203. {
  1204. m_currentDataCollector.SoftRegisterUniform( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].AvailableShaderGlobals[ i ] );
  1205. }
  1206. }
  1207. RegisterStandaloneFuntions();
  1208. m_containerGraph.CheckPropertiesAutoRegister( ref m_currentDataCollector );
  1209. //Sort ports by both
  1210. List<InputPort> fragmentPorts = new List<InputPort>();
  1211. List<InputPort> vertexPorts = new List<InputPort>();
  1212. SortInputPorts( ref vertexPorts, ref fragmentPorts );
  1213. string shaderBody = templateData.TemplateBody;
  1214. List<string> vertexInstructions = new List<string>();
  1215. List<string> fragmentInstructions = new List<string>();
  1216. bool validBody = true;
  1217. //validBody = CreateInstructionsForList( templateData, ref fragmentPorts, ref shaderBody, ref vertexInstructions, ref fragmentInstructions ) && validBody;
  1218. //ContainerGraph.ResetNodesLocalVariablesIfNot( MasterNodePortCategory.Vertex );
  1219. //validBody = CreateInstructionsForList( templateData, ref vertexPorts, ref shaderBody, ref vertexInstructions, ref fragmentInstructions ) && validBody;
  1220. validBody = CreateInstructionsForList( templateData, ref vertexPorts, ref shaderBody, ref vertexInstructions, ref fragmentInstructions ) && validBody;
  1221. validBody = CreateInstructionsForList( templateData, ref fragmentPorts, ref shaderBody, ref vertexInstructions, ref fragmentInstructions ) && validBody;
  1222. templateData.ResetTemplateUsageData();
  1223. // Fill vertex interpolators assignment
  1224. for( int i = 0; i < m_currentDataCollector.VertexInterpDeclList.Count; i++ )
  1225. {
  1226. vertexInstructions.Add( m_currentDataCollector.VertexInterpDeclList[ i ] );
  1227. }
  1228. vertexInstructions.AddRange( m_currentDataCollector.TemplateDataCollectorInstance.GetInterpUnusedChannels() );
  1229. //Fill common local variables and operations
  1230. validBody = m_templateMultiPass.FillVertexInstructions( m_subShaderIdx, m_passIdx, vertexInstructions.ToArray() ) && validBody;
  1231. validBody = m_templateMultiPass.FillFragmentInstructions( m_subShaderIdx, m_passIdx, fragmentInstructions.ToArray() ) && validBody;
  1232. vertexInstructions.Clear();
  1233. vertexInstructions = null;
  1234. fragmentInstructions.Clear();
  1235. fragmentInstructions = null;
  1236. // Add Instanced Properties
  1237. if( m_containerGraph.IsInstancedShader )
  1238. {
  1239. m_currentDataCollector.OptimizeInstancedProperties();
  1240. m_currentDataCollector.TabifyInstancedVars();
  1241. string cbufferBegin = string.Format( ( m_currentDataCollector.IsSRP ? IOUtils.LWSRPInstancedPropertiesBegin : IOUtils.InstancedPropertiesBegin ), m_currentDataCollector.InstanceBlockName );
  1242. string cBufferEnd = m_currentDataCollector.IsSRP ? ( string.Format( IOUtils.LWSRPInstancedPropertiesEnd, m_currentDataCollector.InstanceBlockName ) ) : IOUtils.InstancedPropertiesEnd;
  1243. m_currentDataCollector.InstancedPropertiesList.Insert( 0, new PropertyDataCollector( -1, cbufferBegin ) );
  1244. m_currentDataCollector.InstancedPropertiesList.Add( new PropertyDataCollector( -1, cBufferEnd ) );
  1245. m_currentDataCollector.UniformsList.AddRange( m_currentDataCollector.InstancedPropertiesList );
  1246. }
  1247. }
  1248. public void FillPropertyData( MasterNodeDataCollector dataCollector = null )
  1249. {
  1250. MasterNodeDataCollector currDataCollector = ( dataCollector == null ) ? m_currentDataCollector : dataCollector;
  1251. m_templateMultiPass.SetPropertyData( currDataCollector.BuildUnformatedPropertiesStringArr() );
  1252. }
  1253. public void FillSubShaderData( /*MasterNodeDataCollector dataCollector = null */)
  1254. {
  1255. //MasterNodeDataCollector currDataCollector = ( dataCollector == null ) ? m_currentDataCollector : dataCollector;
  1256. //// SubShader Data
  1257. //m_templateMultiPass.SetPropertyData( currDataCollector.BuildUnformatedPropertiesStringArr() );
  1258. //templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModulePass, m_subShaderIdx, currDataCollector.GrabPassList );
  1259. SetModuleData( m_subShaderModule, true );
  1260. }
  1261. public void FillPassData( TemplateMultiPassMasterNode masterNode )
  1262. {
  1263. if( m_isInvisible )
  1264. {
  1265. if( masterNode.UniqueId != UniqueId )
  1266. {
  1267. if( ( m_invisibleOptions & (int)InvisibleOptionsEnum.SyncProperties ) > 0 )
  1268. {
  1269. PassModule.SyncWith( masterNode.PassModule );
  1270. }
  1271. }
  1272. int inputCount = m_inputPorts.Count;
  1273. for( int i = 0; i < inputCount; i++ )
  1274. {
  1275. if( m_inputPorts[ i ].HasExternalLink )
  1276. {
  1277. TemplateMultiPassMasterNode linkedNode = m_inputPorts[ i ].ExternalLinkNode as TemplateMultiPassMasterNode;
  1278. if( linkedNode != null )
  1279. {
  1280. SetLinkedModuleData( linkedNode.PassModule );
  1281. }
  1282. }
  1283. }
  1284. }
  1285. SetModuleData( m_passModule, false );
  1286. if( m_currentDataCollector != null )
  1287. {
  1288. if( Pass.CustomOptionsContainer.CopyOptionsFromMainPass )
  1289. {
  1290. SetCustomOptionsInfo( m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode );
  1291. }
  1292. else
  1293. SetCustomOptionsInfo( this );
  1294. m_templateMultiPass.SetPassData( TemplateModuleDataType.PassVertexData, m_subShaderIdx, m_passIdx, m_currentDataCollector.VertexInputList.ToArray() );
  1295. m_templateMultiPass.SetPassData( TemplateModuleDataType.PassInterpolatorData, m_subShaderIdx, m_passIdx, m_currentDataCollector.InterpolatorList.ToArray() );
  1296. SetHDInfoOnPass();
  1297. List<PropertyDataCollector> includePragmaDefineList = new List<PropertyDataCollector>();
  1298. includePragmaDefineList.AddRange( m_currentDataCollector.IncludesList );
  1299. includePragmaDefineList.AddRange( m_currentDataCollector.DefinesList );
  1300. includePragmaDefineList.AddRange( m_currentDataCollector.PragmasList );
  1301. includePragmaDefineList.AddRange( m_currentDataCollector.MiscList );
  1302. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModulePragma, m_subShaderIdx, m_passIdx, includePragmaDefineList );
  1303. m_currentDataCollector.TemplateDataCollectorInstance.CloseLateDirectives();
  1304. //Add Functions
  1305. if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.FunctionsTag.IsValid )
  1306. {
  1307. m_currentDataCollector.FunctionsList.InsertRange( 0, m_currentDataCollector.TemplateDataCollectorInstance.LateDirectivesList );
  1308. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleFunctions, m_subShaderIdx, m_passIdx, m_currentDataCollector.FunctionsList );
  1309. }
  1310. else
  1311. {
  1312. m_currentDataCollector.UniformsList.InsertRange(0, m_currentDataCollector.TemplateDataCollectorInstance.LateDirectivesList );
  1313. m_currentDataCollector.UniformsList.AddRange( m_currentDataCollector.FunctionsList );
  1314. }
  1315. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleGlobals, m_subShaderIdx, m_passIdx, m_currentDataCollector.UniformsList );
  1316. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleInputVert, m_subShaderIdx, m_passIdx, m_currentDataCollector.TemplateDataCollectorInstance.VertexInputParamsStr );
  1317. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleInputFrag, m_subShaderIdx, m_passIdx, m_currentDataCollector.TemplateDataCollectorInstance.FragInputParamsStr );
  1318. }
  1319. m_templateMultiPass.SetPassData( TemplateModuleDataType.PassNameData, m_subShaderIdx, m_passIdx, string.Format( PassNameFormateStr, m_passName ) );
  1320. }
  1321. void SetHDInfoOnPass()
  1322. {
  1323. if( m_currentDataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD )
  1324. {
  1325. TemplateModulesHelper subShaderHelper = null;
  1326. TemplateModulesHelper passHelper = null;
  1327. if( m_isMainOutputNode )
  1328. {
  1329. subShaderHelper = m_subShaderModule;
  1330. passHelper = m_passModule;
  1331. }
  1332. else
  1333. {
  1334. TemplateMultiPassMasterNode masterNode = m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode;
  1335. if( masterNode != null )
  1336. {
  1337. subShaderHelper = masterNode.SubShaderModule;
  1338. passHelper = masterNode.PassModule;
  1339. }
  1340. else
  1341. {
  1342. subShaderHelper = m_subShaderModule;
  1343. passHelper = m_passModule;
  1344. }
  1345. }
  1346. RenderQueue renderQueue = RenderQueue.Geometry;
  1347. RenderType renderType = RenderType.Opaque;
  1348. if( passHelper.TagsHelper.HasRenderInfo( ref renderType, ref renderQueue ) ||
  1349. subShaderHelper.TagsHelper.HasRenderInfo( ref renderType, ref renderQueue ) )
  1350. {
  1351. if( renderType == RenderType.Transparent && renderQueue == RenderQueue.Transparent )
  1352. {
  1353. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransparentKeyword );
  1354. TemplatesBlendModule blendOpHelper = passHelper.BlendOpHelper.ValidBlendMode ? passHelper.BlendOpHelper : subShaderHelper.BlendOpHelper;
  1355. if( blendOpHelper.IsAdditiveRGB )
  1356. {
  1357. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialBlendModeAddKeyword );
  1358. }
  1359. else if( blendOpHelper.IsAlphaBlendRGB )
  1360. {
  1361. m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialBlendModeAlphaKeyword );
  1362. }
  1363. }
  1364. }
  1365. }
  1366. }
  1367. void SetLinkedModuleData( TemplateModulesHelper linkedModule )
  1368. {
  1369. //if( linkedModule.AdditionalPragmas.ValidData )
  1370. //{
  1371. // linkedModule.AdditionalPragmas.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer );
  1372. //}
  1373. //if( linkedModule.AdditionalIncludes.ValidData )
  1374. //{
  1375. // linkedModule.AdditionalIncludes.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer );
  1376. //}
  1377. //if( linkedModule.AdditionalDefines.ValidData )
  1378. //{
  1379. // linkedModule.AdditionalDefines.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer );
  1380. //}
  1381. if( linkedModule.AdditionalDirectives.ValidData )
  1382. {
  1383. linkedModule.AdditionalDirectives.AddAllToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer );
  1384. }
  1385. }
  1386. void SetModuleData( TemplateModulesHelper module, bool isSubShader )
  1387. {
  1388. if( isSubShader )
  1389. {
  1390. //if ( module.AdditionalPragmas.ValidData )
  1391. //{
  1392. // module.AdditionalPragmas.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.IncludePragmaContainer );
  1393. //}
  1394. //if ( module.AdditionalIncludes.ValidData )
  1395. //{
  1396. // module.AdditionalIncludes.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.IncludePragmaContainer );
  1397. //}
  1398. //if ( module.AdditionalDefines.ValidData )
  1399. //{
  1400. // module.AdditionalDefines.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.IncludePragmaContainer );
  1401. //}
  1402. if( module.AdditionalDirectives.ValidData )
  1403. {
  1404. module.AdditionalDirectives.AddAllToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.IncludePragmaContainer );
  1405. }
  1406. if( module.TagsHelper.ValidData )
  1407. {
  1408. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleTag, m_subShaderIdx, module.TagsHelper.GenerateTags() );
  1409. }
  1410. if( module.AllModulesMode )
  1411. {
  1412. string body = module.GenerateAllModulesString( isSubShader );
  1413. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.AllModules, m_subShaderIdx, body.Split( '\n' ) );
  1414. }
  1415. if( module.ShaderModelHelper.ValidAndIndependent )
  1416. {
  1417. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleShaderModel, m_subShaderIdx, module.ShaderModelHelper.GenerateShaderData( isSubShader ) );
  1418. }
  1419. if( module.BlendOpHelper.IndependentModule && module.BlendOpHelper.ValidBlendMode )
  1420. {
  1421. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleBlendMode, m_subShaderIdx, module.BlendOpHelper.CurrentBlendFactor );
  1422. }
  1423. if( module.BlendOpHelper.IndependentModule && module.BlendOpHelper.ValidBlendOp )
  1424. {
  1425. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleBlendOp, m_subShaderIdx, module.BlendOpHelper.CurrentBlendOp );
  1426. }
  1427. if( module.BlendOpHelper.AlphaToMaskIndependent && module.BlendOpHelper.ValidAlphaToMask )
  1428. {
  1429. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleAlphaToMask, m_subShaderIdx, module.BlendOpHelper.CurrentAlphaToMask );
  1430. }
  1431. if( module.CullModeHelper.ValidAndIndependent )
  1432. {
  1433. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleCullMode, m_subShaderIdx, module.CullModeHelper.GenerateShaderData( isSubShader ) );
  1434. }
  1435. if( module.ColorMaskHelper.ValidAndIndependent )
  1436. {
  1437. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleColorMask, m_subShaderIdx, module.ColorMaskHelper.GenerateShaderData( isSubShader ) );
  1438. }
  1439. if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidZTest )
  1440. {
  1441. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleZTest, m_subShaderIdx, module.DepthOphelper.CurrentZTestMode );
  1442. }
  1443. if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidZWrite )
  1444. {
  1445. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleZwrite, m_subShaderIdx, module.DepthOphelper.CurrentZWriteMode );
  1446. }
  1447. if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidOffset )
  1448. {
  1449. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleZOffset, m_subShaderIdx, module.DepthOphelper.CurrentOffset );
  1450. }
  1451. if( module.StencilBufferHelper.ValidAndIndependent )
  1452. {
  1453. CullMode cullMode = ( module.CullModeHelper.ValidData ) ? module.CullModeHelper.CurrentCullMode : CullMode.Back;
  1454. string value = module.StencilBufferHelper.CreateStencilOp( cullMode );
  1455. m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleStencil, m_subShaderIdx, value.Split( '\n' ) );
  1456. }
  1457. }
  1458. else
  1459. {
  1460. //if ( module.AdditionalPragmas.ValidData )
  1461. //{
  1462. // module.AdditionalPragmas.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer );
  1463. //}
  1464. //if ( module.AdditionalIncludes.ValidData )
  1465. //{
  1466. // module.AdditionalIncludes.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer );
  1467. //}
  1468. //if ( module.AdditionalDefines.ValidData )
  1469. //{
  1470. // module.AdditionalDefines.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer );
  1471. //}
  1472. List<PropertyDataCollector> aboveUsePass = new List<PropertyDataCollector>();
  1473. List<PropertyDataCollector> bellowUsePass = new List<PropertyDataCollector>();
  1474. m_usePass.BuildUsePassInfo( ref aboveUsePass, ref bellowUsePass );
  1475. //adding grab pass after use pass on purpose, so it wont be caught by them
  1476. aboveUsePass.AddRange( m_currentDataCollector.GrabPassList );
  1477. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModulePass, m_subShaderIdx, m_passIdx, aboveUsePass );
  1478. //m_templateMultiPass.SetPassData( TemplateModuleDataType.EndPass, m_subShaderIdx, m_passIdx, bellowUsePass);
  1479. if( module.AdditionalDirectives.ValidData )
  1480. {
  1481. module.AdditionalDirectives.AddAllToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer );
  1482. }
  1483. if( module.TagsHelper.ValidData )
  1484. {
  1485. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleTag, m_subShaderIdx, m_passIdx, module.TagsHelper.GenerateTags() );
  1486. }
  1487. if( module.AllModulesMode )
  1488. {
  1489. string body = module.GenerateAllModulesString( isSubShader );
  1490. m_templateMultiPass.SetPassData( TemplateModuleDataType.AllModules, m_subShaderIdx, m_passIdx, body.Split( '\n' ) );
  1491. }
  1492. if( module.ShaderModelHelper.ValidAndIndependent )
  1493. {
  1494. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleShaderModel, m_subShaderIdx, m_passIdx, module.ShaderModelHelper.GenerateShaderData( isSubShader ) );
  1495. }
  1496. if( module.BlendOpHelper.IndependentModule && module.BlendOpHelper.ValidBlendMode )
  1497. {
  1498. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleBlendMode, m_subShaderIdx, m_passIdx, module.BlendOpHelper.CurrentBlendFactor );
  1499. }
  1500. if( module.BlendOpHelper.IndependentModule && module.BlendOpHelper.ValidBlendOp )
  1501. {
  1502. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleBlendOp, m_subShaderIdx, m_passIdx, module.BlendOpHelper.CurrentBlendOp );
  1503. }
  1504. if( module.BlendOpHelper.AlphaToMaskIndependent && module.BlendOpHelper.ValidAlphaToMask )
  1505. {
  1506. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleAlphaToMask, m_subShaderIdx, m_passIdx, module.BlendOpHelper.CurrentAlphaToMask );
  1507. }
  1508. if( module.CullModeHelper.ValidAndIndependent )
  1509. {
  1510. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleCullMode, m_subShaderIdx, m_passIdx, module.CullModeHelper.GenerateShaderData( isSubShader ) );
  1511. }
  1512. if( module.ColorMaskHelper.ValidAndIndependent )
  1513. {
  1514. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleColorMask, m_subShaderIdx, m_passIdx, module.ColorMaskHelper.GenerateShaderData( isSubShader ) );
  1515. }
  1516. if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidZTest )
  1517. {
  1518. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleZTest, m_subShaderIdx, m_passIdx, module.DepthOphelper.CurrentZTestMode );
  1519. }
  1520. if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidZWrite )
  1521. {
  1522. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleZwrite, m_subShaderIdx, m_passIdx, module.DepthOphelper.CurrentZWriteMode );
  1523. }
  1524. if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidOffset )
  1525. {
  1526. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleZOffset, m_subShaderIdx, m_passIdx, module.DepthOphelper.CurrentOffset );
  1527. }
  1528. if( module.StencilBufferHelper.ValidAndIndependent )
  1529. {
  1530. CullMode cullMode = ( module.CullModeHelper.ValidData ) ? module.CullModeHelper.CurrentCullMode : CullMode.Back;
  1531. string value = module.StencilBufferHelper.CreateStencilOp( cullMode );
  1532. m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleStencil, m_subShaderIdx, m_passIdx, value.Split( '\n' ) );
  1533. }
  1534. }
  1535. }
  1536. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  1537. {
  1538. return "0";
  1539. }
  1540. public override void Destroy()
  1541. {
  1542. base.Destroy();
  1543. #if CUSTOM_OPTIONS_AVAILABLE
  1544. for( int i = 0; i < m_passCustomOptionsUI.Count; i++ )
  1545. {
  1546. m_passCustomOptionsUI[ i ].Destroy();
  1547. }
  1548. m_passCustomOptionsUI.Clear();
  1549. m_passCustomOptionsUI = null;
  1550. m_passCustomOptionsUIDict.Clear();
  1551. m_passCustomOptionsUIDict = null;
  1552. m_passCustomOptionsPorts.Clear();
  1553. m_passCustomOptionsPorts = null;
  1554. #endif
  1555. m_fallbackHelper.Destroy();
  1556. GameObject.DestroyImmediate( m_fallbackHelper );
  1557. m_fallbackHelper = null;
  1558. m_usePass.Destroy();
  1559. GameObject.DestroyImmediate( m_usePass );
  1560. m_usePass = null;
  1561. m_dependenciesHelper.Destroy();
  1562. m_dependenciesHelper = null;
  1563. m_subShaderModule.Destroy();
  1564. m_subShaderModule = null;
  1565. m_passModule.Destroy();
  1566. m_passModule = null;
  1567. m_containerGraph.MultiPassMasterNodes.RemoveNode( this );
  1568. }
  1569. void UpdateSubShaderPassStr()
  1570. {
  1571. m_subShaderIdxStr = SubShaderModuleStr + m_templateMultiPass.SubShaders[ m_subShaderIdx ].Idx;
  1572. m_passIdxStr = PassModuleStr + m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Idx;
  1573. }
  1574. public override void ReadFromString( ref string[] nodeParams )
  1575. {
  1576. base.ReadFromString( ref nodeParams );
  1577. try
  1578. {
  1579. string currShaderName = GetCurrentParam( ref nodeParams );
  1580. if( currShaderName.Length > 0 )
  1581. currShaderName = UIUtils.RemoveShaderInvalidCharacters( currShaderName );
  1582. m_templateGUID = GetCurrentParam( ref nodeParams );
  1583. m_subShaderIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  1584. m_passIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  1585. m_passName = GetCurrentParam( ref nodeParams );
  1586. SetTemplate( null, false, true, m_subShaderIdx, m_passIdx );
  1587. // only in here, after SetTemplate, we know if shader name is to be used as title or not
  1588. ShaderName = currShaderName;
  1589. m_visiblePorts = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  1590. m_subShaderModule.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1591. m_passModule.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1592. if( UIUtils.CurrentShaderVersion() > 15308 )
  1593. {
  1594. m_fallbackHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1595. m_dependenciesHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1596. }
  1597. if( UIUtils.CurrentShaderVersion() > 15402 )
  1598. {
  1599. m_usePass.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1600. }
  1601. if( UIUtils.CurrentShaderVersion() > 15409 )
  1602. {
  1603. m_hdSrpMaterialType = (HDSRPMaterialType)Enum.Parse( typeof( HDSRPMaterialType ), GetCurrentParam( ref nodeParams ) );
  1604. }
  1605. if( UIUtils.CurrentShaderVersion() > 15501 )
  1606. {
  1607. RefreshCustomOptionsDict();
  1608. int savedOptions = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  1609. for( int i = 0; i < savedOptions; i++ )
  1610. {
  1611. string optionName = GetCurrentParam( ref nodeParams );
  1612. int optionSelection = Convert.ToInt32( GetCurrentParam( ref nodeParams ) );
  1613. if( m_passCustomOptionsUIDict.ContainsKey( optionName ) )
  1614. {
  1615. m_passCustomOptionsUIDict[ optionName ].CurrentOption = optionSelection;
  1616. }
  1617. }
  1618. }
  1619. if( m_templateMultiPass != null && !m_templateMultiPass.IsSinglePass )
  1620. {
  1621. SetClippedTitle( m_passName );
  1622. }
  1623. }
  1624. catch( Exception e )
  1625. {
  1626. Debug.LogException( e, this );
  1627. }
  1628. m_containerGraph.CurrentCanvasMode = NodeAvailability.TemplateShader;
  1629. }
  1630. public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  1631. {
  1632. base.WriteToString( ref nodeInfo, ref connectionsInfo );
  1633. IOUtils.AddFieldValueToString( ref nodeInfo, ShaderName );
  1634. IOUtils.AddFieldValueToString( ref nodeInfo, m_templateGUID );
  1635. IOUtils.AddFieldValueToString( ref nodeInfo, m_subShaderIdx );
  1636. IOUtils.AddFieldValueToString( ref nodeInfo, m_passIdx );
  1637. IOUtils.AddFieldValueToString( ref nodeInfo, m_passName );
  1638. IOUtils.AddFieldValueToString( ref nodeInfo, m_visiblePorts );
  1639. m_subShaderModule.WriteToString( ref nodeInfo );
  1640. m_passModule.WriteToString( ref nodeInfo );
  1641. m_fallbackHelper.WriteToString( ref nodeInfo );
  1642. m_dependenciesHelper.WriteToString( ref nodeInfo );
  1643. m_usePass.WriteToString( ref nodeInfo );
  1644. IOUtils.AddFieldValueToString( ref nodeInfo, m_hdSrpMaterialType );
  1645. int optionsCount = m_passCustomOptionsUI.Count;
  1646. IOUtils.AddFieldValueToString( ref nodeInfo, optionsCount );
  1647. for( int i = 0; i < optionsCount; i++ )
  1648. {
  1649. IOUtils.AddFieldValueToString( ref nodeInfo, m_passCustomOptionsUI[ i ].Options.Id );
  1650. IOUtils.AddFieldValueToString( ref nodeInfo, m_passCustomOptionsUI[ i ].CurrentOption );
  1651. }
  1652. }
  1653. public override void ReadFromDeprecated( ref string[] nodeParams, Type oldType = null )
  1654. {
  1655. base.ReadFromString( ref nodeParams );
  1656. try
  1657. {
  1658. string currShaderName = GetCurrentParam( ref nodeParams );
  1659. if( currShaderName.Length > 0 )
  1660. currShaderName = UIUtils.RemoveShaderInvalidCharacters( currShaderName );
  1661. string templateGUID = GetCurrentParam( ref nodeParams );
  1662. string templateShaderName = string.Empty;
  1663. if( UIUtils.CurrentShaderVersion() > 13601 )
  1664. {
  1665. templateShaderName = GetCurrentParam( ref nodeParams );
  1666. }
  1667. TemplateMultiPass template = m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( templateGUID ) as TemplateMultiPass;
  1668. if( template != null )
  1669. {
  1670. m_templateGUID = templateGUID;
  1671. SetTemplate( null, false, true, 0, 0 );
  1672. }
  1673. else
  1674. {
  1675. template = m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplateByName( templateShaderName ) as TemplateMultiPass;
  1676. if( template != null )
  1677. {
  1678. m_templateGUID = template.GUID;
  1679. SetTemplate( null, false, true, 0, 0 );
  1680. }
  1681. else
  1682. {
  1683. m_masterNodeCategory = -1;
  1684. }
  1685. }
  1686. if( m_invalidNode )
  1687. return;
  1688. // only in here, after SetTemplate, we know if shader name is to be used as title or not
  1689. ShaderName = currShaderName;
  1690. if( UIUtils.CurrentShaderVersion() > 13902 )
  1691. {
  1692. //BLEND MODULE
  1693. if( m_templateMultiPass.SubShaders[ 0 ].Modules.BlendData.ValidBlendMode )
  1694. {
  1695. m_subShaderModule.BlendOpHelper.ReadBlendModeFromString( ref m_currentReadParamIdx, ref nodeParams );
  1696. }
  1697. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.BlendData.ValidBlendMode )
  1698. {
  1699. m_passModule.BlendOpHelper.ReadBlendModeFromString( ref m_currentReadParamIdx, ref nodeParams );
  1700. }
  1701. if( m_templateMultiPass.SubShaders[ 0 ].Modules.BlendData.ValidBlendOp )
  1702. {
  1703. m_subShaderModule.BlendOpHelper.ReadBlendOpFromString( ref m_currentReadParamIdx, ref nodeParams );
  1704. }
  1705. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.BlendData.ValidBlendOp )
  1706. {
  1707. m_passModule.BlendOpHelper.ReadBlendOpFromString( ref m_currentReadParamIdx, ref nodeParams );
  1708. }
  1709. //CULL MODE
  1710. if( m_templateMultiPass.SubShaders[ 0 ].Modules.CullModeData.DataCheck == TemplateDataCheck.Valid )
  1711. {
  1712. m_subShaderModule.CullModeHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1713. }
  1714. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.CullModeData.DataCheck == TemplateDataCheck.Valid )
  1715. {
  1716. m_passModule.CullModeHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1717. }
  1718. //COLOR MASK
  1719. if( m_templateMultiPass.SubShaders[ 0 ].Modules.ColorMaskData.DataCheck == TemplateDataCheck.Valid )
  1720. {
  1721. m_subShaderModule.ColorMaskHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1722. }
  1723. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.ColorMaskData.DataCheck == TemplateDataCheck.Valid )
  1724. {
  1725. m_passModule.ColorMaskHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1726. }
  1727. //STENCIL BUFFER
  1728. if( m_templateMultiPass.SubShaders[ 0 ].Modules.StencilData.DataCheck == TemplateDataCheck.Valid )
  1729. {
  1730. m_subShaderModule.StencilBufferHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1731. }
  1732. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.StencilData.DataCheck == TemplateDataCheck.Valid )
  1733. {
  1734. m_passModule.StencilBufferHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1735. }
  1736. }
  1737. if( UIUtils.CurrentShaderVersion() > 14202 )
  1738. {
  1739. //DEPTH OPTIONS
  1740. if( m_templateMultiPass.SubShaders[ 0 ].Modules.DepthData.ValidZWrite )
  1741. {
  1742. m_subShaderModule.DepthOphelper.ReadZWriteFromString( ref m_currentReadParamIdx, ref nodeParams );
  1743. }
  1744. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.DepthData.ValidZWrite )
  1745. {
  1746. m_passModule.DepthOphelper.ReadZWriteFromString( ref m_currentReadParamIdx, ref nodeParams );
  1747. }
  1748. if( m_templateMultiPass.SubShaders[ 0 ].Modules.DepthData.ValidZTest )
  1749. {
  1750. m_subShaderModule.DepthOphelper.ReadZTestFromString( ref m_currentReadParamIdx, ref nodeParams );
  1751. }
  1752. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.DepthData.ValidZTest )
  1753. {
  1754. m_subShaderModule.DepthOphelper.ReadZTestFromString( ref m_currentReadParamIdx, ref nodeParams );
  1755. }
  1756. if( m_templateMultiPass.SubShaders[ 0 ].Modules.DepthData.ValidOffset )
  1757. {
  1758. m_subShaderModule.DepthOphelper.ReadOffsetFromString( ref m_currentReadParamIdx, ref nodeParams );
  1759. }
  1760. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.DepthData.ValidOffset )
  1761. {
  1762. m_passModule.DepthOphelper.ReadOffsetFromString( ref m_currentReadParamIdx, ref nodeParams );
  1763. }
  1764. }
  1765. //TAGS
  1766. if( UIUtils.CurrentShaderVersion() > 14301 )
  1767. {
  1768. if( m_templateMultiPass.SubShaders[ 0 ].Modules.TagData.DataCheck == TemplateDataCheck.Valid )
  1769. {
  1770. m_subShaderModule.TagsHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1771. }
  1772. else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.TagData.DataCheck == TemplateDataCheck.Valid )
  1773. {
  1774. m_passModule.TagsHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams );
  1775. }
  1776. }
  1777. }
  1778. catch( Exception e )
  1779. {
  1780. Debug.LogException( e, this );
  1781. }
  1782. m_containerGraph.CurrentCanvasMode = NodeAvailability.TemplateShader;
  1783. }
  1784. public override void RefreshExternalReferences()
  1785. {
  1786. base.RefreshExternalReferences();
  1787. CheckTemplateChanges();
  1788. if( m_templateMultiPass != null && m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.SRPIsPBRHD && UIUtils.CurrentShaderVersion() < 15410 )
  1789. {
  1790. FetchHDPorts();
  1791. m_hdSrpMaterialType = ( m_specularPort != null && m_specularPort.HasOwnOrLinkConnection ) ? HDSRPMaterialType.Specular : HDSRPMaterialType.Standard;
  1792. ConfigHDPorts();
  1793. }
  1794. }
  1795. public override float HeightEstimate
  1796. {
  1797. get
  1798. {
  1799. float heightEstimate = 0;
  1800. heightEstimate = 32 + Constants.INPUT_PORT_DELTA_Y;
  1801. if( m_templateMultiPass != null && !m_templateMultiPass.IsSinglePass )
  1802. {
  1803. heightEstimate += 22;
  1804. }
  1805. float internalPortSize = 0;
  1806. for( int i = 0; i < InputPorts.Count; i++ )
  1807. {
  1808. if( InputPorts[ i ].Visible )
  1809. internalPortSize += 18 + Constants.INPUT_PORT_DELTA_Y;
  1810. }
  1811. return heightEstimate + Mathf.Max( internalPortSize, m_insideSize.y );
  1812. }
  1813. }
  1814. public HDSRPMaterialType CurrentHDMaterialType
  1815. {
  1816. get { return m_hdSrpMaterialType; }
  1817. set
  1818. {
  1819. m_hdSrpMaterialType = value;
  1820. if( m_isMainOutputNode )
  1821. {
  1822. List<TemplateMultiPassMasterNode> mpNodes = UIUtils.CurrentWindow.CurrentGraph.MultiPassMasterNodes.NodesList;
  1823. int count = mpNodes.Count;
  1824. for( int i = 0; i < count; i++ )
  1825. {
  1826. if( mpNodes[ i ].UniqueId != UniqueId )
  1827. {
  1828. mpNodes[ i ].CurrentHDMaterialType = value;
  1829. }
  1830. }
  1831. }
  1832. }
  1833. }
  1834. public TemplateSubShader SubShader { get { return m_templateMultiPass.SubShaders[ m_subShaderIdx ]; } }
  1835. public TemplatePass Pass { get { return m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ]; } }
  1836. public int SubShaderIdx { get { return m_subShaderIdx; } }
  1837. public int PassIdx { get { return m_passIdx; } }
  1838. public TemplateMultiPass CurrentTemplate { get { return m_templateMultiPass; } }
  1839. public TemplateModulesHelper SubShaderModule { get { return m_subShaderModule; } }
  1840. public TemplateModulesHelper PassModule { get { return m_passModule; } }
  1841. public string PassName { get { return m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data; } }
  1842. public string OriginalPassName { get { return m_originalPassName; } }
  1843. public bool HasLinkPorts { get { return m_hasLinkPorts; } }
  1844. public bool IsInvisible { get { return m_isInvisible; } }
  1845. #if CUSTOM_OPTIONS_AVAILABLE
  1846. public List<TemplateOptionUIItem> PassCustomOptionsUI { get { return m_passCustomOptionsUI; } }
  1847. public List<TemplateOptionPortItem> PassCustomOptionsPorts { get { return m_passCustomOptionsPorts; } }
  1848. #endif
  1849. }
  1850. }