// Amplify Shader Editor - Visual Shader Editing Tool // Copyright (c) Amplify Creations, Lda //#define SHOW_TEMPLATE_HELP_BOX #define SHOW_HD_SRP #define CUSTOM_OPTIONS_AVAILABLE using System; using System.Collections.Generic; using UnityEngine; using UnityEditor; namespace AmplifyShaderEditor { public enum HDSRPMaterialType { SubsurfaceScattering, Standard, Specular, Anisotropy, Iridescence, Translucent } [Serializable] [NodeAttributes( "Template Master Node", "Master", "Shader Generated according to template rules", null, KeyCode.None, false )] public sealed class TemplateMultiPassMasterNode : MasterNode { private const string SubTitleFormatterStr = "(SubShader {0} Pass {1})"; private const string NoSubShaderPropertyStr = "No Sub-Shader properties available"; private const string NoPassPropertyStr = "No Pass properties available"; 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."; private const string OpenTemplateStr = "Edit Template"; private const string ReloadTemplateStr = "Reload Template"; private const string CommonPropertiesStr = "Common Properties "; private const string SubShaderModuleStr = "SubShader "; private const string PassModuleStr = "Pass "; private const string PassNameStr = "Name"; private const string PassNameFormateStr = "Name \"{0}\""; private bool m_reRegisterTemplateData = false; private bool m_fireTemplateChange = false; private bool m_fetchMasterNodeCategory = false; [SerializeField] private string m_templateGUID = "4e1801f860093ba4f9eb58a4b556825b"; [SerializeField] private int m_passIdx = 0; [SerializeField] private string m_passIdxStr = string.Empty; [SerializeField] private bool m_passFoldout = false; [SerializeField] private int m_subShaderIdx = 0; [SerializeField] private string m_subShaderIdxStr = string.Empty; [SerializeField] private bool m_subStringFoldout = false; [SerializeField] private int m_subShaderLOD = -1; [SerializeField] private string m_subShaderLODStr; //[SerializeField] //private bool m_mainMPMasterNode = false; [NonSerialized] private TemplateMultiPass m_templateMultiPass = null; [NonSerialized] private TemplateMultiPassMasterNode m_mainMasterNodeRef = null; [SerializeField] private TemplateModulesHelper m_subShaderModule = new TemplateModulesHelper(); [SerializeField] private TemplateModulesHelper m_passModule = new TemplateModulesHelper(); [SerializeField] private UsePassHelper m_usePass; [SerializeField] private string m_passName = string.Empty; [SerializeField] private string m_originalPassName = string.Empty; [SerializeField] private bool m_hasLinkPorts = false; [SerializeField] private bool m_isInvisible = false; [SerializeField] private int m_invisibleOptions = 0; [SerializeField] private bool m_invalidNode = false; [SerializeField] private FallbackPickerHelper m_fallbackHelper = null; [SerializeField] private DependenciesHelper m_dependenciesHelper = new DependenciesHelper(); #if CUSTOM_OPTIONS_AVAILABLE private const string CustomOptionsLabel = " Custom Options"; [SerializeField] private bool m_passCustomOptionsFoldout = false; [SerializeField] private string m_passCustomOptionsLabel = CustomOptionsLabel; [SerializeField] private int m_passCustomOptionsSizeCheck = 0; [SerializeField] private List m_passCustomOptionsUI = new List(); [NonSerialized] private Dictionary m_passCustomOptionsUIDict = new Dictionary(); [SerializeField] private List m_passCustomOptionsPorts = new List(); #endif // HATE THIS BELOW, MUST REMOVE HD SPECIFIC CODE FROM GENERIC MASTER NODE private const string HDSRPMaterialTypeStr = "Material Type"; private const string SRPMaterialSubsurfaceScatteringKeyword = "_MATERIAL_FEATURE_SUBSURFACE_SCATTERING 1"; private const string SRPMaterialTransmissionKeyword = "_MATERIAL_FEATURE_TRANSMISSION 1"; private const string SRPHDMaterialSpecularKeyword = "_MATERIAL_FEATURE_SPECULAR_COLOR 1"; private const string SRPLWMaterialSpecularKeyword = "_SPECULAR_SETUP 1"; private const string SRPMaterialAnisotropyKeyword = "_MATERIAL_FEATURE_ANISOTROPY 1"; private const string SRPMaterialIridiscenceKeyword = "_MATERIAL_FEATURE_IRIDESCENCE 1"; private const string SRPMaterialNormalMapKeyword = "_NORMALMAP 1"; private const string SRPMaterialAlphaTestKeyword = "_ALPHATEST_ON 1"; private const string SRPMaterialBlendModeAlphaClipThresholdKeyword = "_AlphaClip 1"; private const string SRPMaterialTransparentKeyword = "_SURFACE_TYPE_TRANSPARENT 1"; private const string SRPMaterialBlendModeAddKeyword = "_BLENDMODE_ADD 1"; private const string SRPMaterialBlendModeAlphaKeyword = "_BLENDMODE_ALPHA 1"; private const string SRPMaterialClearCoatKeyword = "_MATERIAL_FEATURE_CLEAR_COAT"; [NonSerialized] private bool m_fetchPorts = true; [NonSerialized] private InputPort m_specularPort; [NonSerialized] private InputPort m_metallicPort; [NonSerialized] private InputPort m_coatMaskPort; [NonSerialized] private InputPort m_diffusionProfilePort; [NonSerialized] private InputPort m_subsurfaceMaskPort; [NonSerialized] private InputPort m_thicknessPort; [NonSerialized] private InputPort m_anisotropyPort; [NonSerialized] private InputPort m_iridescenceThicknessPort; [NonSerialized] private InputPort m_iridescenceMaskPort; [NonSerialized] private InputPort m_indexOfRefractionPort; [NonSerialized] private InputPort m_transmittanceColorPort; [NonSerialized] private InputPort m_transmittanceAbsorptionDistancePort; [NonSerialized] private InputPort m_transmittanceMaskPort; [SerializeField] private HDSRPMaterialType m_hdSrpMaterialType = HDSRPMaterialType.Standard; ////////////////////////////////////////////////////////////////////////// protected override void CommonInit( int uniqueId ) { base.CommonInit( uniqueId ); m_masterNodeCategory = 1;// First Template m_marginPreviewLeft = 20; m_shaderNameIsTitle = false; m_customInspectorName = string.Empty; } public override void ReleaseResources() { if( !m_isMainOutputNode ) return; m_containerGraph.ClearInternalTemplateNodes(); TemplateMultiPass template = ( m_templateMultiPass == null ) ? m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( m_templateGUID ) as TemplateMultiPass : m_templateMultiPass; if( template != null && template.AvailableShaderProperties != null ) { // Unregister old template properties int oldPropertyCount = template.AvailableShaderProperties.Count; for( int i = 0; i < oldPropertyCount; i++ ) { UIUtils.ReleaseUniformName( UniqueId, template.AvailableShaderProperties[ i ].PropertyName ); } } } void RegisterProperties() { if( !m_isMainOutputNode ) { m_reRegisterTemplateData = false; return; } if( m_templateMultiPass != null ) { m_reRegisterTemplateData = false; // Register old template properties int newPropertyCount = m_templateMultiPass.AvailableShaderProperties.Count; for( int i = 0; i < newPropertyCount; i++ ) { m_containerGraph.AddInternalTemplateNode( m_templateMultiPass.AvailableShaderProperties[ i ] ); int nodeId = UIUtils.CheckUniformNameOwner( m_templateMultiPass.AvailableShaderProperties[ i ].PropertyName ); if( nodeId > -1 ) { if( UniqueId != nodeId ) { ParentNode node = m_containerGraph.GetNode( nodeId ); if( node != null ) { 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 ) ); } else { 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 ) ); } } } else { UIUtils.RegisterUniformName( UniqueId, m_templateMultiPass.AvailableShaderProperties[ i ].PropertyName ); } } } } public override void OnEnable() { base.OnEnable(); m_reRegisterTemplateData = true; if( m_usePass == null ) { m_usePass = ScriptableObject.CreateInstance(); m_usePass.Init(" Additional Use Passes" ); } if( m_fallbackHelper == null ) { m_fallbackHelper = ScriptableObject.CreateInstance(); m_fallbackHelper.Init(); } } protected override void OnUniqueIDAssigned() { base.OnUniqueIDAssigned(); if( UniqueId >= 0 ) { m_containerGraph.MultiPassMasterNodes.AddNode( this ); } } public void SetTemplate( TemplateMultiPass template, bool writeDefaultData, bool fetchMasterNodeCategory, int subShaderIdx, int passIdx ) { if( subShaderIdx > -1 ) m_subShaderIdx = subShaderIdx; if( passIdx > -1 ) m_passIdx = passIdx; ReleaseResources(); m_templateMultiPass = ( template == null ) ? m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( m_templateGUID ) as TemplateMultiPass : template; if( m_templateMultiPass != null ) { m_containerGraph.CurrentSRPType = m_templateMultiPass.SRPtype; if( m_templateMultiPass.IsSinglePass ) { SetAdditonalTitleText( string.Empty ); } else { SetAdditonalTitleText( string.Format( SubTitleFormatterStr, m_subShaderIdx, m_passIdx ) ); } m_invalidNode = false; if( m_subShaderIdx >= m_templateMultiPass.SubShaders.Count || m_passIdx >= m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes.Count ) { if( DebugConsoleWindow.DeveloperMode ) Debug.LogFormat( "Inexisting pass {0}. Cancelling template fetch", m_originalPassName ); return; } m_isMainOutputNode = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].IsMainPass; if( m_isMainOutputNode ) { // We cannot use UIUtils.MasterNodeOnTexture.height since this method can be // called before UIUtils is initialized m_insideSize.y = 55; } else { m_insideSize.y = 0; } //IsMainOutputNode = m_mainMPMasterNode; m_isInvisible = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].IsInvisible; m_invisibleOptions = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].InvisibleOptions; m_originalPassName = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data; m_shaderNameIsTitle = ( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes.Count == 1 ); if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Index > -1 ) { m_subShaderLODStr = m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Id; m_subShaderLOD = Convert.ToInt32( m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Data ); } else { m_subShaderLOD = -1; } m_fetchMasterNodeCategory = fetchMasterNodeCategory; m_templateGUID = m_templateMultiPass.GUID; UpdatePortInfo(); RegisterProperties(); // template is null when hot code reloading or loading from file so inspector name shouldn't be changed if( template != null ) { m_customInspectorName = m_templateMultiPass.CustomInspectorContainer.Data; } #if CUSTOM_OPTIONS_AVAILABLE SetupCustomOptionsFromTemplate( template != null ); #endif if( string.IsNullOrEmpty( m_fallbackHelper.RawFallbackShader ) ) m_fallbackHelper.RawFallbackShader = m_templateMultiPass.FallbackContainer.Data; //bool updateInfofromTemplate = UpdatePortInfo(); //if( updateInfofromTemplate ) //{ m_subShaderModule.FetchDataFromTemplate( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules ); m_passModule.FetchDataFromTemplate( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules ); //} //RegisterProperties(); if( writeDefaultData ) { ShaderName = m_templateMultiPass.DefaultShaderName; m_passName = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data; if( !m_templateMultiPass.IsSinglePass && !m_shaderNameIsTitle ) { SetClippedTitle( m_passName ); } } UpdateSubShaderPassStr(); if( m_isMainOutputNode ) m_fireTemplateChange = true; } else { m_invalidNode = true; } } public override void OnRefreshLinkedPortsComplete() { if( m_invalidNode ) return; if( m_templateMultiPass.SubShaders[m_subShaderIdx].Passes[m_passIdx].Modules.SRPIsPBRHD ) ConfigHDPorts(); } bool UpdatePortInfo() { List inputDataList = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].InputDataList; int count = inputDataList.Count; if( count != m_inputPorts.Count ) { DeleteAllInputConnections( true ); for( int i = 0; i < count; i++ ) { InputPort port = AddInputPort( inputDataList[ i ].DataType, false, inputDataList[ i ].PortName, inputDataList[ i ].OrderId, inputDataList[ i ].PortCategory, inputDataList[ i ].PortUniqueId ); port.ExternalLinkId = inputDataList[ i ].LinkId; m_hasLinkPorts = m_hasLinkPorts || !string.IsNullOrEmpty( inputDataList[ i ].LinkId ); } return true; } else { for( int i = 0; i < count; i++ ) { m_inputPorts[ i ].ChangeProperties( inputDataList[ i ].PortName, inputDataList[ i ].DataType, false ); m_inputPorts[ i ].ExternalLinkId = inputDataList[ i ].LinkId; } return false; } } #if CUSTOM_OPTIONS_AVAILABLE void DrawCustomOptions() { for( int i = 0; i < m_passCustomOptionsUI.Count; i++ ) { m_passCustomOptionsUI[ i ].Draw( this ); } EditorGUILayout.Space(); } public void OnCustomOptionSelected( TemplateOptionUIItem uiItem, params TemplateActionItem[] validActions ) { uiItem.CheckOnExecute = false; for( int i = 0; i < validActions.Length; i++ ) { switch( validActions[ i ].ActionType ) { case AseOptionsActionType.ShowOption: { TemplateOptionUIItem item = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( validActions[ i ].ActionData ) ) ); if( item != null ) { item.IsVisible = true; } } break; case AseOptionsActionType.HideOption: { TemplateOptionUIItem item = m_passCustomOptionsUI.Find( x => ( x.Options.Name.Equals( validActions[ i ].ActionData ) ) ); if( item != null ) { item.IsVisible = false; } } break; case AseOptionsActionType.HidePort: { InputPort port = m_inputPorts.Find( x => x.Name.Equals( validActions[ i ].ActionData ) ); if( port != null ) { port.Visible = false; m_sizeIsDirty = true; } } break; case AseOptionsActionType.ShowPort: { InputPort port = m_inputPorts.Find( x => x.Name.Equals( validActions[ i ].ActionData ) ); if( port != null ) { port.Visible = true; m_sizeIsDirty = true; } } break; case AseOptionsActionType.SetDefine: { uiItem.CheckOnExecute = true; } break; case AseOptionsActionType.UnsetDefine: { uiItem.CheckOnExecute = true; } break; case AseOptionsActionType.ExcludePass: { } break; } } } void SetupCustomOptionsFromTemplate( bool newTemplate ) { TemplateOptionsContainer customOptionsContainer = Pass.CustomOptionsContainer; if( !newTemplate && customOptionsContainer.Body.Length == m_passCustomOptionsSizeCheck ) { for( int i = 0; i < m_passCustomOptionsUI.Count; i++ ) { if( m_passCustomOptionsUI[ i ].EmptyEvent ) { m_passCustomOptionsUI[ i ].OnActionPerformedEvt += OnCustomOptionSelected; } } return; } m_passCustomOptionsLabel = string.IsNullOrEmpty( customOptionsContainer.Name ) ? CustomOptionsLabel : " " + customOptionsContainer.Name; for( int i = 0; i < m_passCustomOptionsUI.Count; i++ ) { m_passCustomOptionsUI[ i ].Destroy(); } m_passCustomOptionsUI.Clear(); m_passCustomOptionsUIDict.Clear(); m_passCustomOptionsPorts.Clear(); if( customOptionsContainer.Enabled ) { m_passCustomOptionsSizeCheck = customOptionsContainer.Body.Length; for( int i = 0; i < customOptionsContainer.Options.Length; i++ ) { switch( customOptionsContainer.Options[ i ].Type ) { case AseOptionsType.Option: { TemplateOptionUIItem item = new TemplateOptionUIItem( customOptionsContainer.Options[ i ] ); item.OnActionPerformedEvt += OnCustomOptionSelected; m_passCustomOptionsUI.Add( item ); m_passCustomOptionsUIDict.Add( customOptionsContainer.Options[ i ].Id, item ); } break; case AseOptionsType.Port: { TemplateOptionPortItem item = new TemplateOptionPortItem( this, customOptionsContainer.Options[ i ] ); m_passCustomOptionsPorts.Add( item ); } break; } } } else { m_passCustomOptionsSizeCheck = 0; } } void SetCustomOptionsInfo( TemplateMultiPassMasterNode masterNode ) { if( masterNode == null ) return; for( int i = 0; i < masterNode.PassCustomOptionsUI.Count; i++ ) { masterNode.PassCustomOptionsUI[ i ].FillDataCollector( ref m_currentDataCollector ); } for( int i = 0; i < masterNode.PassCustomOptionsPorts.Count; i++ ) { masterNode.PassCustomOptionsPorts[ i ].FillDataCollector( masterNode, ref m_currentDataCollector ); } } void RefreshCustomOptionsDict() { if( m_passCustomOptionsUIDict.Count != m_passCustomOptionsUI.Count ) { m_passCustomOptionsUIDict.Clear(); int count = m_passCustomOptionsUI.Count; for( int i = 0; i < count; i++ ) { m_passCustomOptionsUIDict.Add( m_passCustomOptionsUI[ i ].Options.Id, m_passCustomOptionsUI[ i ] ); } } } #endif void SetCategoryIdxFromTemplate() { int templateCount = m_containerGraph.ParentWindow.TemplatesManagerInstance.TemplateCount; for( int i = 0; i < templateCount; i++ ) { int idx = i + 1; TemplateMultiPass templateData = m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( i ) as TemplateMultiPass; if( templateData != null && m_templateMultiPass != null && m_templateMultiPass.GUID.Equals( templateData.GUID ) ) m_masterNodeCategory = idx; } } void CheckTemplateChanges() { if( m_invalidNode ) return; if( m_isMainOutputNode ) { if( m_containerGraph.MultiPassMasterNodes.Count != m_templateMultiPass.MasterNodesRequired ) { if( m_availableCategories == null ) RefreshAvailableCategories(); if( DebugConsoleWindow.DeveloperMode ) Debug.Log( "Template Pass amount was changed. Rebuiling master nodes" ); m_containerGraph.ParentWindow.ReplaceMasterNode( m_availableCategories[ m_masterNodeCategory ], true ); } } } public override void OnNodeLogicUpdate( DrawInfo drawInfo ) { base.OnNodeLogicUpdate( drawInfo ); if( m_invalidNode ) { return; } if( m_templateMultiPass == null ) { // Hotcode reload has happened SetTemplate( null, false, true, m_subShaderIdx, m_passIdx ); CheckTemplateChanges(); } if( m_reRegisterTemplateData ) { RegisterProperties(); } if( m_fetchMasterNodeCategory ) { if( m_availableCategories != null ) { m_fetchMasterNodeCategory = false; SetCategoryIdxFromTemplate(); } } if( m_fireTemplateChange ) { m_fireTemplateChange = false; m_containerGraph.FireMasterNodeReplacedEvent(); } if( m_subShaderModule.HasValidData ) { m_subShaderModule.OnLogicUpdate( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules ); } if( m_passModule.HasValidData ) { m_passModule.OnLogicUpdate( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules ); } } public override void Draw( DrawInfo drawInfo ) { if( !m_isInvisible ) { base.Draw( drawInfo ); } } public override void OnNodeLayout( DrawInfo drawInfo ) { if( m_invalidNode ) { if( m_isMainOutputNode ) { UIUtils.ShowMessage( "Invalid current template. Switching to Standard Surface", MessageSeverity.Error ); m_shaderModelIdx = 0; m_masterNodeCategory = 0; m_containerGraph.ParentWindow.ReplaceMasterNode( new MasterNodeCategoriesData( AvailableShaderTypes.SurfaceShader, m_shaderName ), false ); } return; } if( m_isInvisible ) { return; } if( !IsMainOutputNode ) { if( !IsInvisible && Docking ) { m_useSquareNodeTitle = true; TemplateMultiPassMasterNode master = ContainerGraph.CurrentMasterNode as TemplateMultiPassMasterNode; m_position = master.TruePosition; m_position.height = 32; int masterIndex = ContainerGraph.MultiPassMasterNodes.NodesList.IndexOf( master ); int index = ContainerGraph.MultiPassMasterNodes.GetNodeRegisterIdx( UniqueId ); if( index > masterIndex ) { int backTracking = 0; for( int i = index - 1; i > masterIndex; i-- ) { if( !ContainerGraph.MultiPassMasterNodes.NodesList[ i ].IsInvisible && ContainerGraph.MultiPassMasterNodes.NodesList[ i ].Docking ) backTracking++; } m_position.y = master.TruePosition.yMax + 1 + 33 * ( backTracking );// ContainerGraph.MultiPassMasterNodes.NodesList[ index - 1 ].TruePosition.yMax; base.OnNodeLayout( drawInfo ); } else { int forwardTracking = 1; for( int i = index + 1; i < masterIndex; i++ ) { if( !ContainerGraph.MultiPassMasterNodes.NodesList[ i ].IsInvisible && ContainerGraph.MultiPassMasterNodes.NodesList[ i ].Docking ) forwardTracking++; } m_position.y = master.TruePosition.y - 33 * ( forwardTracking );// ContainerGraph.MultiPassMasterNodes.NodesList[ index - 1 ].TruePosition.yMax; base.OnNodeLayout( drawInfo ); } } else { m_useSquareNodeTitle = false; base.OnNodeLayout( drawInfo ); } } else { base.OnNodeLayout( drawInfo ); } } public override void OnNodeRepaint( DrawInfo drawInfo ) { base.OnNodeRepaint( drawInfo ); if( m_invalidNode ) return; if( !m_isInvisible ) { if( m_containerGraph.IsInstancedShader ) { DrawInstancedIcon( drawInfo ); } } } public override void UpdateFromShader( Shader newShader ) { if( m_currentMaterial != null && m_currentMaterial.shader != newShader ) { m_currentMaterial.shader = newShader; } CurrentShader = newShader; } public override void UpdateMasterNodeMaterial( Material material ) { m_currentMaterial = material; FireMaterialChangedEvt(); } void DrawReloadButton() { if( GUILayout.Button( ReloadTemplateStr ) && m_templateMultiPass != null ) { m_templateMultiPass.Reload(); } } void DrawOpenTemplateButton() { GUILayout.BeginHorizontal(); { if( GUILayout.Button( OpenTemplateStr ) && m_templateMultiPass != null ) { try { string pathname = AssetDatabase.GUIDToAssetPath( m_templateMultiPass.GUID ); if( !string.IsNullOrEmpty( pathname ) ) { Shader selectedTemplate = AssetDatabase.LoadAssetAtPath( pathname ); if( selectedTemplate != null ) { AssetDatabase.OpenAsset( selectedTemplate, 1 ); } } } catch( Exception e ) { Debug.LogException( e ); } } if( GUILayout.Button( "\u25C4", GUILayout.Width( 18 ), GUILayout.Height( 18 ) ) && m_templateMultiPass != null ) { try { string pathname = AssetDatabase.GUIDToAssetPath( m_templateMultiPass.GUID ); if( !string.IsNullOrEmpty( pathname ) ) { Shader selectedTemplate = AssetDatabase.LoadAssetAtPath( pathname ); if( selectedTemplate != null ) { Event.current.Use(); Selection.activeObject = selectedTemplate; EditorGUIUtility.PingObject( Selection.activeObject ); } } } catch( Exception e ) { Debug.LogException( e ); } } } GUILayout.EndHorizontal(); } public override void DrawProperties() { base.DrawProperties(); if( m_invalidNode ) return; NodeUtils.DrawPropertyGroup( ref m_propertiesFoldout, CommonPropertiesStr, DrawCommonProperties ); NodeUtils.DrawPropertyGroup( ref m_subStringFoldout, SubShaderModuleStr, DrawSubShaderProperties ); NodeUtils.DrawPropertyGroup( ref m_passFoldout, PassModuleStr, DrawPassProperties ); DrawMaterialInputs( UIUtils.MenuItemToolbarStyle, false ); if( m_propertyOrderChanged ) { List mpNodes = UIUtils.CurrentWindow.CurrentGraph.MultiPassMasterNodes.NodesList; int count = mpNodes.Count; for( int i = 0; i < count; i++ ) { if( mpNodes[ i ].UniqueId != UniqueId ) { mpNodes[ i ].CopyPropertyListFrom( this ); } } } #if SHOW_TEMPLATE_HELP_BOX EditorGUILayout.HelpBox( WarningMessage, MessageType.Warning ); #endif } void AddHDKeywords() { if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType != TemplateSRPType.HD || !m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[m_passIdx].Modules.SRPIsPBR ) return; switch( m_hdSrpMaterialType ) { case HDSRPMaterialType.SubsurfaceScattering: { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialSubsurfaceScatteringKeyword ); if( m_thicknessPort != null && m_thicknessPort.HasOwnOrLinkConnection ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransmissionKeyword ); } } break; case HDSRPMaterialType.Standard: break; case HDSRPMaterialType.Specular: { m_currentDataCollector.AddToDefines( UniqueId, SRPHDMaterialSpecularKeyword ); } break; case HDSRPMaterialType.Anisotropy: { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialAnisotropyKeyword ); } break; case HDSRPMaterialType.Iridescence: { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialIridiscenceKeyword ); } break; case HDSRPMaterialType.Translucent: { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransmissionKeyword ); } break; } if( m_coatMaskPort != null && m_coatMaskPort.HasOwnOrLinkConnection ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialClearCoatKeyword ); } } void FetchHDPorts() { if( m_fetchPorts ) { m_fetchPorts = false; if( m_inputPorts.Count > 4 ) { m_specularPort = GetInputPortByUniqueId( 3 ); m_metallicPort = GetInputPortByUniqueId( 4 ); m_coatMaskPort = GetInputPortByUniqueId( 11 ); m_diffusionProfilePort = GetInputPortByUniqueId( 12 ); m_subsurfaceMaskPort = GetInputPortByUniqueId( 13 ); m_thicknessPort = GetInputPortByUniqueId( 14 ); m_anisotropyPort = GetInputPortByUniqueId( 15 ); m_iridescenceThicknessPort = GetInputPortByUniqueId( 16 ); m_iridescenceMaskPort = GetInputPortByUniqueId( 17 ); m_indexOfRefractionPort = GetInputPortByUniqueId( 18 ); m_transmittanceColorPort = GetInputPortByUniqueId( 19 ); m_transmittanceAbsorptionDistancePort = GetInputPortByUniqueId( 20 ); m_transmittanceMaskPort = GetInputPortByUniqueId( 21 ); } } } void ConfigHDPorts() { if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType != TemplateSRPType.HD || !m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.SRPIsPBR ) return; FetchHDPorts(); if( m_inputPorts.Count > 4 ) { switch( m_hdSrpMaterialType ) { case HDSRPMaterialType.SubsurfaceScattering: { m_specularPort.Visible = false; m_metallicPort.Visible = false; m_coatMaskPort.Visible = true; m_diffusionProfilePort.Visible = true; m_subsurfaceMaskPort.Visible = true; m_thicknessPort.Visible = true; m_anisotropyPort.Visible = false; m_iridescenceThicknessPort.Visible = false; m_iridescenceMaskPort.Visible = false; m_indexOfRefractionPort.Visible = false; m_transmittanceColorPort.Visible = false; m_transmittanceAbsorptionDistancePort.Visible = false; m_transmittanceMaskPort.Visible = false; } break; case HDSRPMaterialType.Standard: { m_specularPort.Visible = false; m_metallicPort.Visible = true; m_coatMaskPort.Visible = true; m_diffusionProfilePort.Visible = false; m_subsurfaceMaskPort.Visible = false; m_thicknessPort.Visible = false; m_anisotropyPort.Visible = false; m_iridescenceThicknessPort.Visible = false; m_iridescenceMaskPort.Visible = false; m_indexOfRefractionPort.Visible = false; m_transmittanceColorPort.Visible = false; m_transmittanceAbsorptionDistancePort.Visible = false; m_transmittanceMaskPort.Visible = false; } break; case HDSRPMaterialType.Specular: { m_specularPort.Visible = true; m_metallicPort.Visible = false; m_coatMaskPort.Visible = true; m_diffusionProfilePort.Visible = false; m_subsurfaceMaskPort.Visible = false; m_thicknessPort.Visible = false; m_anisotropyPort.Visible = false; m_iridescenceThicknessPort.Visible = false; m_iridescenceMaskPort.Visible = false; m_indexOfRefractionPort.Visible = false; m_transmittanceColorPort.Visible = false; m_transmittanceAbsorptionDistancePort.Visible = false; m_transmittanceMaskPort.Visible = false; } break; case HDSRPMaterialType.Anisotropy: { m_specularPort.Visible = false; m_metallicPort.Visible = true; m_coatMaskPort.Visible = true; m_diffusionProfilePort.Visible = false; m_subsurfaceMaskPort.Visible = false; m_thicknessPort.Visible = false; m_anisotropyPort.Visible = true; m_iridescenceThicknessPort.Visible = false; m_iridescenceMaskPort.Visible = false; m_indexOfRefractionPort.Visible = false; m_transmittanceColorPort.Visible = false; m_transmittanceAbsorptionDistancePort.Visible = false; m_transmittanceMaskPort.Visible = false; } break; case HDSRPMaterialType.Iridescence: { m_specularPort.Visible = false; m_metallicPort.Visible = true; m_coatMaskPort.Visible = true; m_diffusionProfilePort.Visible = false; m_subsurfaceMaskPort.Visible = false; m_thicknessPort.Visible = false; m_anisotropyPort.Visible = false; m_iridescenceThicknessPort.Visible = true; m_iridescenceMaskPort.Visible = true; m_indexOfRefractionPort.Visible = false; m_transmittanceColorPort.Visible = false; m_transmittanceAbsorptionDistancePort.Visible = false; m_transmittanceMaskPort.Visible = false; } break; case HDSRPMaterialType.Translucent: { m_specularPort.Visible = false; m_metallicPort.Visible = false; m_coatMaskPort.Visible = false; m_diffusionProfilePort.Visible = true; m_subsurfaceMaskPort.Visible = false; m_thicknessPort.Visible = true; m_anisotropyPort.Visible = false; m_iridescenceThicknessPort.Visible = false; m_iridescenceMaskPort.Visible = false; m_indexOfRefractionPort.Visible = false; m_transmittanceColorPort.Visible = false; m_transmittanceAbsorptionDistancePort.Visible = false; m_transmittanceMaskPort.Visible = false; } break; } } m_sizeIsDirty = !m_isInvisible; } void DrawCommonProperties() { if( m_isMainOutputNode ) { DrawShaderName(); DrawCurrentShaderType(); #if SHOW_HD_SRP if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.SRPIsPBRHD ) { EditorGUI.BeginChangeCheck(); CurrentHDMaterialType = (HDSRPMaterialType)EditorGUILayoutEnumPopup( HDSRPMaterialTypeStr, m_hdSrpMaterialType ); if( EditorGUI.EndChangeCheck() ) ConfigHDPorts(); } #endif EditorGUI.BeginChangeCheck(); DrawPrecisionProperty(); if( EditorGUI.EndChangeCheck() ) ContainerGraph.CurrentPrecision = m_currentPrecisionType; m_fallbackHelper.Draw( this ); DrawCustomInspector(); m_dependenciesHelper.Draw( this, true ); } EditorGUILayout.LabelField( m_subShaderIdxStr ); EditorGUILayout.LabelField( m_passIdxStr ); DrawOpenTemplateButton(); if( DebugConsoleWindow.DeveloperMode ) DrawReloadButton(); } public void DrawSubShaderProperties() { if( !m_isMainOutputNode ) { if( m_mainMasterNodeRef == null ) { m_mainMasterNodeRef = m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode; } m_mainMasterNodeRef.DrawSubShaderProperties(); return; } bool noValidData = true; if( m_subShaderLOD > -1 ) { noValidData = false; EditorGUILayout.LabelField( m_subShaderLODStr ); } if( m_subShaderModule.HasValidData ) { noValidData = false; m_subShaderModule.Draw( this, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules ); //if( m_subShaderModule.IsDirty ) //{ // List mpNodes = UIUtils.CurrentWindow.CurrentGraph.MultiPassMasterNodes.NodesList; // int count = mpNodes.Count; // for( int i = 0; i < count; i++ ) // { // if( mpNodes[ i ].SubShaderIdx == m_subShaderIdx && mpNodes[ i ].UniqueId != UniqueId ) // { // mpNodes[ i ].SubShaderModule.CopyFrom( m_subShaderModule ); // } // } // m_subShaderModule.IsDirty = false; //} } if( noValidData ) { EditorGUILayout.HelpBox( NoSubShaderPropertyStr, MessageType.Info ); } } void DrawPassProperties() { EditorGUI.BeginChangeCheck(); m_passName = EditorGUILayoutTextField( PassNameStr, m_passName ); if( EditorGUI.EndChangeCheck() ) { if( m_passName.Length > 0 ) { m_passName = UIUtils.RemoveShaderInvalidCharacters( m_passName ); } else { m_passName = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data; } if( !m_templateMultiPass.IsSinglePass ) SetClippedTitle( m_passName ); } if( m_passModule.HasValidData ) { m_passModule.Draw( this, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules, m_subShaderModule ); } m_usePass.Draw( this, false ); #if CUSTOM_OPTIONS_AVAILABLE if( m_passCustomOptionsSizeCheck > 0 ) { NodeUtils.DrawNestedPropertyGroup( ref m_passCustomOptionsFoldout, m_passCustomOptionsLabel, DrawCustomOptions ); } #endif } bool CreateInstructionsForList( TemplateData templateData, ref List ports, ref string shaderBody, ref List vertexInstructions, ref List fragmentInstructions ) { if( ports.Count == 0 ) return true; AddHDKeywords(); bool isValid = true; //UIUtils.CurrentWindow.CurrentGraph.ResetNodesLocalVariables(); for( int i = 0; i < ports.Count; i++ ) { TemplateInputData inputData = templateData.InputDataFromId( ports[ i ].PortId ); if( ports[ i ].HasOwnOrLinkConnection ) { if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType == TemplateSRPType.Lightweight ) { if( ports[ i ].Name.Contains( "Normal" ) ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialNormalMapKeyword ); } if( ports[ i ].Name.Contains( "Alpha Clip Threshold" ) ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialBlendModeAlphaClipThresholdKeyword ); } if( ports[ i ].Name.Contains( "Specular" ) ) { m_currentDataCollector.AddToDefines( UniqueId, SRPLWMaterialSpecularKeyword ); } } else if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType == TemplateSRPType.HD ) { if( ports[ i ].Name.Contains( "Normal" ) ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialNormalMapKeyword ); } if( ports[ i ].Name.Contains( "Alpha Clip Threshold" ) ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialAlphaTestKeyword ); } } m_currentDataCollector.ResetInstructions(); m_currentDataCollector.ResetVertexInstructions(); m_currentDataCollector.PortCategory = ports[ i ].Category; string newPortInstruction = ports[ i ].GeneratePortInstructions( ref m_currentDataCollector ); if( m_currentDataCollector.DirtySpecialLocalVariables ) { string cleanVariables = m_currentDataCollector.SpecialLocalVariables.Replace( "\t", string.Empty ); m_currentDataCollector.AddInstructions( cleanVariables, false ); m_currentDataCollector.ClearSpecialLocalVariables(); } if( m_currentDataCollector.DirtyVertexVariables ) { string cleanVariables = m_currentDataCollector.VertexLocalVariables.Replace( "\t", string.Empty ); m_currentDataCollector.AddVertexInstruction( cleanVariables, UniqueId, false ); m_currentDataCollector.ClearVertexLocalVariables(); } // fill functions for( int j = 0; j < m_currentDataCollector.InstructionsList.Count; j++ ) { fragmentInstructions.Add( m_currentDataCollector.InstructionsList[ j ].PropertyName ); } for( int j = 0; j < m_currentDataCollector.VertexDataList.Count; j++ ) { vertexInstructions.Add( m_currentDataCollector.VertexDataList[ j ].PropertyName ); } m_templateMultiPass.SetPassInputData( m_subShaderIdx, m_passIdx, ports[ i ].PortId, newPortInstruction ); isValid = m_templateMultiPass.FillTemplateBody( m_subShaderIdx, m_passIdx, inputData.TagId, ref shaderBody, newPortInstruction ) && isValid; } else { m_templateMultiPass.SetPassInputData( m_subShaderIdx, m_passIdx, ports[ i ].PortId, inputData.DefaultValue ); isValid = m_templateMultiPass.FillTemplateBody( m_subShaderIdx, m_passIdx, inputData.TagId, ref shaderBody, inputData.DefaultValue ) && isValid; } } return isValid; } public string BuildShaderBody() { List list = UIUtils.CurrentWindow.CurrentGraph.MultiPassMasterNodes.NodesList; int currentSubshader = list[ 0 ].SubShaderIdx; m_templateMultiPass.SetShaderName( string.Format( TemplatesManager.NameFormatter, m_shaderName ) ); if( string.IsNullOrEmpty( m_customInspectorName ) ) { m_templateMultiPass.SetCustomInspector( string.Empty ); } else { m_templateMultiPass.SetCustomInspector( CustomInspectorFormatted ); } m_templateMultiPass.SetFallback( m_fallbackHelper.FallbackShader ); m_templateMultiPass.SetDependencies( m_dependenciesHelper.GenerateDependencies() ); MasterNodeDataCollector dataCollector = new MasterNodeDataCollector(); int count = list.Count; for( int i = 0; i < count; i++ ) { list[ i ].CollectData(); list[ i ].FillPassData( this ); if( list[ i ].SubShaderIdx == currentSubshader ) { dataCollector.CopyPropertiesFromDataCollector( list[ i ].CurrentDataCollector ); } else { list[ i - 1 ].FillPropertyData( dataCollector ); list[ i - 1 ].FillSubShaderData(); dataCollector.Destroy(); dataCollector = new MasterNodeDataCollector(); dataCollector.CopyPropertiesFromDataCollector( list[ i ].CurrentDataCollector ); currentSubshader = list[ i ].SubShaderIdx; } // Last element must the one filling subshader data // as only there all properties are caught if( i == ( count - 1 ) ) { list[ i ].FillPropertyData( dataCollector ); } if( list[ i ].IsMainOutputNode ) list[ i ].FillSubShaderData(); } return list[ 0 ].CurrentTemplate.IdManager.BuildShader(); } public override Shader Execute( string pathname, bool isFullPath ) { m_templateMultiPass.ResetState(); ForceReordering(); base.Execute( pathname, isFullPath ); string shaderBody = BuildShaderBody(); UpdateShaderAsset( ref pathname, ref shaderBody, isFullPath ); return m_currentShader; } public void CollectData() { if( m_inputPorts.Count == 0 ) return; ContainerGraph.ResetNodesLocalVariables(); m_currentDataCollector = new MasterNodeDataCollector( this ); m_currentDataCollector.TemplateDataCollectorInstance.SetMultipassInfo( m_templateMultiPass, m_subShaderIdx, m_passIdx, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.SRPType ); m_currentDataCollector.TemplateDataCollectorInstance.FillSpecialVariables( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ] ); SetupNodeCategories(); if( m_containerGraph.IsInstancedShader ) m_currentDataCollector.SetupInstancePropertiesBlock( UIUtils.RemoveInvalidCharacters( m_shaderName ) ); TemplateData templateData = m_templateMultiPass.CreateTemplateData( m_shaderName, string.Empty, m_subShaderIdx, m_passIdx ); m_currentDataCollector.TemplateDataCollectorInstance.BuildFromTemplateData( m_currentDataCollector, templateData ); if( m_currentDataCollector.TemplateDataCollectorInstance.InterpData.DynamicMax ) { int interpolatorAmount = -1; if( m_passModule.ShaderModelHelper.ValidData ) { interpolatorAmount = m_passModule.ShaderModelHelper.InterpolatorAmount; } else { TemplateModulesHelper subShaderModule = IsMainOutputNode ? m_subShaderModule : ( m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode ).SubShaderModule; if( subShaderModule.ShaderModelHelper.ValidData ) { interpolatorAmount = subShaderModule.ShaderModelHelper.InterpolatorAmount; } } if( interpolatorAmount > -1 ) { m_currentDataCollector.TemplateDataCollectorInstance.InterpData.RecalculateAvailableInterpolators( interpolatorAmount ); } } //Copy Properties { int shaderPropertiesAmount = m_templateMultiPass.AvailableShaderProperties.Count; for( int i = 0; i < shaderPropertiesAmount; i++ ) { m_currentDataCollector.SoftRegisterUniform( m_templateMultiPass.AvailableShaderProperties[ i ] ); } } //Copy Globals from SubShader level { int subShaderGlobalAmount = m_templateMultiPass.SubShaders[ m_subShaderIdx ].AvailableShaderGlobals.Count; for( int i = 0; i < subShaderGlobalAmount; i++ ) { m_currentDataCollector.SoftRegisterUniform( m_templateMultiPass.SubShaders[ m_subShaderIdx ].AvailableShaderGlobals[ i ] ); } } //Copy Globals from Pass Level { int passGlobalAmount = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].AvailableShaderGlobals.Count; for( int i = 0; i < passGlobalAmount; i++ ) { m_currentDataCollector.SoftRegisterUniform( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].AvailableShaderGlobals[ i ] ); } } RegisterStandaloneFuntions(); m_containerGraph.CheckPropertiesAutoRegister( ref m_currentDataCollector ); //Sort ports by both List fragmentPorts = new List(); List vertexPorts = new List(); SortInputPorts( ref vertexPorts, ref fragmentPorts ); string shaderBody = templateData.TemplateBody; List vertexInstructions = new List(); List fragmentInstructions = new List(); bool validBody = true; //validBody = CreateInstructionsForList( templateData, ref fragmentPorts, ref shaderBody, ref vertexInstructions, ref fragmentInstructions ) && validBody; //ContainerGraph.ResetNodesLocalVariablesIfNot( MasterNodePortCategory.Vertex ); //validBody = CreateInstructionsForList( templateData, ref vertexPorts, ref shaderBody, ref vertexInstructions, ref fragmentInstructions ) && validBody; validBody = CreateInstructionsForList( templateData, ref vertexPorts, ref shaderBody, ref vertexInstructions, ref fragmentInstructions ) && validBody; validBody = CreateInstructionsForList( templateData, ref fragmentPorts, ref shaderBody, ref vertexInstructions, ref fragmentInstructions ) && validBody; templateData.ResetTemplateUsageData(); // Fill vertex interpolators assignment for( int i = 0; i < m_currentDataCollector.VertexInterpDeclList.Count; i++ ) { vertexInstructions.Add( m_currentDataCollector.VertexInterpDeclList[ i ] ); } vertexInstructions.AddRange( m_currentDataCollector.TemplateDataCollectorInstance.GetInterpUnusedChannels() ); //Fill common local variables and operations validBody = m_templateMultiPass.FillVertexInstructions( m_subShaderIdx, m_passIdx, vertexInstructions.ToArray() ) && validBody; validBody = m_templateMultiPass.FillFragmentInstructions( m_subShaderIdx, m_passIdx, fragmentInstructions.ToArray() ) && validBody; vertexInstructions.Clear(); vertexInstructions = null; fragmentInstructions.Clear(); fragmentInstructions = null; // Add Instanced Properties if( m_containerGraph.IsInstancedShader ) { m_currentDataCollector.OptimizeInstancedProperties(); m_currentDataCollector.TabifyInstancedVars(); string cbufferBegin = string.Format( ( m_currentDataCollector.IsSRP ? IOUtils.LWSRPInstancedPropertiesBegin : IOUtils.InstancedPropertiesBegin ), m_currentDataCollector.InstanceBlockName ); string cBufferEnd = m_currentDataCollector.IsSRP ? ( string.Format( IOUtils.LWSRPInstancedPropertiesEnd, m_currentDataCollector.InstanceBlockName ) ) : IOUtils.InstancedPropertiesEnd; m_currentDataCollector.InstancedPropertiesList.Insert( 0, new PropertyDataCollector( -1, cbufferBegin ) ); m_currentDataCollector.InstancedPropertiesList.Add( new PropertyDataCollector( -1, cBufferEnd ) ); m_currentDataCollector.UniformsList.AddRange( m_currentDataCollector.InstancedPropertiesList ); } } public void FillPropertyData( MasterNodeDataCollector dataCollector = null ) { MasterNodeDataCollector currDataCollector = ( dataCollector == null ) ? m_currentDataCollector : dataCollector; m_templateMultiPass.SetPropertyData( currDataCollector.BuildUnformatedPropertiesStringArr() ); } public void FillSubShaderData( /*MasterNodeDataCollector dataCollector = null */) { //MasterNodeDataCollector currDataCollector = ( dataCollector == null ) ? m_currentDataCollector : dataCollector; //// SubShader Data //m_templateMultiPass.SetPropertyData( currDataCollector.BuildUnformatedPropertiesStringArr() ); //templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModulePass, m_subShaderIdx, currDataCollector.GrabPassList ); SetModuleData( m_subShaderModule, true ); } public void FillPassData( TemplateMultiPassMasterNode masterNode ) { if( m_isInvisible ) { if( masterNode.UniqueId != UniqueId ) { if( ( m_invisibleOptions & (int)InvisibleOptionsEnum.SyncProperties ) > 0 ) { PassModule.SyncWith( masterNode.PassModule ); } } int inputCount = m_inputPorts.Count; for( int i = 0; i < inputCount; i++ ) { if( m_inputPorts[ i ].HasExternalLink ) { TemplateMultiPassMasterNode linkedNode = m_inputPorts[ i ].ExternalLinkNode as TemplateMultiPassMasterNode; if( linkedNode != null ) { SetLinkedModuleData( linkedNode.PassModule ); } } } } SetModuleData( m_passModule, false ); if( m_currentDataCollector != null ) { if( Pass.CustomOptionsContainer.CopyOptionsFromMainPass ) { SetCustomOptionsInfo( m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode ); } else SetCustomOptionsInfo( this ); m_templateMultiPass.SetPassData( TemplateModuleDataType.PassVertexData, m_subShaderIdx, m_passIdx, m_currentDataCollector.VertexInputList.ToArray() ); m_templateMultiPass.SetPassData( TemplateModuleDataType.PassInterpolatorData, m_subShaderIdx, m_passIdx, m_currentDataCollector.InterpolatorList.ToArray() ); SetHDInfoOnPass(); List includePragmaDefineList = new List(); includePragmaDefineList.AddRange( m_currentDataCollector.IncludesList ); includePragmaDefineList.AddRange( m_currentDataCollector.DefinesList ); includePragmaDefineList.AddRange( m_currentDataCollector.PragmasList ); includePragmaDefineList.AddRange( m_currentDataCollector.MiscList ); m_templateMultiPass.SetPassData( TemplateModuleDataType.ModulePragma, m_subShaderIdx, m_passIdx, includePragmaDefineList ); m_currentDataCollector.TemplateDataCollectorInstance.CloseLateDirectives(); //Add Functions if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.FunctionsTag.IsValid ) { m_currentDataCollector.FunctionsList.InsertRange( 0, m_currentDataCollector.TemplateDataCollectorInstance.LateDirectivesList ); m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleFunctions, m_subShaderIdx, m_passIdx, m_currentDataCollector.FunctionsList ); } else { m_currentDataCollector.UniformsList.InsertRange(0, m_currentDataCollector.TemplateDataCollectorInstance.LateDirectivesList ); m_currentDataCollector.UniformsList.AddRange( m_currentDataCollector.FunctionsList ); } m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleGlobals, m_subShaderIdx, m_passIdx, m_currentDataCollector.UniformsList ); m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleInputVert, m_subShaderIdx, m_passIdx, m_currentDataCollector.TemplateDataCollectorInstance.VertexInputParamsStr ); m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleInputFrag, m_subShaderIdx, m_passIdx, m_currentDataCollector.TemplateDataCollectorInstance.FragInputParamsStr ); } m_templateMultiPass.SetPassData( TemplateModuleDataType.PassNameData, m_subShaderIdx, m_passIdx, string.Format( PassNameFormateStr, m_passName ) ); } void SetHDInfoOnPass() { if( m_currentDataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD ) { TemplateModulesHelper subShaderHelper = null; TemplateModulesHelper passHelper = null; if( m_isMainOutputNode ) { subShaderHelper = m_subShaderModule; passHelper = m_passModule; } else { TemplateMultiPassMasterNode masterNode = m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode; if( masterNode != null ) { subShaderHelper = masterNode.SubShaderModule; passHelper = masterNode.PassModule; } else { subShaderHelper = m_subShaderModule; passHelper = m_passModule; } } RenderQueue renderQueue = RenderQueue.Geometry; RenderType renderType = RenderType.Opaque; if( passHelper.TagsHelper.HasRenderInfo( ref renderType, ref renderQueue ) || subShaderHelper.TagsHelper.HasRenderInfo( ref renderType, ref renderQueue ) ) { if( renderType == RenderType.Transparent && renderQueue == RenderQueue.Transparent ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransparentKeyword ); TemplatesBlendModule blendOpHelper = passHelper.BlendOpHelper.ValidBlendMode ? passHelper.BlendOpHelper : subShaderHelper.BlendOpHelper; if( blendOpHelper.IsAdditiveRGB ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialBlendModeAddKeyword ); } else if( blendOpHelper.IsAlphaBlendRGB ) { m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialBlendModeAlphaKeyword ); } } } } } void SetLinkedModuleData( TemplateModulesHelper linkedModule ) { //if( linkedModule.AdditionalPragmas.ValidData ) //{ // linkedModule.AdditionalPragmas.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer ); //} //if( linkedModule.AdditionalIncludes.ValidData ) //{ // linkedModule.AdditionalIncludes.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer ); //} //if( linkedModule.AdditionalDefines.ValidData ) //{ // linkedModule.AdditionalDefines.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer ); //} if( linkedModule.AdditionalDirectives.ValidData ) { linkedModule.AdditionalDirectives.AddAllToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer ); } } void SetModuleData( TemplateModulesHelper module, bool isSubShader ) { if( isSubShader ) { //if ( module.AdditionalPragmas.ValidData ) //{ // module.AdditionalPragmas.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.IncludePragmaContainer ); //} //if ( module.AdditionalIncludes.ValidData ) //{ // module.AdditionalIncludes.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.IncludePragmaContainer ); //} //if ( module.AdditionalDefines.ValidData ) //{ // module.AdditionalDefines.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.IncludePragmaContainer ); //} if( module.AdditionalDirectives.ValidData ) { module.AdditionalDirectives.AddAllToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules.IncludePragmaContainer ); } if( module.TagsHelper.ValidData ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleTag, m_subShaderIdx, module.TagsHelper.GenerateTags() ); } if( module.AllModulesMode ) { string body = module.GenerateAllModulesString( isSubShader ); m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.AllModules, m_subShaderIdx, body.Split( '\n' ) ); } if( module.ShaderModelHelper.ValidAndIndependent ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleShaderModel, m_subShaderIdx, module.ShaderModelHelper.GenerateShaderData( isSubShader ) ); } if( module.BlendOpHelper.IndependentModule && module.BlendOpHelper.ValidBlendMode ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleBlendMode, m_subShaderIdx, module.BlendOpHelper.CurrentBlendFactor ); } if( module.BlendOpHelper.IndependentModule && module.BlendOpHelper.ValidBlendOp ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleBlendOp, m_subShaderIdx, module.BlendOpHelper.CurrentBlendOp ); } if( module.BlendOpHelper.AlphaToMaskIndependent && module.BlendOpHelper.ValidAlphaToMask ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleAlphaToMask, m_subShaderIdx, module.BlendOpHelper.CurrentAlphaToMask ); } if( module.CullModeHelper.ValidAndIndependent ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleCullMode, m_subShaderIdx, module.CullModeHelper.GenerateShaderData( isSubShader ) ); } if( module.ColorMaskHelper.ValidAndIndependent ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleColorMask, m_subShaderIdx, module.ColorMaskHelper.GenerateShaderData( isSubShader ) ); } if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidZTest ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleZTest, m_subShaderIdx, module.DepthOphelper.CurrentZTestMode ); } if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidZWrite ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleZwrite, m_subShaderIdx, module.DepthOphelper.CurrentZWriteMode ); } if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidOffset ) { m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleZOffset, m_subShaderIdx, module.DepthOphelper.CurrentOffset ); } if( module.StencilBufferHelper.ValidAndIndependent ) { CullMode cullMode = ( module.CullModeHelper.ValidData ) ? module.CullModeHelper.CurrentCullMode : CullMode.Back; string value = module.StencilBufferHelper.CreateStencilOp( cullMode ); m_templateMultiPass.SetSubShaderData( TemplateModuleDataType.ModuleStencil, m_subShaderIdx, value.Split( '\n' ) ); } } else { //if ( module.AdditionalPragmas.ValidData ) //{ // module.AdditionalPragmas.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer ); //} //if ( module.AdditionalIncludes.ValidData ) //{ // module.AdditionalIncludes.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer ); //} //if ( module.AdditionalDefines.ValidData ) //{ // module.AdditionalDefines.AddToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer ); //} List aboveUsePass = new List(); List bellowUsePass = new List(); m_usePass.BuildUsePassInfo( ref aboveUsePass, ref bellowUsePass ); //adding grab pass after use pass on purpose, so it wont be caught by them aboveUsePass.AddRange( m_currentDataCollector.GrabPassList ); m_templateMultiPass.SetPassData( TemplateModuleDataType.ModulePass, m_subShaderIdx, m_passIdx, aboveUsePass ); //m_templateMultiPass.SetPassData( TemplateModuleDataType.EndPass, m_subShaderIdx, m_passIdx, bellowUsePass); if( module.AdditionalDirectives.ValidData ) { module.AdditionalDirectives.AddAllToDataCollector( ref m_currentDataCollector, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.IncludePragmaContainer ); } if( module.TagsHelper.ValidData ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleTag, m_subShaderIdx, m_passIdx, module.TagsHelper.GenerateTags() ); } if( module.AllModulesMode ) { string body = module.GenerateAllModulesString( isSubShader ); m_templateMultiPass.SetPassData( TemplateModuleDataType.AllModules, m_subShaderIdx, m_passIdx, body.Split( '\n' ) ); } if( module.ShaderModelHelper.ValidAndIndependent ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleShaderModel, m_subShaderIdx, m_passIdx, module.ShaderModelHelper.GenerateShaderData( isSubShader ) ); } if( module.BlendOpHelper.IndependentModule && module.BlendOpHelper.ValidBlendMode ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleBlendMode, m_subShaderIdx, m_passIdx, module.BlendOpHelper.CurrentBlendFactor ); } if( module.BlendOpHelper.IndependentModule && module.BlendOpHelper.ValidBlendOp ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleBlendOp, m_subShaderIdx, m_passIdx, module.BlendOpHelper.CurrentBlendOp ); } if( module.BlendOpHelper.AlphaToMaskIndependent && module.BlendOpHelper.ValidAlphaToMask ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleAlphaToMask, m_subShaderIdx, m_passIdx, module.BlendOpHelper.CurrentAlphaToMask ); } if( module.CullModeHelper.ValidAndIndependent ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleCullMode, m_subShaderIdx, m_passIdx, module.CullModeHelper.GenerateShaderData( isSubShader ) ); } if( module.ColorMaskHelper.ValidAndIndependent ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleColorMask, m_subShaderIdx, m_passIdx, module.ColorMaskHelper.GenerateShaderData( isSubShader ) ); } if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidZTest ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleZTest, m_subShaderIdx, m_passIdx, module.DepthOphelper.CurrentZTestMode ); } if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidZWrite ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleZwrite, m_subShaderIdx, m_passIdx, module.DepthOphelper.CurrentZWriteMode ); } if( module.DepthOphelper.IndependentModule && module.DepthOphelper.ValidOffset ) { m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleZOffset, m_subShaderIdx, m_passIdx, module.DepthOphelper.CurrentOffset ); } if( module.StencilBufferHelper.ValidAndIndependent ) { CullMode cullMode = ( module.CullModeHelper.ValidData ) ? module.CullModeHelper.CurrentCullMode : CullMode.Back; string value = module.StencilBufferHelper.CreateStencilOp( cullMode ); m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleStencil, m_subShaderIdx, m_passIdx, value.Split( '\n' ) ); } } } public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) { return "0"; } public override void Destroy() { base.Destroy(); #if CUSTOM_OPTIONS_AVAILABLE for( int i = 0; i < m_passCustomOptionsUI.Count; i++ ) { m_passCustomOptionsUI[ i ].Destroy(); } m_passCustomOptionsUI.Clear(); m_passCustomOptionsUI = null; m_passCustomOptionsUIDict.Clear(); m_passCustomOptionsUIDict = null; m_passCustomOptionsPorts.Clear(); m_passCustomOptionsPorts = null; #endif m_fallbackHelper.Destroy(); GameObject.DestroyImmediate( m_fallbackHelper ); m_fallbackHelper = null; m_usePass.Destroy(); GameObject.DestroyImmediate( m_usePass ); m_usePass = null; m_dependenciesHelper.Destroy(); m_dependenciesHelper = null; m_subShaderModule.Destroy(); m_subShaderModule = null; m_passModule.Destroy(); m_passModule = null; m_containerGraph.MultiPassMasterNodes.RemoveNode( this ); } void UpdateSubShaderPassStr() { m_subShaderIdxStr = SubShaderModuleStr + m_templateMultiPass.SubShaders[ m_subShaderIdx ].Idx; m_passIdxStr = PassModuleStr + m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Idx; } public override void ReadFromString( ref string[] nodeParams ) { base.ReadFromString( ref nodeParams ); try { string currShaderName = GetCurrentParam( ref nodeParams ); if( currShaderName.Length > 0 ) currShaderName = UIUtils.RemoveShaderInvalidCharacters( currShaderName ); m_templateGUID = GetCurrentParam( ref nodeParams ); m_subShaderIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); m_passIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); m_passName = GetCurrentParam( ref nodeParams ); SetTemplate( null, false, true, m_subShaderIdx, m_passIdx ); // only in here, after SetTemplate, we know if shader name is to be used as title or not ShaderName = currShaderName; m_visiblePorts = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); m_subShaderModule.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); m_passModule.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); if( UIUtils.CurrentShaderVersion() > 15308 ) { m_fallbackHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); m_dependenciesHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } if( UIUtils.CurrentShaderVersion() > 15402 ) { m_usePass.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } if( UIUtils.CurrentShaderVersion() > 15409 ) { m_hdSrpMaterialType = (HDSRPMaterialType)Enum.Parse( typeof( HDSRPMaterialType ), GetCurrentParam( ref nodeParams ) ); } if( UIUtils.CurrentShaderVersion() > 15501 ) { RefreshCustomOptionsDict(); int savedOptions = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); for( int i = 0; i < savedOptions; i++ ) { string optionName = GetCurrentParam( ref nodeParams ); int optionSelection = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); if( m_passCustomOptionsUIDict.ContainsKey( optionName ) ) { m_passCustomOptionsUIDict[ optionName ].CurrentOption = optionSelection; } } } if( m_templateMultiPass != null && !m_templateMultiPass.IsSinglePass ) { SetClippedTitle( m_passName ); } } catch( Exception e ) { Debug.LogException( e, this ); } m_containerGraph.CurrentCanvasMode = NodeAvailability.TemplateShader; } public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) { base.WriteToString( ref nodeInfo, ref connectionsInfo ); IOUtils.AddFieldValueToString( ref nodeInfo, ShaderName ); IOUtils.AddFieldValueToString( ref nodeInfo, m_templateGUID ); IOUtils.AddFieldValueToString( ref nodeInfo, m_subShaderIdx ); IOUtils.AddFieldValueToString( ref nodeInfo, m_passIdx ); IOUtils.AddFieldValueToString( ref nodeInfo, m_passName ); IOUtils.AddFieldValueToString( ref nodeInfo, m_visiblePorts ); m_subShaderModule.WriteToString( ref nodeInfo ); m_passModule.WriteToString( ref nodeInfo ); m_fallbackHelper.WriteToString( ref nodeInfo ); m_dependenciesHelper.WriteToString( ref nodeInfo ); m_usePass.WriteToString( ref nodeInfo ); IOUtils.AddFieldValueToString( ref nodeInfo, m_hdSrpMaterialType ); int optionsCount = m_passCustomOptionsUI.Count; IOUtils.AddFieldValueToString( ref nodeInfo, optionsCount ); for( int i = 0; i < optionsCount; i++ ) { IOUtils.AddFieldValueToString( ref nodeInfo, m_passCustomOptionsUI[ i ].Options.Id ); IOUtils.AddFieldValueToString( ref nodeInfo, m_passCustomOptionsUI[ i ].CurrentOption ); } } public override void ReadFromDeprecated( ref string[] nodeParams, Type oldType = null ) { base.ReadFromString( ref nodeParams ); try { string currShaderName = GetCurrentParam( ref nodeParams ); if( currShaderName.Length > 0 ) currShaderName = UIUtils.RemoveShaderInvalidCharacters( currShaderName ); string templateGUID = GetCurrentParam( ref nodeParams ); string templateShaderName = string.Empty; if( UIUtils.CurrentShaderVersion() > 13601 ) { templateShaderName = GetCurrentParam( ref nodeParams ); } TemplateMultiPass template = m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( templateGUID ) as TemplateMultiPass; if( template != null ) { m_templateGUID = templateGUID; SetTemplate( null, false, true, 0, 0 ); } else { template = m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplateByName( templateShaderName ) as TemplateMultiPass; if( template != null ) { m_templateGUID = template.GUID; SetTemplate( null, false, true, 0, 0 ); } else { m_masterNodeCategory = -1; } } if( m_invalidNode ) return; // only in here, after SetTemplate, we know if shader name is to be used as title or not ShaderName = currShaderName; if( UIUtils.CurrentShaderVersion() > 13902 ) { //BLEND MODULE if( m_templateMultiPass.SubShaders[ 0 ].Modules.BlendData.ValidBlendMode ) { m_subShaderModule.BlendOpHelper.ReadBlendModeFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.BlendData.ValidBlendMode ) { m_passModule.BlendOpHelper.ReadBlendModeFromString( ref m_currentReadParamIdx, ref nodeParams ); } if( m_templateMultiPass.SubShaders[ 0 ].Modules.BlendData.ValidBlendOp ) { m_subShaderModule.BlendOpHelper.ReadBlendOpFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.BlendData.ValidBlendOp ) { m_passModule.BlendOpHelper.ReadBlendOpFromString( ref m_currentReadParamIdx, ref nodeParams ); } //CULL MODE if( m_templateMultiPass.SubShaders[ 0 ].Modules.CullModeData.DataCheck == TemplateDataCheck.Valid ) { m_subShaderModule.CullModeHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.CullModeData.DataCheck == TemplateDataCheck.Valid ) { m_passModule.CullModeHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } //COLOR MASK if( m_templateMultiPass.SubShaders[ 0 ].Modules.ColorMaskData.DataCheck == TemplateDataCheck.Valid ) { m_subShaderModule.ColorMaskHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.ColorMaskData.DataCheck == TemplateDataCheck.Valid ) { m_passModule.ColorMaskHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } //STENCIL BUFFER if( m_templateMultiPass.SubShaders[ 0 ].Modules.StencilData.DataCheck == TemplateDataCheck.Valid ) { m_subShaderModule.StencilBufferHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.StencilData.DataCheck == TemplateDataCheck.Valid ) { m_passModule.StencilBufferHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } } if( UIUtils.CurrentShaderVersion() > 14202 ) { //DEPTH OPTIONS if( m_templateMultiPass.SubShaders[ 0 ].Modules.DepthData.ValidZWrite ) { m_subShaderModule.DepthOphelper.ReadZWriteFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.DepthData.ValidZWrite ) { m_passModule.DepthOphelper.ReadZWriteFromString( ref m_currentReadParamIdx, ref nodeParams ); } if( m_templateMultiPass.SubShaders[ 0 ].Modules.DepthData.ValidZTest ) { m_subShaderModule.DepthOphelper.ReadZTestFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.DepthData.ValidZTest ) { m_subShaderModule.DepthOphelper.ReadZTestFromString( ref m_currentReadParamIdx, ref nodeParams ); } if( m_templateMultiPass.SubShaders[ 0 ].Modules.DepthData.ValidOffset ) { m_subShaderModule.DepthOphelper.ReadOffsetFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.DepthData.ValidOffset ) { m_passModule.DepthOphelper.ReadOffsetFromString( ref m_currentReadParamIdx, ref nodeParams ); } } //TAGS if( UIUtils.CurrentShaderVersion() > 14301 ) { if( m_templateMultiPass.SubShaders[ 0 ].Modules.TagData.DataCheck == TemplateDataCheck.Valid ) { m_subShaderModule.TagsHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } else if( m_templateMultiPass.SubShaders[ 0 ].Passes[ 0 ].Modules.TagData.DataCheck == TemplateDataCheck.Valid ) { m_passModule.TagsHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); } } } catch( Exception e ) { Debug.LogException( e, this ); } m_containerGraph.CurrentCanvasMode = NodeAvailability.TemplateShader; } public override void RefreshExternalReferences() { base.RefreshExternalReferences(); CheckTemplateChanges(); if( m_templateMultiPass != null && m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.SRPIsPBRHD && UIUtils.CurrentShaderVersion() < 15410 ) { FetchHDPorts(); m_hdSrpMaterialType = ( m_specularPort != null && m_specularPort.HasOwnOrLinkConnection ) ? HDSRPMaterialType.Specular : HDSRPMaterialType.Standard; ConfigHDPorts(); } } public override float HeightEstimate { get { float heightEstimate = 0; heightEstimate = 32 + Constants.INPUT_PORT_DELTA_Y; if( m_templateMultiPass != null && !m_templateMultiPass.IsSinglePass ) { heightEstimate += 22; } float internalPortSize = 0; for( int i = 0; i < InputPorts.Count; i++ ) { if( InputPorts[ i ].Visible ) internalPortSize += 18 + Constants.INPUT_PORT_DELTA_Y; } return heightEstimate + Mathf.Max( internalPortSize, m_insideSize.y ); } } public HDSRPMaterialType CurrentHDMaterialType { get { return m_hdSrpMaterialType; } set { m_hdSrpMaterialType = value; if( m_isMainOutputNode ) { List mpNodes = UIUtils.CurrentWindow.CurrentGraph.MultiPassMasterNodes.NodesList; int count = mpNodes.Count; for( int i = 0; i < count; i++ ) { if( mpNodes[ i ].UniqueId != UniqueId ) { mpNodes[ i ].CurrentHDMaterialType = value; } } } } } public TemplateSubShader SubShader { get { return m_templateMultiPass.SubShaders[ m_subShaderIdx ]; } } public TemplatePass Pass { get { return m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ]; } } public int SubShaderIdx { get { return m_subShaderIdx; } } public int PassIdx { get { return m_passIdx; } } public TemplateMultiPass CurrentTemplate { get { return m_templateMultiPass; } } public TemplateModulesHelper SubShaderModule { get { return m_subShaderModule; } } public TemplateModulesHelper PassModule { get { return m_passModule; } } public string PassName { get { return m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data; } } public string OriginalPassName { get { return m_originalPassName; } } public bool HasLinkPorts { get { return m_hasLinkPorts; } } public bool IsInvisible { get { return m_isInvisible; } } #if CUSTOM_OPTIONS_AVAILABLE public List PassCustomOptionsUI { get { return m_passCustomOptionsUI; } } public List PassCustomOptionsPorts { get { return m_passCustomOptionsPorts; } } #endif } }