diff options
author | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-10-23 13:08:43 +0800 |
commit | b82da95b5181ac8bbae38efb13e950d5e88a4caa (patch) | |
tree | 48a6f3269276484bbc7cfc95f0651f40a2176aa1 /Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Templates/TemplateMultiPassMasterNode.cs | |
parent | 917e9e0b320775634dc2e710f7deac74fd0822f0 (diff) |
*移动amplify shader editor到third party目录
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Templates/TemplateMultiPassMasterNode.cs')
-rw-r--r-- | Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Templates/TemplateMultiPassMasterNode.cs | 3113 |
1 files changed, 3113 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Templates/TemplateMultiPassMasterNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Templates/TemplateMultiPassMasterNode.cs new file mode 100644 index 00000000..92ce5c77 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Templates/TemplateMultiPassMasterNode.cs @@ -0,0 +1,3113 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +//#define SHOW_TEMPLATE_HELP_BOX + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + public enum HDSRPMaterialType + { + SubsurfaceScattering, + Standard, + Specular, + Anisotropy, + Iridescence, + Translucent + } + + public enum InvisibilityStatus + { + LockedInvisible, + Invisible, + Visible + } + + public enum SetTemplateSource + { + NewShader, + ShaderLoad, + HotCodeReload + }; + + [Serializable] + [NodeAttributes( "Template Master Node", "Master", "Shader Generated according to template rules", null, KeyCode.None, false )] + public sealed class TemplateMultiPassMasterNode : MasterNode + { + private const double MaxLODEditTimestamp = 1; + + private static int PASS_SELECTOR_VERSION = 16200; + private static int PASS_UNIQUE_ID_VERSION = 16204; + + private const string LodNameId = "LODName"; + private const string LodValueId = "LODValue"; + + private const string LodSubtitle = "LOD( {0} )"; + private const string AdditionalLODsStr = "LODs"; + + 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 const string SubShaderLODValueLabel = "LOD Value"; + private const string SubShaderLODNameLabel = "LOD Name"; + + + + 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 bool m_lodFoldout = false; + + + [SerializeField] + private string m_mainLODName = string.Empty; + + //[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_passUniqueId = string.Empty; + + [SerializeField] + private string m_originalPassName = string.Empty; + + [SerializeField] + private bool m_hasLinkPorts = false; + + [SerializeField] + private InvisibilityStatus m_isInvisible = InvisibilityStatus.Visible; + + [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(); + + [SerializeField] + private TemplateOptionsUIHelper m_subShaderOptions = new TemplateOptionsUIHelper( true ); + + [SerializeField] + private TemplateOptionsUIHelper m_passOptions = new TemplateOptionsUIHelper( false ); + + [SerializeField] + private TemplatePassSelectorHelper m_passSelector = new TemplatePassSelectorHelper(); + + [SerializeField] + private TemplateOptionsDefinesContainer m_optionsDefineContainer = new TemplateOptionsDefinesContainer(); + + [SerializeField] + private TerrainDrawInstancedHelper m_drawInstancedHelper = new TerrainDrawInstancedHelper(); + + // 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; + + [NonSerialized] + private bool m_refreshLODValueMasterNodes = false; + [NonSerialized] + private bool m_refocusLODValueMasterNodes = false; + [NonSerialized] + private double m_refreshLODValueMasterNodesTimestamp; + + ////////////////////////////////////////////////////////////////////////// + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + m_masterNodeCategory = 1;// First Template + m_marginPreviewLeft = 20; + m_shaderNameIsTitle = true; + m_customInspectorName = string.Empty; + m_customPrecision = true; + } + + public override void ReleaseResources() + { + // Internal template resources ( for inline properties) are released by first node on the list + // As it's also registered that way + if( IsLODMainFirstPass ) + m_containerGraph.ClearInternalTemplateNodes(); + + if( !IsLODMainMasterNode ) + return; + TemplateMultiPass template = ( m_templateMultiPass == null ) ? m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( m_templateGUID ) as TemplateMultiPass : m_templateMultiPass; + //Maintained the logic of being the main master node to unregister since this method is being called + //over the main master node in multiple places + //but it will unregister with unique of the first master node (pass 0) since it was the one + //to register it + int passUniqueId = ( m_passIdx == 0 ) ? UniqueId : ContainerGraph.MultiPassMasterNodes.NodesList[ 0 ].UniqueId; + + if( template != null && template.AvailableShaderProperties != null ) + { + // Unregister old template properties + int oldPropertyCount = template.AvailableShaderProperties.Count; + for( int i = 0; i < oldPropertyCount; i++ ) + { + UIUtils.ReleaseUniformName( passUniqueId, template.AvailableShaderProperties[ i ].PropertyName ); + } + } + } + + public void CopyOptionsFrom( TemplateMultiPassMasterNode origin ) + { + //Copy options + SubShaderOptions.CopyOptionsValuesFrom( origin.SubShaderOptions ); + PassOptions.CopyOptionsValuesFrom( origin.PassOptions ); + + //Copy selected passes + if( IsMainOutputNode ) + m_passSelector.CopyFrom( origin.PassSelector ); + } + + void RegisterProperties() + { + //First pass must be the one to always register properties so all modules + //can extract a valid negative Id when reading inline properties + if( /*!IsLODMainMasterNode*/!IsLODMainFirstPass ) + { + 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<UsePassHelper>(); + m_usePass.Init( " Additional Use Passes" ); + } + + if( m_fallbackHelper == null ) + { + m_fallbackHelper = ScriptableObject.CreateInstance<FallbackPickerHelper>(); + m_fallbackHelper.Init(); + } + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + if( UniqueId >= 0 ) + { + if( m_lodIndex == -1 ) + { + m_containerGraph.MultiPassMasterNodes.AddNode( this ); + } + else + { + m_containerGraph.LodMultiPassMasternodes[ m_lodIndex ].AddNode( this ); + } + } + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_passOptions.CheckImediateActionsForPort( this, portId ); + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + m_passOptions.CheckImediateActionsForPort( this, portId ); + } + + public void ForceTemplateRefresh() + { + SetTemplate( null, false, true, m_subShaderIdx, m_passIdx, SetTemplateSource.HotCodeReload ); + } + + public void SetTemplate( TemplateMultiPass template, bool writeDefaultData, bool fetchMasterNodeCategory, int subShaderIdx, int passIdx , SetTemplateSource source ) + { + if( subShaderIdx > -1 ) + m_subShaderIdx = subShaderIdx; + + if( passIdx > -1 ) + m_passIdx = passIdx; + + ReleaseResources(); + bool hotCodeOrRead = ( template == null ); + m_templateMultiPass = ( hotCodeOrRead ) ? m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( m_templateGUID ) as TemplateMultiPass : template; + if( m_templateMultiPass != null ) + { + + string passName = string.IsNullOrEmpty( m_passUniqueId ) ? ( m_isInvisible == InvisibilityStatus.LockedInvisible ? m_passName : m_originalPassName ) : m_passUniqueId; + int newPassIdx = m_passIdx; + int newSubShaderIdx = m_subShaderIdx; + m_templateMultiPass.GetSubShaderandPassFor( passName, ref newSubShaderIdx, ref newPassIdx ); + if( newPassIdx == -1 || newSubShaderIdx == -1 ) + { + //m_containerGraph.MarkToDelete( this ); + ContainerGraph.ParentWindow.SetOutdatedShaderFromTemplate(); + m_invalidNode = true; + UIUtils.ShowMessage( "Template changed drastically. Removing invalid passes." ); + return; + } + else + { + if( m_passIdx != newPassIdx ) + m_passIdx = newPassIdx; + + if( m_subShaderIdx != newSubShaderIdx ) + m_subShaderIdx = newSubShaderIdx; + } + + m_containerGraph.CurrentSRPType = m_templateMultiPass.SRPtype; + if( m_templateMultiPass.IsSinglePass ) + { + SetAdditonalTitleText( string.Empty ); + } + else if( m_templateMultiPass.SubShaders[ 0 ].MainPass != m_passIdx ) + { + 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; + if( source != SetTemplateSource.HotCodeReload ) + { + //Only set this if no hotcode reload happens ( via new shader or load ) + m_isInvisible = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].IsInvisible ? InvisibilityStatus.LockedInvisible : InvisibilityStatus.Visible; + } + else + { + // On hot code reload we only need to verify if template pass visibility data changes + // and change accordingly + if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].IsInvisible ) + { + if( m_isInvisible != InvisibilityStatus.LockedInvisible ) + m_isInvisible = InvisibilityStatus.LockedInvisible; + } + else + { + if( m_isInvisible == InvisibilityStatus.LockedInvisible ) + { + m_isInvisible = InvisibilityStatus.Visible; + } + } + } + + m_invisibleOptions = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].InvisibleOptions; + + m_originalPassName = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data; + + if( !hotCodeOrRead ) + { + if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Index > -1 ) + { + //m_subShaderLODStr = m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Id; + ShaderLOD = Convert.ToInt32( m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Data ); + } + else + { + ShaderLOD = 0; + } + } + + m_shaderNameIsTitle = IsMainOutputNode; + 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( !hotCodeOrRead ) + { + m_customInspectorName = m_templateMultiPass.CustomInspectorContainer.Data; + if( m_isMainOutputNode ) + { + m_passSelector.Clear(); + m_passSelector.Setup( m_templateMultiPass.SubShaders[ m_subShaderIdx ] ); + } + } + else + { + //Hotcode reload or ReadFromString + // Setup is only made if internal pass array is null + if( m_isMainOutputNode ) + { + m_passSelector.Setup( m_templateMultiPass.SubShaders[ m_subShaderIdx ] ); + } + } + + SetupCustomOptionsFromTemplate( template != null ); + + 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; + ShaderName = m_shaderName; + m_passName = m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].PassNameContainer.Data; + if( !m_templateMultiPass.IsSinglePass /*&& !m_shaderNameIsTitle*/ ) + { + if( m_templateMultiPass.SubShaders[ 0 ].MainPass != m_passIdx ) + 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(); + + SetReadOptions(); + } + + public void SetReadOptions() + { + m_passOptions.SetReadOptions(); + if( m_isMainOutputNode ) + m_subShaderOptions.SetReadOptions(); + } + + bool UpdatePortInfo() + { + List<TemplateInputData> 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; + } + } + + public void SetPropertyActionFromItem( TemplateModulesHelper module, TemplateActionItem item ) + { + TemplateModulesHelper subShaderModule = m_isMainOutputNode ? m_subShaderModule : m_mainMasterNodeRef.SubShaderModule; + switch( item.PropertyAction ) + { + case PropertyActionsEnum.CullMode: + { + if( item.CopyFromSubShader ) + { + module.CullModeHelper.CurrentCullMode = subShaderModule.CullModeHelper.CurrentCullMode; + } + else + { + module.CullModeHelper.CurrentCullMode = item.ActionCullMode; + } + + } + break; + case PropertyActionsEnum.ColorMask: + { + if( item.CopyFromSubShader ) + { + module.ColorMaskHelper.ColorMask = subShaderModule.ColorMaskHelper.ColorMask; + } + else + { + module.ColorMaskHelper.ColorMask = item.ColorMask; + } + } + break; + case PropertyActionsEnum.ZWrite: + { + if( item.CopyFromSubShader ) + { + module.DepthOphelper.ZWriteModeValue = subShaderModule.DepthOphelper.ZWriteModeValue; + } + else + { + module.DepthOphelper.ZWriteModeValue = item.ActionZWrite; + } + } + break; + case PropertyActionsEnum.ZTest: + { + if( item.CopyFromSubShader ) + { + module.DepthOphelper.ZTestModeValue = subShaderModule.DepthOphelper.ZTestModeValue; + } + else + { + module.DepthOphelper.ZTestModeValue = item.ActionZTest; + } + } + break; + case PropertyActionsEnum.ZOffsetFactor: + { + if( item.CopyFromSubShader ) + { + module.DepthOphelper.OffsetFactorValue = subShaderModule.DepthOphelper.OffsetFactorValue; + } + else + { + module.DepthOphelper.OffsetFactorValue = item.ActionZOffsetFactor; + } + } + break; + case PropertyActionsEnum.ZOffsetUnits: + { + if( item.CopyFromSubShader ) + { + module.DepthOphelper.OffsetUnitsValue = subShaderModule.DepthOphelper.OffsetUnitsValue; + } + else + { + module.DepthOphelper.OffsetUnitsValue = item.ActionZOffsetUnits; + } + } + break; + case PropertyActionsEnum.BlendRGB: + { + if( item.CopyFromSubShader ) + { + module.BlendOpHelper.SourceFactorRGB = subShaderModule.BlendOpHelper.SourceFactorRGB; + module.BlendOpHelper.DestFactorRGB = subShaderModule.BlendOpHelper.DestFactorRGB; + } + else + { + module.BlendOpHelper.SourceFactorRGB = item.ActionBlendRGBSource; + module.BlendOpHelper.DestFactorRGB = item.ActionBlendRGBDest; + } + } + break; + case PropertyActionsEnum.BlendAlpha: + { + if( item.CopyFromSubShader ) + { + module.BlendOpHelper.SourceFactorAlpha = subShaderModule.BlendOpHelper.SourceFactorAlpha; + module.BlendOpHelper.DestFactorAlpha = subShaderModule.BlendOpHelper.DestFactorAlpha; + } + else + { + module.BlendOpHelper.CurrentAlphaIndex = 1; + module.BlendOpHelper.SourceFactorAlpha = item.ActionBlendAlphaSource; + module.BlendOpHelper.DestFactorAlpha = item.ActionBlendAlphaDest; + } + } + break; + case PropertyActionsEnum.BlendOpRGB: + { + if( item.CopyFromSubShader ) + { + module.BlendOpHelper.BlendOpRGB = subShaderModule.BlendOpHelper.BlendOpRGB; + } + else + { + module.BlendOpHelper.BlendOpRGB = item.ActionBlendOpRGB; + } + } + break; + case PropertyActionsEnum.BlendOpAlpha: + { + if( item.CopyFromSubShader ) + { + module.BlendOpHelper.BlendOpAlpha = subShaderModule.BlendOpHelper.BlendOpAlpha; + } + else + { + module.BlendOpHelper.BlendOpAlpha = item.ActionBlendOpAlpha; + } + } + break; + case PropertyActionsEnum.StencilReference: + { + if( item.CopyFromSubShader ) + { + module.StencilBufferHelper.ReferenceValue = subShaderModule.StencilBufferHelper.ReferenceValue; + } + else + { + module.StencilBufferHelper.ReferenceValue = item.ActionStencilReference; + } + } + break; + case PropertyActionsEnum.StencilReadMask: + { + if( item.CopyFromSubShader ) + { + module.StencilBufferHelper.ReadMaskValue = subShaderModule.StencilBufferHelper.ReadMaskValue; + } + else + { + module.StencilBufferHelper.ReadMaskValue = item.ActionStencilReadMask; + } + } + break; + case PropertyActionsEnum.StencilWriteMask: + { + if( item.CopyFromSubShader ) + { + module.StencilBufferHelper.WriteMaskValue = subShaderModule.StencilBufferHelper.WriteMaskValue; + } + else + { + module.StencilBufferHelper.WriteMaskValue = item.ActionStencilWriteMask; + } + } + break; + case PropertyActionsEnum.StencilComparison: + { + if( item.CopyFromSubShader ) + { + module.StencilBufferHelper.ComparisonFunctionIdxValue = subShaderModule.StencilBufferHelper.ComparisonFunctionIdxValue; + } + else + { + module.StencilBufferHelper.ComparisonFunctionIdxValue = item.ActionStencilComparison; + } + } + break; + case PropertyActionsEnum.StencilPass: + { + if( item.CopyFromSubShader ) + { + module.StencilBufferHelper.PassStencilOpIdxValue = subShaderModule.StencilBufferHelper.PassStencilOpIdxValue; + } + else + { + module.StencilBufferHelper.PassStencilOpIdxValue = item.ActionStencilPass; + } + } + break; + case PropertyActionsEnum.StencilFail: + { + if( item.CopyFromSubShader ) + { + module.StencilBufferHelper.FailStencilOpIdxValue = subShaderModule.StencilBufferHelper.FailStencilOpIdxValue; + } + else + { + module.StencilBufferHelper.FailStencilOpIdxValue = item.ActionStencilFail; + } + } + break; + case PropertyActionsEnum.StencilZFail: + { + if( item.CopyFromSubShader ) + { + module.StencilBufferHelper.ZFailStencilOpIdxValue = subShaderModule.StencilBufferHelper.ZFailStencilOpIdxValue; + } + else + { + module.StencilBufferHelper.ZFailStencilOpIdxValue = item.ActionStencilZFail; + } + } + break; + case PropertyActionsEnum.RenderType: + { + module.TagsHelper.AddSpecialTag( TemplateSpecialTags.RenderType, item ); + } + break; + case PropertyActionsEnum.RenderQueue: + { + module.TagsHelper.AddSpecialTag( TemplateSpecialTags.Queue, item ); + } + break; + } + } + + public void OnCustomPassOptionSelected( bool isRefreshing, bool invertAction, TemplateOptionUIItem uiItem, params TemplateActionItem[] validActions ) + { + m_passOptions.OnCustomOptionSelected( isRefreshing, invertAction, this, uiItem, validActions ); + } + + public void OnCustomSubShaderOptionSelected( bool isRefreshing, bool invertAction, TemplateOptionUIItem uiItem, params TemplateActionItem[] validActions ) + { + if( m_isMainOutputNode ) + m_subShaderOptions.OnCustomOptionSelected( isRefreshing, invertAction, this, uiItem, validActions ); + } + + void SetupCustomOptionsFromTemplate( bool newTemplate ) + { + m_passOptions.SetupCustomOptionsFromTemplate( this, newTemplate ); + if( m_isMainOutputNode ) + m_subShaderOptions.SetupCustomOptionsFromTemplate( this, newTemplate ); + } + + void SetPassCustomOptionsInfo( TemplateMultiPassMasterNode masterNode ) + { + TemplateMultiPassMasterNode mainMasterNode = masterNode.IsMainOutputNode ? masterNode : ( m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode ); + mainMasterNode.SubShaderOptions.SetSubShaderCustomOptionsPortsInfo( masterNode, ref m_currentDataCollector ); + masterNode.PassOptions.SetCustomOptionsInfo( masterNode, ref m_currentDataCollector ); + } + + void RefreshCustomOptionsDict() + { + m_passOptions.RefreshCustomOptionsDict(); + if( m_isMainOutputNode ) + m_subShaderOptions.RefreshCustomOptionsDict(); + } + + 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; + } + } + + public void CheckTemplateChanges() + { + if( m_invalidNode ) + return; + + if( IsLODMainMasterNode ) + { + 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 ) + { + if( m_invalidNode ) + { + return; + } + base.OnNodeLogicUpdate( drawInfo ); + + if( m_templateMultiPass == null ) + { + // Hotcode reload has happened + SetTemplate( null, false, true, m_subShaderIdx, m_passIdx , SetTemplateSource.HotCodeReload ); + 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 ); + } + + if( !m_isMainOutputNode && m_mainMasterNodeRef == null ) + { + m_mainMasterNodeRef = m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode; + } + + if( m_refreshLODValueMasterNodes && ( EditorApplication.timeSinceStartup - m_refreshLODValueMasterNodesTimestamp ) > MaxLODEditTimestamp ) + { + m_refreshLODValueMasterNodes = false; + m_refocusLODValueMasterNodes = true; + m_containerGraph.SortLODMasterNodes(); + } + } + + public override void Draw( DrawInfo drawInfo ) + { + if( m_isInvisible == InvisibilityStatus.Visible ) + { + 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 != InvisibilityStatus.Visible ) + { + 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 == InvisibilityStatus.Visible ) + { + 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<Shader>( 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<Shader>( 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<TemplateMultiPassMasterNode> 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 + } + + // this will be removed later when PBR options are created + void SetExtraDefine( string define ) + { + List<TemplateMultiPassMasterNode> nodes = this.ContainerGraph.MultiPassMasterNodes.NodesList; + int count = nodes.Count; + for( int nodeIdx = 0; nodeIdx < count; nodeIdx++ ) + { + nodes[ nodeIdx ].OptionsDefineContainer.AddDefine( "#define " + define, false ); + } + } + + void AddHDKeywords() + { + if( m_templateMultiPass.CustomTemplatePropertyUI == CustomTemplatePropertyUIEnum.None ) + return; + + 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: + { + SetExtraDefine( SRPMaterialSubsurfaceScatteringKeyword ); + //m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialSubsurfaceScatteringKeyword ); + if( m_thicknessPort != null && m_thicknessPort.HasOwnOrLinkConnection ) + { + SetExtraDefine( SRPMaterialTransmissionKeyword ); + //m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransmissionKeyword ); + } + } + break; + case HDSRPMaterialType.Standard: + break; + case HDSRPMaterialType.Specular: + { + SetExtraDefine( SRPHDMaterialSpecularKeyword ); + //m_currentDataCollector.AddToDefines( UniqueId, SRPHDMaterialSpecularKeyword ); + } + break; + case HDSRPMaterialType.Anisotropy: + { + SetExtraDefine( SRPMaterialAnisotropyKeyword ); + //m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialAnisotropyKeyword ); + } + break; + case HDSRPMaterialType.Iridescence: + { + SetExtraDefine( SRPMaterialIridiscenceKeyword ); + //m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialIridiscenceKeyword ); + } + break; + case HDSRPMaterialType.Translucent: + { + SetExtraDefine( SRPMaterialTransmissionKeyword ); + //m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransmissionKeyword ); + } + break; + } + + if( m_coatMaskPort != null && m_coatMaskPort.HasOwnOrLinkConnection ) + { + SetExtraDefine( SRPMaterialClearCoatKeyword ); + //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.CustomTemplatePropertyUI == CustomTemplatePropertyUIEnum.None ) + return; + + 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 == InvisibilityStatus.Visible ); + } + + + public void SetShaderLODValueAndLabel( int value ) + { + if( ShaderLOD != value ) + ShaderLOD = value; + + if( ContainerGraph.HasLODs ) + { + SetClippedAdditionalTitle( string.Format( LodSubtitle, ShaderLOD ) ); + } + else + { + SetAdditonalTitleText( string.Empty ); + } + } + + void DrawLODAddRemoveButtons() + { + DrawLODAddRemoveButtons( -2 , true ); + } + + void DrawLODAddRemoveButtons( int index , bool showRemove ) + { + if( GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( 15 ) ) ) + { + Vector2 minPos = Vec2Position; + //bool newNodePositionMode = false; + //if( newNodePositionMode ) + //{ + // for( int lod = 0; lod < ContainerGraph.LodMultiPassMasternodes.Count; lod++ ) + // { + // if( ContainerGraph.LodMultiPassMasternodes[ lod ].Count != 0 ) + // { + // Vector2 currPos = ContainerGraph.LodMultiPassMasternodes[ lod ].NodesList[ m_passIdx ].Vec2Position; + // if( currPos.y > minPos.y ) + // { + // minPos = currPos; + // } + // } + // else + // { + // if( index < 0 ) + // { + // index = lod; + // } + // break; + // } + // } + //} + //else + //{ + for( int lod = ContainerGraph.LodMultiPassMasternodes.Count - 1 ; lod >= 0; lod-- ) + { + if( ContainerGraph.LodMultiPassMasternodes[ lod ].Count != 0 ) + { + minPos = ContainerGraph.LodMultiPassMasternodes[ lod ].NodesList[ m_passIdx ].Vec2Position; + break; + } + } + //} + + minPos.y += HeightEstimate + 10; + ContainerGraph.CreateLodMasterNodes( m_templateMultiPass, index, minPos ); + } + + if( showRemove && GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( 15 ) ) ) + { + ContainerGraph.DestroyLodMasterNodes( index ); + } + } + + void SetupLODNodeName() + { + if( IsMainOutputNode ) + { + if( string.IsNullOrEmpty( m_mainLODName ) ) + { + m_shaderNameIsTitle = true; + m_content.text = GenerateClippedTitle( m_croppedShaderName ); + } + else + { + m_shaderNameIsTitle = false; + m_content.text = GenerateClippedTitle( m_mainLODName ); + } + } + else + { + m_shaderNameIsTitle = false; + m_content.text = GenerateClippedTitle( m_passName ); + } + } + + public void DrawLodRowItem(bool listMode) + { + float labelWidthBuffer = EditorGUIUtility.labelWidth; + EditorGUILayout.BeginHorizontal(); + if( listMode ) + { + if( GUILayout.Button( "\u25b6", GUILayout.Width( 18 ), GUILayout.Height( 18 ) ) ) + { + m_containerGraph.ParentWindow.FocusOnNode( this, 1, false, true ); + } + EditorGUI.BeginChangeCheck(); + GUI.SetNextControlName( LodValueId + m_lodIndex ); + m_shaderLOD = EditorGUILayoutIntField( string.Empty, m_shaderLOD, GUILayout.Width( 50 ) ); + } + else + { + EditorGUI.BeginChangeCheck(); + EditorGUIUtility.labelWidth = 45; + GUI.SetNextControlName( LodValueId + m_lodIndex ); + m_shaderLOD = EditorGUILayoutIntField( "LOD", ShaderLOD, GUILayout.Width(100)); + EditorGUIUtility.labelWidth = labelWidthBuffer; + } + + if( EditorGUI.EndChangeCheck() ) + { + m_refreshLODValueMasterNodes = true; + m_refreshLODValueMasterNodesTimestamp = EditorApplication.timeSinceStartup; + + if( ContainerGraph.HasLODs ) + SetClippedAdditionalTitle( string.Format( LodSubtitle, ShaderLOD ) ); + } + + EditorGUI.BeginChangeCheck(); + GUI.SetNextControlName( LodNameId + ShaderLOD ); + if( listMode ) + { + m_mainLODName = EditorGUILayoutTextField( string.Empty, m_mainLODName, GUILayout.Width( 100 ) ); + } + else + { + GUILayout.Space( -15 ); + EditorGUIUtility.labelWidth = 45; + m_mainLODName = EditorGUILayoutTextField( string.Empty, m_mainLODName ); + EditorGUIUtility.labelWidth = labelWidthBuffer; + } + if( EditorGUI.EndChangeCheck() ) + { + // If reorder is scheduled make sure it doesn't happen when editing LOD name + if( m_refreshLODValueMasterNodes ) + m_refreshLODValueMasterNodesTimestamp = EditorApplication.timeSinceStartup; + + SetupLODNodeName(); + } + + if( listMode ) + DrawLODAddRemoveButtons( m_lodIndex, ( m_lodIndex >= 0) ); + + EditorGUILayout.EndHorizontal(); + + if( m_refocusLODValueMasterNodes ) + { + m_refocusLODValueMasterNodes = false; + string focusedControl = GUI.GetNameOfFocusedControl(); + if( focusedControl.Contains( LodValueId ) ) + { + GUI.FocusControl( LodValueId + m_lodIndex ); + TextEditor te = (TextEditor)GUIUtility.GetStateObject( typeof( TextEditor ), GUIUtility.keyboardControl ); + if( te != null ) + { + te.SelectTextEnd(); + } + } + else if( focusedControl.Contains( LodNameId ) ) + { + GUI.FocusControl( LodNameId + m_lodIndex ); + TextEditor te = (TextEditor)GUIUtility.GetStateObject( typeof( TextEditor ), GUIUtility.keyboardControl ); + if( te != null ) + { + te.SelectTextEnd(); + } + } + } + } + + void DrawLOD() + { + if( m_templateMultiPass.CanAddLODs && m_lodIndex == -1 ) + { + EditorGUILayout.Space(); + + DrawLodRowItem(true); + EditorGUILayout.Space(); + + for( int i = 0; i < ContainerGraph.LodMultiPassMasternodes.Count; i++ ) + { + if( ContainerGraph.LodMultiPassMasternodes[ i ].NodesList.Count > 0 ) + { + TemplateMultiPassMasterNode masterNode = m_containerGraph.LodMultiPassMasternodes[ i ].NodesList[ m_passIdx ]; + masterNode.DrawLodRowItem( true ); + EditorGUILayout.Space(); + } + } + EditorGUILayout.Space(); + } + } + + void DrawCommonProperties() + { + if( m_isMainOutputNode ) + { + //if( m_templateMultiPass.CanAddLODs && m_lodIndex == -1 ) + //{ + // if( GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( 15 ) ) ) + // { + // ContainerGraph.CreateLodMasterNodes( m_templateMultiPass, Vec2Position ); + // } + + + // if( GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( 15 ) ) ) + // { + // ContainerGraph.DestroyLodMasterNodes(); + // } + + //} + + //EditorGUILayout.LabelField( "LOD: " + m_lodIndex ); + DrawShaderName(); + DrawCurrentShaderType(); + + if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.SRPIsPBRHD ) + { + if( m_templateMultiPass.CustomTemplatePropertyUI == CustomTemplatePropertyUIEnum.HDPBR ) + { + EditorGUI.BeginChangeCheck(); + CurrentHDMaterialType = (HDSRPMaterialType)EditorGUILayoutEnumPopup( HDSRPMaterialTypeStr, m_hdSrpMaterialType ); + if( EditorGUI.EndChangeCheck() ) + ConfigHDPorts(); + } + } + + EditorGUI.BeginChangeCheck(); + DrawPrecisionProperty( false ); + if( EditorGUI.EndChangeCheck() ) + ContainerGraph.CurrentPrecision = m_currentPrecisionType; + m_drawInstancedHelper.Draw( this ); + m_fallbackHelper.Draw( this ); + DrawCustomInspector( m_templateMultiPass.SRPtype != TemplateSRPType.BuiltIn ); + m_subShaderOptions.DrawCustomOptions( this ); + m_dependenciesHelper.Draw( this, true ); + } + //EditorGUILayout.LabelField( m_subShaderIdxStr ); + //EditorGUILayout.LabelField( m_passIdxStr ); + + if( IsLODMainMasterNode && m_templateMultiPass.CanAddLODs ) + { + NodeUtils.DrawNestedPropertyGroup( ref m_lodFoldout, AdditionalLODsStr, DrawLOD, DrawLODAddRemoveButtons ); + } + + DrawOpenTemplateButton(); + if( DebugConsoleWindow.DeveloperMode ) + DrawReloadButton(); + + } + + public void DrawSubShaderProperties() + { + if( !m_isMainOutputNode ) + { + m_mainMasterNodeRef.DrawSubShaderProperties(); + return; + } + + bool noValidData = true; + if( ShaderLOD > 0 ) + { + noValidData = false; + if( m_templateMultiPass.CanAddLODs && m_containerGraph.LodMultiPassMasternodes[0].Count > 0 ) + { + DrawLodRowItem( false ); + } + else + { + ShaderLOD = EditorGUILayoutIntField( SubShaderLODValueLabel, ShaderLOD ); + } + } + + if( m_subShaderModule.HasValidData ) + { + noValidData = false; + m_subShaderModule.Draw( this, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Modules ); + //if( m_subShaderModule.IsDirty ) + //{ + // List<TemplateMultiPassMasterNode> 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; + //} + } + + m_passSelector.Draw( this ); + + 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 ); + } + EditorGUILayout.LabelField( Pass.Modules.PassUniqueName ); + if( m_passModule.HasValidData ) + { + m_passModule.Draw( this, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules, m_subShaderModule ); + } + + m_usePass.Draw( this, false ); + m_passOptions.DrawCustomOptions( this ); + } + + bool CreateInstructionsForList( TemplateData templateData, ref List<InputPort> ports, ref string shaderBody, ref List<string> vertexInstructions, ref List<string> 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.AddToDirectives( SRPMaterialNormalMapKeyword, -1, AdditionalLineType.Define ); + // } + + // if( ports[ i ].Name.Contains( "Alpha Clip Threshold" ) ) + // { + // m_currentDataCollector.AddToDirectives( SRPMaterialBlendModeAlphaClipThresholdKeyword, -1, AdditionalLineType.Define ); + // } + + // if( ports[ i ].Name.Contains( "Specular" ) ) + // { + // m_currentDataCollector.AddToDirectives( SRPLWMaterialSpecularKeyword, -1, AdditionalLineType.Define ); + // } + //} + //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( MasterNodeDataCollector inDataCollector, ref MasterNodeDataCollector outDataCollector ) + { + List<TemplateMultiPassMasterNode> 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() ); + + if( inDataCollector != null ) + outDataCollector.CopyPropertiesFromDataCollector( inDataCollector ); + + outDataCollector.TemplateDataCollectorInstance.CurrentSRPType = m_templateMultiPass.SRPtype; + + int lastActivePass = m_passSelector.LastActivePass; + int count = list.Count; + + for( int i = 0; i < count; i++ ) + { + bool removePass = !m_passSelector.IsVisible( i ); + + list[ 0 ].CurrentTemplate.IdManager.SetPassIdUsage( i, removePass ); + if( removePass ) + continue; + + list[ i ].CollectData(); + list[ i ].FillPassData( this, outDataCollector.TemplateDataCollectorInstance ); + + if( list[ i ].SubShaderIdx == currentSubshader ) + { + outDataCollector.CopyPropertiesFromDataCollector( list[ i ].CurrentDataCollector ); + } + else + { + list[ i - 1 ].FillPropertyData( outDataCollector ); + list[ i - 1 ].FillSubShaderData(); + outDataCollector.Destroy(); + outDataCollector = new MasterNodeDataCollector(); + outDataCollector.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 ) ) + if( i == lastActivePass ) + { + list[ i ].FillPropertyData( outDataCollector ); + } + + if( list[ i ].IsMainOutputNode ) + list[ i ].FillSubShaderData(); + } + + outDataCollector.TemplateDataCollectorInstance.BuildCBuffer( -1 ); + + //Fill uniforms is set on last since we need to collect all srp batcher data ( if needed ) + //To set it into each pass + for( int i = 0; i < count; i++ ) + { + bool removePass = !m_passSelector.IsVisible( i ); + if( removePass ) + continue; + + list[ i ].FillUniforms( outDataCollector.TemplateDataCollectorInstance ); + } + + return list[ 0 ].CurrentTemplate.IdManager.BuildShader(); + } + + public string BuildLOD( MasterNodeDataCollector inDataCollector, ref MasterNodeDataCollector outDataCollector ) + { + UsageListTemplateMultiPassMasterNodes bufferNodesList = ContainerGraph.MultiPassMasterNodes; + int bufferMasterNodeId = ContainerGraph.CurrentMasterNodeId; + + ContainerGraph.MultiPassMasterNodes = ContainerGraph.LodMultiPassMasternodes[ m_lodIndex ]; + ContainerGraph.CurrentMasterNodeId = UniqueId; + + m_templateMultiPass.ResetState(); + base.Execute( string.Empty, false ); + string shaderBody = BuildShaderBody( inDataCollector, ref outDataCollector ); + + + ContainerGraph.MultiPassMasterNodes = bufferNodesList; + ContainerGraph.CurrentMasterNodeId = bufferMasterNodeId; + return shaderBody; + } + + public override Shader Execute( string pathname, bool isFullPath ) + { + ForceReordering(); + MasterNodeDataCollector overallDataCollector = new MasterNodeDataCollector(); + + //BUILD LOD + string allLodSubShaders = string.Empty; + if( ContainerGraph.HasLODs ) + { + for( int lod = 0; lod < ContainerGraph.LodMultiPassMasternodes.Count; lod++ ) + { + if( ContainerGraph.LodMultiPassMasternodes[ lod ].Count == 0 ) + break; + + TemplateMultiPassMasterNode newMasterNode = ContainerGraph.LodMultiPassMasternodes[ lod ].NodesList.Find( ( x ) => x.IsMainOutputNode ); + string lodSubShaders = newMasterNode.BuildLOD( null, ref overallDataCollector ); + lodSubShaders = TemplateHelperFunctions.GetSubShaderFrom( lodSubShaders ) + "\n"; + allLodSubShaders += lodSubShaders; + } + } + + //BUILD MAIN + m_templateMultiPass.ResetState(); + base.Execute( pathname, isFullPath ); + MasterNodeDataCollector dummy = new MasterNodeDataCollector(); + string shaderBody = BuildShaderBody( overallDataCollector, ref dummy ); + + //COMBINE LOD WITH MAIN + if( !string.IsNullOrEmpty( allLodSubShaders ) ) + shaderBody = shaderBody.Replace( TemplatesManager.TemplateLODsTag, allLodSubShaders ); + + UpdateShaderAsset( ref pathname, ref shaderBody, isFullPath ); + return m_currentShader; + } + + public void CollectData() + { + if( m_inputPorts.Count == 0 ) + return; + + ContainerGraph.ResetNodesLocalVariables(); + m_optionsDefineContainer.RemoveTemporaries(); + 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 ) + { + string blockName = UIUtils.RemoveInvalidCharacters( ContainerGraph.GetMainMasterNodeOfLOD( -1 ).ShaderName ); + m_currentDataCollector.SetupInstancePropertiesBlock( blockName ); + } + 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 ] ); + } + } + // Check Current Options for property changes on subshader + if( m_isMainOutputNode ) + { + CheckPropertyChangesOnOptions( m_subShaderOptions ); + } + + // Check Current Options for property changes on pass + CheckPropertyChangesOnOptions( m_passOptions ); + + + //Set SRP info +#if UNITY_2018_3_OR_NEWER + if( m_templateMultiPass.SRPtype != TemplateSRPType.BuiltIn ) + ASEPackageManagerHelper.SetSRPInfoOnDataCollector( ref m_currentDataCollector ); +#endif + RegisterStandaloneFuntions(); + m_containerGraph.CheckPropertiesAutoRegister( ref m_currentDataCollector ); + + //Sort ports by both + List<InputPort> fragmentPorts = new List<InputPort>(); + List<InputPort> vertexPorts = new List<InputPort>(); + + SortInputPorts( ref vertexPorts, ref fragmentPorts ); + + + string shaderBody = templateData.TemplateBody; + + List<string> vertexInstructions = new List<string>(); + List<string> fragmentInstructions = new List<string>(); + + 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; + + if( !m_isMainOutputNode && m_mainMasterNodeRef == null ) + { + m_mainMasterNodeRef = m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode; + } + + TerrainDrawInstancedHelper drawInstanced = m_isMainOutputNode ? m_drawInstancedHelper : m_mainMasterNodeRef.DrawInstancedHelperInstance; + drawInstanced.UpdateDataCollectorForTemplates( ref m_currentDataCollector, ref vertexInstructions ); + + 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 = m_currentDataCollector.IsSRP ? + // string.Format( IOUtils.SRPInstancedPropertiesBegin, "UnityPerMaterial" ) : + // string.Format( IOUtils.InstancedPropertiesBegin, m_currentDataCollector.InstanceBlockName ); + //string cBufferEnd = m_currentDataCollector.IsSRP ? ( string.Format( IOUtils.SRPInstancedPropertiesEnd, m_currentDataCollector.InstanceBlockName ) ) : IOUtils.InstancedPropertiesEnd; + string cbufferBegin = m_currentDataCollector.IsSRP ? + string.Format( IOUtils.LWSRPInstancedPropertiesBegin, m_currentDataCollector.InstanceBlockName ) : + string.Format( 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 ); + } + + if( m_currentDataCollector.DotsPropertiesList.Count > 0 ) + { + m_currentDataCollector.DotsPropertiesList.Insert( 0, new PropertyDataCollector( -1, "UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)" ) ); + m_currentDataCollector.DotsPropertiesList.Insert( 0, new PropertyDataCollector( -1, "#ifdef UNITY_DOTS_INSTANCING_ENABLED" ) ); + m_currentDataCollector.DotsPropertiesList.Insert( 0, new PropertyDataCollector( -1, "" ) ); + m_currentDataCollector.DotsPropertiesList.Add( new PropertyDataCollector( -1, "UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)" ) ); + m_currentDataCollector.DotsDefinesList.Add( new PropertyDataCollector( -1, "#endif" ) ); + m_currentDataCollector.UniformsList.AddRange( m_currentDataCollector.DotsPropertiesList ); + m_currentDataCollector.UniformsList.AddRange( m_currentDataCollector.DotsDefinesList ); + } + + TemplateShaderModelModule shaderModelModule = m_isMainOutputNode ? m_subShaderModule.ShaderModelHelper : m_mainMasterNodeRef.SubShaderModule.ShaderModelHelper; + string shaderModel = string.Empty; + if( m_passModule.ShaderModelHelper.ValidData ) + { + shaderModel = m_passModule.ShaderModelHelper.CurrentShaderModel; + } + else if( shaderModelModule.ValidData ) + { + shaderModel = shaderModelModule.CurrentShaderModel; + } + else if( m_templateMultiPass.GlobalShaderModel.IsValid ) + { + shaderModel = m_templateMultiPass.GlobalShaderModel.Value; + } + else + { + shaderModel = ( m_templateMultiPass.SRPtype == TemplateSRPType.HD ) ? "4.5" : "3.0"; + } + + m_currentDataCollector.TemplateDataCollectorInstance.CheckInterpolatorOverflow( shaderModel, m_passName ); + } + + public void CheckPropertyChangesOnOptions( TemplateOptionsUIHelper optionsUI ) + { + //Only Main LOD master node can change shader properties + if( !IsLODMainMasterNode ) + return; + + List<TemplateOptionUIItem> options = optionsUI.PassCustomOptionsUI; + for( int optionIdx = 0; optionIdx < options.Count; optionIdx++ ) + { + if( options[ optionIdx ].IsVisible ) + { + TemplateActionItem[] actionItems = options[ optionIdx ].CurrentOptionActions.Columns; + for( int actionIdx = 0; actionIdx < actionItems.Length; actionIdx++ ) + { + if( actionItems[ actionIdx ].ActionType == AseOptionsActionType.SetShaderProperty && !string.IsNullOrEmpty( actionItems[ actionIdx ].ActionBuffer ) ) + { + TemplateShaderPropertyData data = m_templateMultiPass.GetShaderPropertyData( actionItems[ actionIdx ].ActionData ); + if( data != null ) + { + string newPropertyValue = data.CreatePropertyForValue( actionItems[ actionIdx ].ActionBuffer ); + CurrentTemplate.IdManager.SetReplacementText( data.FullValue, newPropertyValue ); + } + } + } + + if( options[ optionIdx ].Options.Type == AseOptionsType.Field ) + { + foreach( var item in CurrentTemplate.IdManager.RegisteredTags ) + { + if( item.Output.Equals( options[ optionIdx ].Options.FieldInlineName ) ) + { + var node = options[ optionIdx ].Options.FieldValue.GetPropertyNode(); + if( node != null && ( node.IsConnected || node.AutoRegister ) && options[ optionIdx ].Options.FieldValue.Active ) + { + item.Replacement = node.PropertyName; + } + } + } + } + } + } + } + public void FillPropertyData( MasterNodeDataCollector dataCollector = null ) + { + MasterNodeDataCollector currDataCollector = ( dataCollector == null ) ? m_currentDataCollector : dataCollector; + +#if UNITY_2019_2_OR_NEWER + // Temporary hack + if( m_templateMultiPass.SRPtype != TemplateSRPType.BuiltIn && ASEPackageManagerHelper.CurrentHDVersion > ASESRPVersions.ASE_SRP_6_9_0 ) + { + if( m_templateMultiPass.AvailableShaderProperties.Find( x => x.PropertyName.Equals( "_AlphaCutoff" ) ) == null ) + { + if( !currDataCollector.ContainsProperty("_AlphaCutoff") ) + { + currDataCollector.AddToProperties( UniqueId, "[HideInInspector] _AlphaCutoff(\"Alpha Cutoff \", Range(0, 1)) = 0.5", -1 ); + } + } + + if( m_templateMultiPass.AvailableShaderProperties.Find( x => x.PropertyName.Equals( "_EmissionColor" ) ) == null ) + { + if( !currDataCollector.ContainsProperty( "_EmissionColor" ) ) + { + currDataCollector.AddToProperties( UniqueId, "[HideInInspector] _EmissionColor(\"Emission Color\", Color) = (1,1,1,1)", -1 ); + } + } + } +#endif + + 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 ); + if( ShaderLOD > -1 ) + { + string lodUniqueId = m_templateMultiPass.SubShaders[ m_subShaderIdx ].UniquePrefix + "Module" + m_templateMultiPass.SubShaders[ m_subShaderIdx ].LODContainer.Id; + m_templateMultiPass.IdManager.SetReplacementText( lodUniqueId, "LOD " + ShaderLOD ); + } + + SetModuleData( m_subShaderModule, true ); + } + + public void FillPassData( TemplateMultiPassMasterNode masterNode, TemplateDataCollector mainTemplateDataCollector ) + { + if( m_isInvisible != InvisibilityStatus.Visible ) + { + 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 ) + { + SetPassCustomOptionsInfo( m_containerGraph.CurrentMasterNode as TemplateMultiPassMasterNode ); + } + else + { + SetPassCustomOptionsInfo( this ); + } + + var inputArray = m_currentDataCollector.VertexInputList.ToArray(); + + m_templateMultiPass.SetPassData( TemplateModuleDataType.PassVertexData, m_subShaderIdx, m_passIdx, inputArray ); + m_templateMultiPass.SetPassData( TemplateModuleDataType.PassInterpolatorData, m_subShaderIdx, m_passIdx, m_currentDataCollector.InterpolatorList.ToArray() ); + SetHDInfoOnPass(); + List<PropertyDataCollector> afterNativesIncludePragmaDefineList = new List<PropertyDataCollector>(); + afterNativesIncludePragmaDefineList.AddRange( m_currentDataCollector.IncludesList ); + afterNativesIncludePragmaDefineList.AddRange( m_currentDataCollector.DefinesList ); + //includePragmaDefineList.AddRange( m_optionsDefineContainer.DefinesList ); + afterNativesIncludePragmaDefineList.AddRange( m_currentDataCollector.PragmasList ); + afterNativesIncludePragmaDefineList.AddRange( m_currentDataCollector.AfterNativeDirectivesList ); + + //includePragmaDefineList.AddRange( m_currentDataCollector.MiscList ); + + List<PropertyDataCollector> beforeNatives = new List<PropertyDataCollector>(); + beforeNatives.AddRange( m_optionsDefineContainer.DefinesList ); + beforeNatives.AddRange( m_currentDataCollector.BeforeNativeDirectivesList ); + + m_templateMultiPass.SetPassData( TemplateModuleDataType.ModulePragmaBefore, m_subShaderIdx, m_passIdx, beforeNatives ); + m_templateMultiPass.SetPassData( TemplateModuleDataType.ModulePragma, m_subShaderIdx, m_passIdx, afterNativesIncludePragmaDefineList ); + + 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 ); + } + + //copy srp batch if present + //if( m_currentDataCollector.IsSRP ) + //{ + // m_currentDataCollector.UniformsList.AddRange( mainTemplateDataCollector.SrpBatcherPropertiesList ); + //} + //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 ); + + if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].TessVControlTag != null && m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].TessVControlTag.IsValid ) + m_templateMultiPass.SetPassData( TemplateModuleDataType.VControl, m_subShaderIdx, m_passIdx, inputArray ); + + if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].TessControlData != null && m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].TessControlData.IsValid ) + m_templateMultiPass.SetPassData( TemplateModuleDataType.ControlData, m_subShaderIdx, m_passIdx, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].TessControlData.GenerateControl( m_currentDataCollector.TemplateDataCollectorInstance.VertexDataDict, m_currentDataCollector.VertexInputList ) ); + + if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].TessDomainData != null && m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].TessDomainData.IsValid ) + m_templateMultiPass.SetPassData( TemplateModuleDataType.DomainData, m_subShaderIdx, m_passIdx, m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].TessDomainData.GenerateDomain( m_currentDataCollector.TemplateDataCollectorInstance.VertexDataDict, m_currentDataCollector.VertexInputList ) ); + + afterNativesIncludePragmaDefineList.Clear(); + afterNativesIncludePragmaDefineList = null; + + beforeNatives.Clear(); + beforeNatives = null; + } + + m_templateMultiPass.SetPassData( TemplateModuleDataType.PassNameData, m_subShaderIdx, m_passIdx, string.Format( PassNameFormateStr, m_passName ) ); + } + + public List<PropertyDataCollector> CrossCheckSoftRegisteredUniformList( List<PropertyDataCollector> uniformList ) + { + List<PropertyDataCollector> newItems = new List<PropertyDataCollector>(); + for( int i = 0; i < uniformList.Count; i++ ) + { + if( !m_currentDataCollector.CheckIfSoftRegistered( uniformList[ i ].PropertyName ) ) + { + newItems.Add( uniformList[ i ] ); + } + } + return newItems; + } + + public void FillUniforms( TemplateDataCollector mainTemplateDataCollector ) + { + if( m_currentDataCollector.IsSRP ) + { + + if( m_templateMultiPass.SubShaders[ m_subShaderIdx ].Passes[ m_passIdx ].Modules.SRPBatcherTag.IsValid ) + { + List<PropertyDataCollector> finalList = CrossCheckSoftRegisteredUniformList( mainTemplateDataCollector.SrpBatcherPropertiesList ); + m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleSRPBatcher, m_subShaderIdx, m_passIdx, finalList ); + finalList.Clear(); + finalList = null; + } + else + { + List<PropertyDataCollector> finalList = CrossCheckSoftRegisteredUniformList( mainTemplateDataCollector.FullSrpBatcherPropertiesList ); + m_currentDataCollector.UniformsList.AddRange( finalList ); + finalList.Clear(); + finalList = null; + } + } + m_templateMultiPass.SetPassData( TemplateModuleDataType.ModuleGlobals, m_subShaderIdx, m_passIdx, m_currentDataCollector.UniformsList ); + } + + void SetHDInfoOnPass() + { +#if UNITY_2019_3_OR_NEWER + if( ASEPackageManagerHelper.CurrentHDVersion > ASESRPVersions.ASE_SRP_6_9_1 ) + return; +#endif + + 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 ) + { + SetExtraDefine( SRPMaterialTransparentKeyword ); + //m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialTransparentKeyword ); + TemplatesBlendModule blendOpHelper = passHelper.BlendOpHelper.ValidBlendMode ? passHelper.BlendOpHelper : subShaderHelper.BlendOpHelper; + if( blendOpHelper.IsAdditiveRGB ) + { + SetExtraDefine( SRPMaterialBlendModeAddKeyword ); + //m_currentDataCollector.AddToDefines( UniqueId, SRPMaterialBlendModeAddKeyword ); + } + else if( blendOpHelper.IsAlphaBlendRGB ) + { + SetExtraDefine( SRPMaterialBlendModeAlphaKeyword ); + //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<PropertyDataCollector> aboveUsePass = new List<PropertyDataCollector>(); + List<PropertyDataCollector> belowUsePass = new List<PropertyDataCollector>(); + m_usePass.BuildUsePassInfo( m_currentDataCollector, ref aboveUsePass, ref belowUsePass ); + //TODO Must place this on the correct place + aboveUsePass.AddRange( belowUsePass ); + + //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(); + + m_drawInstancedHelper = null; + + m_optionsDefineContainer.Destroy(); + m_optionsDefineContainer = null; + + m_passSelector.Destroy(); + m_passSelector = null; + + m_subShaderOptions.Destroy(); + m_passOptions.Destroy(); + + 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; + if( m_lodIndex == -1 ) + { + ContainerGraph.MultiPassMasterNodes.RemoveNode( this ); + } + else + { + ContainerGraph.LodMultiPassMasternodes[ m_lodIndex ].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 ); + bool hasUniqueName = false; + if( UIUtils.CurrentShaderVersion() > PASS_UNIQUE_ID_VERSION ) + { + hasUniqueName = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + } + + if( hasUniqueName ) + m_passUniqueId = GetCurrentParam( ref nodeParams ); + + m_subShaderIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_passIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > LOD_SUBSHADER_VERSION ) + { + + if( m_lodIndex != -1 ) + { + m_containerGraph.MultiPassMasterNodes.RemoveNode( this ); + m_containerGraph.LodMultiPassMasternodes[ m_lodIndex ].AddNode( this ); + } + } + + m_passName = GetCurrentParam( ref nodeParams ); + SetTemplate( null, false, true, m_subShaderIdx, m_passIdx, SetTemplateSource.ShaderLoad ); + ////If value gotten from template is > -1 then it contains the LOD field + ////and we can properly write the value + //if( m_subShaderLOD > -1 ) + //{ + // m_subShaderLOD = subShaderLOD; + //} + + // 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 ) + { + if( m_isMainOutputNode && UIUtils.CurrentShaderVersion() > PASS_SELECTOR_VERSION ) + m_subShaderOptions.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + + m_passOptions.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( m_isMainOutputNode && UIUtils.CurrentShaderVersion() > PASS_SELECTOR_VERSION ) + { + m_passSelector.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( m_isMainOutputNode && UIUtils.CurrentShaderVersion() > 16203 ) + { + m_drawInstancedHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( m_isMainOutputNode && UIUtils.CurrentShaderVersion() > LOD_SUBSHADER_VERSION ) + { + m_mainLODName = GetCurrentParam( ref nodeParams ); + SetupLODNodeName(); + } + else + { + m_content.text = GenerateClippedTitle( m_passName ); + } + + + //if( m_templateMultiPass != null && !m_templateMultiPass.IsSinglePass ) + //{ + // SetClippedTitle( m_passName ); + //} + } + catch( Exception e ) + { + Debug.LogException( e, this ); + } + + m_containerGraph.CurrentCanvasMode = NodeAvailability.TemplateShader; + m_containerGraph.CurrentPrecision = m_currentPrecisionType; + } + + 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 ); + + bool hasUniquePassName = Pass.Modules.HasPassUniqueName; + IOUtils.AddFieldValueToString( ref nodeInfo, hasUniquePassName ); + if( hasUniquePassName ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, Pass.Modules.PassUniqueName ); + } + + 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 ); + if( m_isMainOutputNode ) + m_subShaderOptions.WriteToString( ref nodeInfo ); + + m_passOptions.WriteToString( ref nodeInfo ); + + if( m_isMainOutputNode ) + { + m_passSelector.WriteToString( ref nodeInfo ); + m_drawInstancedHelper.WriteToString( ref nodeInfo ); + } + + if( m_isMainOutputNode ) + IOUtils.AddFieldValueToString( ref nodeInfo, m_mainLODName ); + + } + + 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,SetTemplateSource.ShaderLoad ); + } + else + { + template = m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplateByName( templateShaderName ) as TemplateMultiPass; + if( template != null ) + { + m_templateGUID = template.GUID; + SetTemplate( null, false, true, 0, 0, SetTemplateSource.ShaderLoad ); + } + 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 void ForceOptionsRefresh() + { + m_passOptions.Refresh(); + if( m_isMainOutputNode ) + m_subShaderOptions.Refresh(); + } + + public void SetPassVisible( string passName, bool visible ) + { + TemplateMultiPassMasterNode node = m_containerGraph.GetMasterNodeOfPass( passName, m_lodIndex ); + if( node != null ) + { + m_passSelector.SetPassVisible( passName, visible ); + node.IsInvisible = !visible; + } + + } + + public override void RefreshExternalReferences() + { + if( m_invalidNode ) + return; + + base.RefreshExternalReferences(); + if( IsLODMainMasterNode ) + { + SetMasterNodeCategoryFromGUID( m_templateGUID ); + } + + 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(); + } + + if( ContainerGraph.HasLODs ) + { + SetClippedAdditionalTitle( string.Format( LodSubtitle, ShaderLOD ) ); + } + + if( m_isMainOutputNode ) + { + List<TemplateMultiPassMasterNode> masterNodes = ( m_lodIndex == -1 ) ? m_containerGraph.MultiPassMasterNodes.NodesList : m_containerGraph.LodMultiPassMasternodes[ m_lodIndex ].NodesList; + masterNodes.Sort( ( x, y ) => ( x.PassIdx.CompareTo( y.PassIdx ) )); + int passAmount = m_templateMultiPass.SubShaders[ m_subShaderIdx ].PassAmount; + if( passAmount != masterNodes.Count ) + { + UIUtils.ShowMessage( "Template master nodes amount was modified. Could not set correctly its visibility options." ); + } + else + { + for( int i = 0; i < passAmount; i++ ) + { + if( i != m_passIdx ) + { + masterNodes[ i ].IsInvisible = !m_passSelector.IsVisible( i ); + } + } + } + } + } + + public override void ReadInputDataFromString( ref string[] nodeParams ) + { + //For a Template Master Node an input port data must be set by its template and not meta data + if( UIUtils.CurrentShaderVersion() > 17007 ) + return; + + int count = 0; + if( UIUtils.CurrentShaderVersion() > 7003 ) + { + try + { + count = Convert.ToInt32( nodeParams[ m_currentReadParamIdx++ ] ); + } + catch( Exception e ) + { + Debug.LogException( e ); + } + } + else + { + count = ( m_oldInputCount < 0 ) ? m_inputPorts.Count : m_oldInputCount; + } + + for( int i = 0; i < count && i < nodeParams.Length && m_currentReadParamIdx < nodeParams.Length; i++ ) + { + if( UIUtils.CurrentShaderVersion() < 5003 ) + { + int newId = VersionConvertInputPortId( i ); + if( UIUtils.CurrentShaderVersion() > 23 ) + { + m_currentReadParamIdx++; + } + + m_currentReadParamIdx++; + if( m_inputPorts[ newId ].IsEditable && UIUtils.CurrentShaderVersion() >= 3100 && m_currentReadParamIdx < nodeParams.Length ) + { + m_currentReadParamIdx++; + } + } + else + { + m_currentReadParamIdx++; + m_currentReadParamIdx++; + m_currentReadParamIdx++; + bool isEditable = Convert.ToBoolean( nodeParams[ m_currentReadParamIdx++ ] ); + if( isEditable && m_currentReadParamIdx < nodeParams.Length ) + { + m_currentReadParamIdx++; + } + } + } + } + + //For a Template Master Node an input port data must be set by its template and not meta data + public override void WriteInputDataToString( ref string nodeInfo ) { } + + 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<TemplateMultiPassMasterNode> 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 PassUniqueName + { + get + { + return string.IsNullOrEmpty( m_passUniqueId ) ? m_originalPassName : m_passUniqueId; + } + } + + public string OriginalPassName { get { return m_originalPassName; } } + public bool HasLinkPorts { get { return m_hasLinkPorts; } } + public bool IsInvisible + { + get + { + return m_isInvisible != InvisibilityStatus.Visible; + } + set + { + if( m_isInvisible != InvisibilityStatus.LockedInvisible && !m_isMainOutputNode ) + { + m_isInvisible = value ? InvisibilityStatus.Invisible : InvisibilityStatus.Visible; + if( value ) + { + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + m_inputPorts[ i ].FullDeleteConnections(); + } + } + } + } + } + + public TemplatePassSelectorHelper PassSelector { get { return m_passSelector; } } + public TemplateOptionsUIHelper PassOptions { get { return m_passOptions; } } + public TemplateOptionsUIHelper SubShaderOptions { get { return m_subShaderOptions; } } + public TemplateOptionsDefinesContainer OptionsDefineContainer { get { return m_optionsDefineContainer; } } + public TerrainDrawInstancedHelper DrawInstancedHelperInstance { get { return m_drawInstancedHelper; } } + public bool InvalidNode { get { return m_invalidNode; } } + public override void SetName( string name ) + { + ShaderName = name; + } + public bool IsLODMainFirstPass { get { return m_passIdx == 0 && m_lodIndex == -1; } } + } +} |