diff options
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master')
60 files changed, 15238 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalDefinesHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalDefinesHelper.cs new file mode 100644 index 00000000..7aa08d96 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalDefinesHelper.cs @@ -0,0 +1,140 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class AdditionalDefinesHelper + { + private const string AdditionalDefinesStr = " Additional Defines"; + private const float ShaderKeywordButtonLayoutWidth = 15; + private ParentNode m_currentOwner; + + [SerializeField] + private List<string> m_additionalDefines = new List<string>(); + public List<string> DefineList { get { return m_additionalDefines; } set { m_additionalDefines = value; } } + + [SerializeField] + private List<string> m_outsideDefines = new List<string>(); + public List<string> OutsideList { get { return m_outsideDefines; } set { m_outsideDefines = value; } } + + public void Draw( ParentNode owner ) + { + m_currentOwner = owner; + bool value = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalDefines; + NodeUtils.DrawPropertyGroup( ref value, AdditionalDefinesStr, DrawMainBody, DrawButtons ); + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalDefines = value; + } + + void DrawButtons() + { + EditorGUILayout.Separator(); + + // Add keyword + if( GUILayout.Button( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_additionalDefines.Add( string.Empty ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove keyword + if( GUILayout.Button( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + if( m_additionalDefines.Count > 0 ) + { + m_additionalDefines.RemoveAt( m_additionalDefines.Count - 1 ); + EditorGUI.FocusTextInControl( null ); + } + } + } + + void DrawMainBody() + { + EditorGUILayout.Separator(); + int itemCount = m_additionalDefines.Count; + int markedToDelete = -1; + for( int i = 0; i < itemCount; i++ ) + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUI.BeginChangeCheck(); + m_additionalDefines[ i ] = EditorGUILayout.TextField( m_additionalDefines[ i ] ); + if( EditorGUI.EndChangeCheck() ) + { + m_additionalDefines[ i ] = UIUtils.RemoveShaderInvalidCharacters( m_additionalDefines[ i ] ); + } + + // Add new port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_additionalDefines.Insert( i + 1, string.Empty ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + markedToDelete = i; + } + } + EditorGUILayout.EndHorizontal(); + } + + if( markedToDelete > -1 ) + { + if( m_additionalDefines.Count > markedToDelete ) + { + m_additionalDefines.RemoveAt( markedToDelete ); + EditorGUI.FocusTextInControl( null ); + } + } + EditorGUILayout.Separator(); + EditorGUILayout.HelpBox( "Please add your defines without the #define keywords", MessageType.Info ); + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + int count = Convert.ToInt32( nodeParams[ index++ ] ); + for( int i = 0; i < count; i++ ) + { + m_additionalDefines.Add( nodeParams[ index++ ] ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDefines.Count ); + for( int i = 0; i < m_additionalDefines.Count; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalDefines[ i ] ); + } + } + + public void AddToDataCollector( ref MasterNodeDataCollector dataCollector ) + { + for( int i = 0; i < m_additionalDefines.Count; i++ ) + { + if( !string.IsNullOrEmpty( m_additionalDefines[ i ] ) ) + dataCollector.AddToDefines( -1, m_additionalDefines[ i ] ); + } + + for( int i = 0; i < m_outsideDefines.Count; i++ ) + { + if( !string.IsNullOrEmpty( m_outsideDefines[ i ] ) ) + dataCollector.AddToDefines( -1, m_outsideDefines[ i ] ); + } + } + + public void Destroy() + { + m_additionalDefines.Clear(); + m_additionalDefines = null; + m_currentOwner = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalDefinesHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalDefinesHelper.cs.meta new file mode 100644 index 00000000..6839c0e6 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalDefinesHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0801a5994efb46142ad8dcc0fe3c47f8 +timeCreated: 1513252939 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalIncludesHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalIncludesHelper.cs new file mode 100644 index 00000000..542b586f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalIncludesHelper.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class AdditionalIncludesHelper + { + private const string AdditionalIncludesStr = " Additional Includes"; + private const float ShaderKeywordButtonLayoutWidth = 15; + private ParentNode m_currentOwner; + + [SerializeField] + private List<string> m_additionalIncludes = new List<string>(); + public List<string> IncludeList { get { return m_additionalIncludes; } set { m_additionalIncludes = value; } } + + [SerializeField] + private List<string> m_outsideIncludes = new List<string>(); + public List<string> OutsideList { get { return m_outsideIncludes; } set { m_outsideIncludes = value; } } + + public void Draw( ParentNode owner ) + { + m_currentOwner = owner; + bool value = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalIncludes; + NodeUtils.DrawPropertyGroup( ref value, AdditionalIncludesStr, DrawMainBody, DrawButtons ); + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalIncludes = value; + + } + + void DrawButtons() + { + EditorGUILayout.Separator(); + + // Add keyword + if( GUILayout.Button( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_additionalIncludes.Add( string.Empty ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove keyword + if( GUILayout.Button( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + if( m_additionalIncludes.Count > 0 ) + { + m_additionalIncludes.RemoveAt( m_additionalIncludes.Count - 1 ); + EditorGUI.FocusTextInControl( null ); + } + } + } + + void DrawMainBody() + { + EditorGUILayout.Separator(); + //if( OutsideList != null && OutsideList.Count > 0 ) + //{ + // m_drawElements.Clear(); + // EditorGUI.BeginDisabledGroup( true ); + // int outsideCount = OutsideList.Count; + // for( int i = 0; i < outsideCount; i++ ) + // { + // if( !m_drawElements.Contains( OutsideList[ i ] ) ) + // { + // m_drawElements.Add( OutsideList[ i ] ); + // EditorGUILayout.TextField( OutsideList[ i ] ); + // } + // } + // EditorGUI.EndDisabledGroup(); + // EditorGUILayout.Separator(); + //} + int itemCount = m_additionalIncludes.Count; + int markedToDelete = -1; + for( int i = 0; i < itemCount; i++ ) + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUI.BeginChangeCheck(); + m_additionalIncludes[ i ] = EditorGUILayout.TextField( m_additionalIncludes[ i ] ); + if( EditorGUI.EndChangeCheck() ) + { + m_additionalIncludes[ i ] = UIUtils.RemoveShaderInvalidCharacters( m_additionalIncludes[ i ] ); + } + + // Add new port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_additionalIncludes.Insert( i + 1, string.Empty ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + markedToDelete = i; + } + } + EditorGUILayout.EndHorizontal(); + } + + if( markedToDelete > -1 ) + { + if( m_additionalIncludes.Count > markedToDelete ) + { + m_additionalIncludes.RemoveAt( markedToDelete ); + EditorGUI.FocusTextInControl( null ); + } + } + EditorGUILayout.Separator(); + EditorGUILayout.HelpBox( "Please add your includes without the #include \"\" keywords", MessageType.Info ); + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + int count = Convert.ToInt32( nodeParams[ index++ ] ); + for( int i = 0; i < count; i++ ) + { + m_additionalIncludes.Add( nodeParams[ index++ ] ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalIncludes.Count ); + for( int i = 0; i < m_additionalIncludes.Count; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalIncludes[ i ] ); + } + } + + public void AddToDataCollector( ref MasterNodeDataCollector dataCollector ) + { + for( int i = 0; i < m_additionalIncludes.Count; i++ ) + { + if( !string.IsNullOrEmpty( m_additionalIncludes[ i ] ) ) + dataCollector.AddToIncludes( -1, m_additionalIncludes[ i ] ); + } + + for( int i = 0; i < m_outsideIncludes.Count; i++ ) + { + if( !string.IsNullOrEmpty( m_outsideIncludes[ i ] ) ) + dataCollector.AddToIncludes( -1, m_outsideIncludes[ i ] ); + } + } + + public void Destroy() + { + m_additionalIncludes.Clear(); + m_additionalIncludes = null; + m_currentOwner = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalIncludesHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalIncludesHelper.cs.meta new file mode 100644 index 00000000..0997164e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalIncludesHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 74ff3d342e013f64198aaf767e623962 +timeCreated: 1498123240 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalPragmasHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalPragmasHelper.cs new file mode 100644 index 00000000..a7e89707 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalPragmasHelper.cs @@ -0,0 +1,141 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class AdditionalPragmasHelper + { + private const string AdditionalPragmasStr = " Additional Pragmas"; + private const float ShaderKeywordButtonLayoutWidth = 15; + private ParentNode m_currentOwner; + + [SerializeField] + private List<string> m_additionalPragmas = new List<string>(); + public List<string> PragmaList { get { return m_additionalPragmas; } set { m_additionalPragmas = value; } } + + [SerializeField] + private List<string> m_outsidePragmas = new List<string>(); + public List<string> OutsideList { get { return m_outsidePragmas; } set { m_outsidePragmas = value; } } + + public void Draw( ParentNode owner ) + { + m_currentOwner = owner; + bool value = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalPragmas; + NodeUtils.DrawPropertyGroup( ref value, AdditionalPragmasStr, DrawMainBody, DrawButtons ); + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalPragmas = value; + + } + + void DrawButtons() + { + EditorGUILayout.Separator(); + + // Add keyword + if( GUILayout.Button( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_additionalPragmas.Add( string.Empty ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove keyword + if( GUILayout.Button( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + if( m_additionalPragmas.Count > 0 ) + { + m_additionalPragmas.RemoveAt( m_additionalPragmas.Count - 1 ); + EditorGUI.FocusTextInControl( null ); + } + } + } + + void DrawMainBody() + { + EditorGUILayout.Separator(); + int itemCount = m_additionalPragmas.Count; + int markedToDelete = -1; + for( int i = 0; i < itemCount; i++ ) + { + EditorGUILayout.BeginHorizontal(); + { + EditorGUI.BeginChangeCheck(); + m_additionalPragmas[ i ] = EditorGUILayout.TextField( m_additionalPragmas[ i ] ); + if( EditorGUI.EndChangeCheck() ) + { + m_additionalPragmas[ i ] = UIUtils.RemoveShaderInvalidCharacters( m_additionalPragmas[ i ] ); + } + + // Add new port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_additionalPragmas.Insert( i + 1, string.Empty ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + markedToDelete = i; + } + } + EditorGUILayout.EndHorizontal(); + } + + if( markedToDelete > -1 ) + { + if( m_additionalPragmas.Count > markedToDelete ) + { + m_additionalPragmas.RemoveAt( markedToDelete ); + EditorGUI.FocusTextInControl( null ); + } + } + EditorGUILayout.Separator(); + EditorGUILayout.HelpBox( "Please add your pragmas without the #pragma keywords", MessageType.Info ); + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + int count = Convert.ToInt32( nodeParams[ index++ ] ); + for( int i = 0; i < count; i++ ) + { + m_additionalPragmas.Add( nodeParams[ index++ ] ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalPragmas.Count ); + for( int i = 0; i < m_additionalPragmas.Count; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_additionalPragmas[ i ] ); + } + } + + public void AddToDataCollector( ref MasterNodeDataCollector dataCollector ) + { + for( int i = 0; i < m_additionalPragmas.Count; i++ ) + { + if( !string.IsNullOrEmpty( m_additionalPragmas[ i ] ) ) + dataCollector.AddToPragmas( -1, m_additionalPragmas[ i ] ); + } + + for( int i = 0; i < m_outsidePragmas.Count; i++ ) + { + if( !string.IsNullOrEmpty( m_outsidePragmas[ i ] ) ) + dataCollector.AddToPragmas( -1, m_outsidePragmas[ i ] ); + } + } + + public void Destroy() + { + m_additionalPragmas.Clear(); + m_additionalPragmas = null; + m_currentOwner = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalPragmasHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalPragmasHelper.cs.meta new file mode 100644 index 00000000..3f245aaf --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalPragmasHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3153b4d10effd174988d75b84b12d281 +timeCreated: 1504515475 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalSurfaceOptionsHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalSurfaceOptionsHelper.cs new file mode 100644 index 00000000..cd3efae7 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalSurfaceOptionsHelper.cs @@ -0,0 +1,153 @@ +using System; +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + + [Serializable] + public class AdditionalSurfaceOptionsHelper + { + private const string AdditionalOptionsStr = " Additional Surface Options"; + + + private const float ShaderKeywordButtonLayoutWidth = 15; + private ParentNode m_currentOwner; + + [SerializeField] + private List<string> m_availableOptions = new List<string>(); + + public void Draw( ParentNode owner ) + { + m_currentOwner = owner; + bool value = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalSurfaceOptions; + NodeUtils.DrawPropertyGroup( ref value, AdditionalOptionsStr, DrawMainBody, DrawButtons ); + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedAdditionalSurfaceOptions = value; + } + + void DrawButtons() + { + EditorGUILayout.Separator(); + + // Add tag + if( GUILayout.Button( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_availableOptions.Add( string.Empty ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove tag + if( GUILayout.Button( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + if( m_availableOptions.Count > 0 ) + { + m_availableOptions.RemoveAt( m_availableOptions.Count - 1 ); + EditorGUI.FocusTextInControl( null ); + } + } + } + + void DrawMainBody() + { + EditorGUILayout.Separator(); + int itemCount = m_availableOptions.Count; + + if( itemCount == 0 ) + { + EditorGUILayout.HelpBox( "Your list is Empty!\nUse the plus button to add one.", MessageType.Info ); + } + + int markedToDelete = -1; + float originalLabelWidth = EditorGUIUtility.labelWidth; + for( int i = 0; i < itemCount; i++ ) + { + + EditorGUI.indentLevel += 1; + EditorGUIUtility.labelWidth = 62; + EditorGUILayout.BeginHorizontal(); + //Option + EditorGUI.BeginChangeCheck(); + m_availableOptions[ i ] = EditorGUILayout.TextField( "["+i+"] -", m_availableOptions[ i ] ); + if( EditorGUI.EndChangeCheck() ) + { + m_availableOptions[ i ] = UIUtils.RemoveShaderInvalidCharacters( m_availableOptions[ i ] ); + } + + EditorGUIUtility.labelWidth = originalLabelWidth; + + { + // Add new port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_availableOptions.Insert( i + 1, string.Empty ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + markedToDelete = i; + } + } + EditorGUILayout.EndHorizontal(); + EditorGUI.indentLevel -= 1; + } + + if( markedToDelete > -1 ) + { + if( m_availableOptions.Count > markedToDelete ) + { + m_availableOptions.RemoveAt( markedToDelete ); + EditorGUI.FocusTextInControl( null ); + } + } + EditorGUILayout.Separator(); + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + int count = Convert.ToInt32( nodeParams[ index++ ] ); + for( int i = 0; i < count; i++ ) + { + m_availableOptions.Add( nodeParams[ index++ ] ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + int optionsCount = m_availableOptions.Count; + IOUtils.AddFieldValueToString( ref nodeInfo, optionsCount ); + for( int i = 0; i < optionsCount; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_availableOptions[ i ].ToString() ); + } + } + + public void WriteToOptionalSurfaceOptions( ref string currentOptions ) + { + int tagsCount = m_availableOptions.Count; + if( tagsCount == 0 ) + return; + + string result = " "; + + for( int i = 0; i < tagsCount; i++ ) + { + result += m_availableOptions[ i ]; + if( i < tagsCount - 1 ) + { + result += " "; + } + } + currentOptions = currentOptions + result; + } + + public void Destroy() + { + m_availableOptions.Clear(); + m_availableOptions = null; + m_currentOwner = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalSurfaceOptionsHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalSurfaceOptionsHelper.cs.meta new file mode 100644 index 00000000..ccd630e4 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalSurfaceOptionsHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d830b2cc8bc5e174485077319135fc1e +timeCreated: 1528881842 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BillboardOpHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BillboardOpHelper.cs new file mode 100644 index 00000000..d1391d95 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BillboardOpHelper.cs @@ -0,0 +1,242 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +// Billboard based on: +// https://gist.github.com/renaudbedard/7a90ec4a5a7359712202 +using System; +using UnityEngine; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + public enum BillboardType + { + Cylindrical, + Spherical + } + + [Serializable] + public class BillboardOpHelper + { + public static readonly string BillboardTitleStr = " Billboard"; + public static readonly string BillboardTypeStr = "Type"; + public static readonly string BillboardRotIndStr = "Ignore Rotation"; + + public static readonly string[] BillboardCylindricalInstructions = { "//Calculate new billboard vertex position and normal", + "float3 upCamVec = float3( 0, 1, 0 )"}; + + public static readonly string[] BillboardSphericalInstructions = { "//Calculate new billboard vertex position and normal", + "float3 upCamVec = normalize ( UNITY_MATRIX_V._m10_m11_m12 )"}; + + + public static readonly string[] BillboardCommonInstructions = { "float3 forwardCamVec = -normalize ( UNITY_MATRIX_V._m20_m21_m22 )", + "float3 rightCamVec = normalize( UNITY_MATRIX_V._m00_m01_m02 )", + "float4x4 rotationCamMatrix = float4x4( rightCamVec, 0, upCamVec, 0, forwardCamVec, 0, 0, 0, 0, 1 )", + "{0} = normalize( mul( float4( {0} , 0 ), rotationCamMatrix )).xyz"}; + + public static readonly string[] BillboardRotDependent = { "//This unfortunately must be made to take non-uniform scaling into account", + "//Transform to world coords, apply rotation and transform back to local", + "{0} = mul( {1} , unity_ObjectToWorld ){2}", + "{0} = mul( {1} , rotationCamMatrix ){2}", + "{0} = mul( {1} , unity_WorldToObject ){2}"}; + + + public static readonly string[] BillboardRotIndependent = { "{0}.x *= length( unity_ObjectToWorld._m00_m10_m20 )", + "{0}.y *= length( unity_ObjectToWorld._m01_m11_m21 )", + "{0}.z *= length( unity_ObjectToWorld._m02_m12_m22 )", + "{0} = mul( {0}, rotationCamMatrix )", + "{0}.xyz += unity_ObjectToWorld._m03_m13_m23", + "//Need to nullify rotation inserted by generated surface shader", + "{0} = mul( unity_WorldToObject, {0} )"}; + + + + public static readonly string[] BillboardHDRotDependent = { "//This unfortunately must be made to take non-uniform scaling into account", + "//Transform to world coords, apply rotation and transform back to local", + "{0} = mul( {1} , GetObjectToWorldMatrix() ){2}", + "{0} = mul( {1} , rotationCamMatrix ){2}", + "{0} = mul( {1} , GetWorldToObjectMatrix() ){2}"}; + + + public static readonly string[] BillboardHDRotIndependent = { "{0}.x *= length( GetObjectToWorldMatrix()._m00_m10_m20 )", + "{0}.y *= length( GetObjectToWorldMatrix()._m01_m11_m21 )", + "{0}.z *= length( GetObjectToWorldMatrix()._m02_m12_m22 )", + "{0} = mul( {0}, rotationCamMatrix )", + "{0}.xyz += GetObjectToWorldMatrix()._m03_m13_m23", + "//Need to nullify rotation inserted by generated surface shader", + "{0} = mul( GetWorldToObjectMatrix(), {0} )"}; + + + [SerializeField] + private bool m_isBillboard = false; + + [SerializeField] + private BillboardType m_billboardType = BillboardType.Cylindrical; + + [SerializeField] + private bool m_rotationIndependent = false; + + public void Draw( ParentNode owner ) + { + bool visible = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedVertexOptions; + bool enabled = m_isBillboard; + NodeUtils.DrawPropertyGroup( owner, ref visible, ref m_isBillboard, BillboardTitleStr, () => + { + m_billboardType = (BillboardType)owner.EditorGUILayoutEnumPopup( BillboardTypeStr, m_billboardType ); + m_rotationIndependent = owner.EditorGUILayoutToggle( BillboardRotIndStr, m_rotationIndependent ); + } ); + + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedVertexOptions = visible; + if( m_isBillboard != enabled ) + { + UIUtils.RequestSave(); + } + } + public void FillDataCollectorWithInternalData( ref MasterNodeDataCollector dataCollector ) + { + if( m_isBillboard ) + { + FillDataCollector( ref dataCollector, m_billboardType, m_rotationIndependent, "v.vertex", "v.normal", false ); + } + } + // This should be called after the Vertex Offset and Vertex Normal ports are analised + public static void FillDataCollector( ref MasterNodeDataCollector dataCollector, BillboardType billboardType, bool rotationIndependent, string vertexPosValue, string vertexNormalValue, bool vertexIsFloat3 ) + { + switch( billboardType ) + { + case BillboardType.Cylindrical: + { + for( int i = 0; i < BillboardCylindricalInstructions.Length; i++ ) + { + dataCollector.AddVertexInstruction( BillboardCylindricalInstructions[ i ] + ( dataCollector.IsTemplate ? ";" : string.Empty ), -1, true ); + } + } + break; + + case BillboardType.Spherical: + { + for( int i = 0; i < BillboardCylindricalInstructions.Length; i++ ) + { + dataCollector.AddVertexInstruction( BillboardSphericalInstructions[ i ] + ( dataCollector.IsTemplate ? ";" : string.Empty ), -1, true ); + } + } + break; + } + + for( int i = 0; i < BillboardCommonInstructions.Length; i++ ) + { + string value = ( i == 3 ) ? string.Format( BillboardCommonInstructions[ i ], vertexNormalValue ) : BillboardCommonInstructions[ i ]; + dataCollector.AddVertexInstruction( value + ( dataCollector.IsTemplate ? ";" : string.Empty ), -1, true ); + } + + if( rotationIndependent ) + { + for( int i = 0; i < BillboardRotIndependent.Length; i++ ) + { + string value = string.Empty; + if( dataCollector.IsTemplate && dataCollector.TemplateDataCollectorInstance.CurrentSRPType != TemplateSRPType.BuiltIn ) + { + value = ( i != 5 ) ? string.Format( BillboardHDRotIndependent[ i ], vertexPosValue ) : BillboardHDRotIndependent[ i ]; + } + else + { + value = ( i != 5 ) ? string.Format( BillboardRotIndependent[ i ], vertexPosValue ) : BillboardRotIndependent[ i ]; + } + dataCollector.AddVertexInstruction( value + ( dataCollector.IsTemplate ? ";" : string.Empty ), -1, true ); + } + } + else + { + string vertexPosConverted = vertexIsFloat3 ? string.Format( "float4({0},0)", vertexPosValue ) : vertexPosValue; + for( int i = 0; i < BillboardRotDependent.Length; i++ ) + { + string value = string.Empty; + if( dataCollector.IsTemplate && dataCollector.TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD ) + { + value = ( i > 1 ) ? string.Format( BillboardHDRotDependent[ i ], vertexPosValue, vertexPosConverted, ( vertexIsFloat3 ? ".xyz" : string.Empty ) ) : BillboardHDRotDependent[ i ]; + } + else + { + value = ( i > 1 ) ? string.Format( BillboardRotDependent[ i ], vertexPosValue, vertexPosConverted, ( vertexIsFloat3 ? ".xyz" : string.Empty ) ) : BillboardRotDependent[ i ]; + } + dataCollector.AddVertexInstruction( value + ( dataCollector.IsTemplate ? ";" : string.Empty ), -1, true ); + } + } + } + + public string[] GetInternalMultilineInstructions() + { + // This method is only used on Surface ... no HD variation is needed + return GetMultilineInstructions( m_billboardType, m_rotationIndependent, "v.vertex", "v.normal" ); + } + + public static string[] GetMultilineInstructions( BillboardType billboardType, bool rotationIndependent, string vertexPosValue, string vertexNormalValue ) + { + // This method is only used on Surface ... no HD variation is needed + List<string> body = new List<string>(); + switch( billboardType ) + { + case BillboardType.Cylindrical: + { + for( int i = 0; i < BillboardCylindricalInstructions.Length; i++ ) + { + body.Add( BillboardCylindricalInstructions[ i ] ); + } + } + break; + + case BillboardType.Spherical: + { + for( int i = 0; i < BillboardCylindricalInstructions.Length; i++ ) + { + body.Add( BillboardSphericalInstructions[ i ] ); + } + } + break; + } + + for( int i = 0; i < BillboardCommonInstructions.Length; i++ ) + { + string value = ( i == 3 ) ? string.Format( BillboardCommonInstructions[ i ], vertexNormalValue ) : BillboardCommonInstructions[ i ]; + body.Add( value ); + } + + if( rotationIndependent ) + { + for( int i = 0; i < BillboardRotIndependent.Length; i++ ) + { + string value = ( i != 5 ) ? string.Format( BillboardRotIndependent[ i ], vertexPosValue ) : BillboardRotIndependent[ i ]; + body.Add( value ); + } + } + else + { + for( int i = 0; i < BillboardRotDependent.Length; i++ ) + { + string value = ( i > 1 ) ? string.Format( BillboardRotDependent[ i ], vertexPosValue ) : BillboardRotDependent[ i ]; + body.Add( value ); + } + } + return body.ToArray(); + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + m_isBillboard = Convert.ToBoolean( nodeParams[ index++ ] ); + m_billboardType = (BillboardType)Enum.Parse( typeof( BillboardType ), nodeParams[ index++ ] ); + if( UIUtils.CurrentShaderVersion() > 11007 ) + { + m_rotationIndependent = Convert.ToBoolean( nodeParams[ index++ ] ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_isBillboard ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_billboardType ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_rotationIndependent ); + } + + public bool IsBillboard { get { return m_isBillboard; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BillboardOpHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BillboardOpHelper.cs.meta new file mode 100644 index 00000000..812475f8 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BillboardOpHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 837b906a268babc49ac733573c5b3394 +timeCreated: 1489159407 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BlendOpsHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BlendOpsHelper.cs new file mode 100644 index 00000000..989ace5f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BlendOpsHelper.cs @@ -0,0 +1,447 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + public enum AvailableBlendFactor + { + One = 1, + Zero = 0, + SrcColor = 3, + SrcAlpha = 5, + DstColor = 2, + DstAlpha = 7, + OneMinusSrcColor = 6, + OneMinusSrcAlpha = 10, + OneMinusDstColor = 4, + OneMinusDstAlpha = 8, + SrcAlphaSaturate = 9 + }; + + public enum AvailableBlendOps + { + OFF = 0, + Add, + Sub, + RevSub, + Min, + Max, + //Direct X11 only + LogicalClear, + LogicalSet, + LogicalCopy, + LogicalCopyInverted, + LogicalNoop, + LogicalInvert, + LogicalAnd, + LogicalNand, + LogicalOr, + LogicalNor, + LogicalXor, + LogicalEquiv, + LogicalAndReverse, + LogicalAndInverted, + LogicalOrReverse, + LogicalOrInverted + }; + + public class CommonBlendTypes + { + public string Name; + public AvailableBlendFactor SourceFactor; + public AvailableBlendFactor DestFactor; + public CommonBlendTypes( string name, AvailableBlendFactor sourceFactor, AvailableBlendFactor destFactor ) + { + Name = name; + SourceFactor = sourceFactor; + DestFactor = destFactor; + } + } + + [Serializable] + public class BlendOpsHelper + { + public static readonly string[] BlendOpsLabels = + { + "<OFF>", + "Add", + "Sub", + "RevSub", + "Min", + "Max", + "LogicalClear ( DX11.1 Only )", + "LogicalSet ( DX11.1 Only )", + "LogicalCopy ( DX11.1 Only )", + "LogicalCopyInverted ( DX11.1 Only )", + "LogicalNoop ( DX11.1 Only )", + "LogicalInvert ( DX11.1 Only )", + "LogicalAnd ( DX11.1 Only )", + "LogicalNand ( DX11.1 Only )", + "LogicalOr ( DX11.1 Only )", + "LogicalNor ( DX11.1 Only )", + "LogicalXor ( DX11.1 Only )", + "LogicalEquiv ( DX11.1 Only )", + "LogicalAndReverse ( DX11.1 Only )", + "LogicalAndInverted ( DX11.1 Only )", + "LogicalOrReverse ( DX11.1 Only )", + "LogicalOrInverted ( DX11.1 Only )" + }; + + private const string BlendModesRGBStr = "Blend RGB"; + private const string BlendModesAlphaStr = "Blend Alpha"; + + private const string BlendOpsRGBStr = "Blend Op RGB"; + private const string BlendOpsAlphaStr = "Blend Op Alpha"; + + private const string SourceFactorStr = "Src"; + private const string DstFactorStr = "Dst"; + + private const string SingleBlendFactorStr = "Blend {0} {1}"; + private const string SeparateBlendFactorStr = "Blend {0} {1} , {2} {3}"; + + private const string SingleBlendOpStr = "BlendOp {0}"; + private const string SeparateBlendOpStr = "BlendOp {0} , {1}"; + + private string[] m_commonBlendTypesArr; + private List<CommonBlendTypes> m_commonBlendTypes = new List<CommonBlendTypes> { new CommonBlendTypes("<OFF>", AvailableBlendFactor.Zero, AvailableBlendFactor.Zero ), + new CommonBlendTypes("Custom", AvailableBlendFactor.Zero, AvailableBlendFactor.Zero ) , + new CommonBlendTypes("Alpha Blend", AvailableBlendFactor.SrcAlpha, AvailableBlendFactor.OneMinusSrcAlpha ) , + new CommonBlendTypes("Premultiplied", AvailableBlendFactor.One, AvailableBlendFactor.OneMinusSrcAlpha ), + new CommonBlendTypes("Additive", AvailableBlendFactor.One, AvailableBlendFactor.One ), + new CommonBlendTypes("Soft Additive", AvailableBlendFactor.OneMinusDstColor, AvailableBlendFactor.One ), + new CommonBlendTypes("Multiplicative", AvailableBlendFactor.DstColor, AvailableBlendFactor.Zero ), + new CommonBlendTypes("2x Multiplicative", AvailableBlendFactor.DstColor, AvailableBlendFactor.SrcColor ), + new CommonBlendTypes("Particle Additive", AvailableBlendFactor.SrcAlpha, AvailableBlendFactor.One ),}; + + [SerializeField] + private bool m_enabled = false; + + // Blend Factor + // RGB + [SerializeField] + private int m_currentIndex = 0; + + + [SerializeField] + private InlineProperty m_sourceFactorRGB = new InlineProperty( 0 ); + + [SerializeField] + private InlineProperty m_destFactorRGB = new InlineProperty( 0 ); + + // Alpha + [SerializeField] + private int m_currentAlphaIndex = 0; + + [SerializeField] + private InlineProperty m_sourceFactorAlpha = new InlineProperty( 0 ); + + [SerializeField] + private InlineProperty m_destFactorAlpha = new InlineProperty( 0 ); + + //Blend Ops + [SerializeField] + private bool m_blendOpEnabled = false; + + [SerializeField] + private InlineProperty m_blendOpRGB = new InlineProperty( 0 ); + + [SerializeField] + private InlineProperty m_blendOpAlpha = new InlineProperty( 0 ); + + public BlendOpsHelper() + { + m_commonBlendTypesArr = new string[ m_commonBlendTypes.Count ]; + for( int i = 0; i < m_commonBlendTypesArr.Length; i++ ) + { + m_commonBlendTypesArr[ i ] = m_commonBlendTypes[ i ].Name; + } + } + + public void Draw( UndoParentNode owner, bool customBlendAvailable ) + { + m_enabled = customBlendAvailable; + + // RGB + EditorGUI.BeginChangeCheck(); + m_currentIndex = owner.EditorGUILayoutPopup( BlendModesRGBStr, m_currentIndex, m_commonBlendTypesArr ); + if( EditorGUI.EndChangeCheck() ) + { + if( m_currentIndex > 1 ) + { + m_sourceFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].SourceFactor; + m_sourceFactorRGB.SetInlineNodeValue(); + + m_destFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].DestFactor; + m_destFactorRGB.SetInlineNodeValue(); + } + } + EditorGUI.BeginDisabledGroup( m_currentIndex == 0 ); + + EditorGUI.BeginChangeCheck(); + float cached = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 40; + + EditorGUILayout.BeginHorizontal(); + AvailableBlendFactor tempCast = (AvailableBlendFactor)m_sourceFactorRGB.IntValue; + m_sourceFactorRGB.CustomDrawer( ref owner, ( x ) => { tempCast = (AvailableBlendFactor)x.EditorGUILayoutEnumPopup( SourceFactorStr, tempCast ); }, SourceFactorStr ); + m_sourceFactorRGB.IntValue = (int)tempCast; + EditorGUI.indentLevel--; + EditorGUIUtility.labelWidth = 25; + tempCast = (AvailableBlendFactor)m_destFactorRGB.IntValue; + m_destFactorRGB.CustomDrawer( ref owner, ( x ) => { tempCast = (AvailableBlendFactor)x.EditorGUILayoutEnumPopup( DstFactorStr, tempCast ); }, DstFactorStr ); + m_destFactorRGB.IntValue = (int)tempCast; + EditorGUI.indentLevel++; + EditorGUILayout.EndHorizontal(); + + EditorGUIUtility.labelWidth = cached; + if( EditorGUI.EndChangeCheck() ) + { + CheckRGBIndex(); + } + + // Both these tests should be removed on a later stage + // ASE v154dev004 changed AvailableBlendOps.OFF value from -1 to 0 + // If importing the new package into an already opened ASE window makes + // hotcode to preserve the -1 value on these variables + if( m_blendOpRGB.FloatValue < 0 ) + m_blendOpRGB.FloatValue = 0; + + if( m_blendOpAlpha.FloatValue < 0 ) + m_blendOpAlpha.FloatValue = 0; + + EditorGUI.BeginChangeCheck(); + //AvailableBlendOps tempOpCast = (AvailableBlendOps)m_blendOpRGB.IntValue; + m_blendOpRGB.CustomDrawer( ref owner, ( x ) => { m_blendOpRGB.IntValue = x.EditorGUILayoutPopup( BlendOpsRGBStr, m_blendOpRGB.IntValue, BlendOpsLabels ); }, BlendOpsRGBStr ); + //m_blendOpRGB.IntValue = (int)tempOpCast; + if( EditorGUI.EndChangeCheck() ) + { + m_blendOpEnabled = ( !m_blendOpRGB.Active && m_blendOpRGB.IntValue > -1 ) || ( m_blendOpRGB.Active && m_blendOpRGB.NodeId > -1 );//AvailableBlendOps.OFF; + m_blendOpRGB.SetInlineNodeValue(); + } + + EditorGUI.EndDisabledGroup(); + + // Alpha + EditorGUILayout.Separator(); + + EditorGUI.BeginChangeCheck(); + m_currentAlphaIndex = owner.EditorGUILayoutPopup( BlendModesAlphaStr, m_currentAlphaIndex, m_commonBlendTypesArr ); + if( EditorGUI.EndChangeCheck() ) + { + if( m_currentAlphaIndex > 0 ) + { + m_sourceFactorAlpha.IntValue = (int)m_commonBlendTypes[ m_currentAlphaIndex ].SourceFactor; + m_sourceFactorAlpha.SetInlineNodeValue(); + + m_destFactorAlpha.IntValue = (int)m_commonBlendTypes[ m_currentAlphaIndex ].DestFactor; + m_destFactorAlpha.SetInlineNodeValue(); + } + } + EditorGUI.BeginDisabledGroup( m_currentAlphaIndex == 0 ); + + EditorGUI.BeginChangeCheck(); + cached = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 40; + EditorGUILayout.BeginHorizontal(); + tempCast = (AvailableBlendFactor)m_sourceFactorAlpha.IntValue; + m_sourceFactorAlpha.CustomDrawer( ref owner, ( x ) => { tempCast = (AvailableBlendFactor)x.EditorGUILayoutEnumPopup( SourceFactorStr, tempCast ); }, SourceFactorStr ); + m_sourceFactorAlpha.IntValue = (int)tempCast; + EditorGUI.indentLevel--; + EditorGUIUtility.labelWidth = 25; + tempCast = (AvailableBlendFactor)m_destFactorAlpha.IntValue; + m_destFactorAlpha.CustomDrawer( ref owner, ( x ) => { tempCast = (AvailableBlendFactor)x.EditorGUILayoutEnumPopup( DstFactorStr, tempCast ); }, DstFactorStr ); + m_destFactorAlpha.IntValue = (int)tempCast; + EditorGUI.indentLevel++; + EditorGUILayout.EndHorizontal(); + EditorGUIUtility.labelWidth = cached; + + if( EditorGUI.EndChangeCheck() ) + { + CheckAlphaIndex(); + } + EditorGUI.BeginChangeCheck(); + //tempOpCast = (AvailableBlendOps)m_blendOpAlpha.IntValue; + m_blendOpAlpha.CustomDrawer( ref owner, ( x ) => { m_blendOpAlpha.IntValue = x.EditorGUILayoutPopup( BlendOpsAlphaStr, m_blendOpAlpha.IntValue, BlendOpsLabels ); }, BlendOpsAlphaStr ); + //m_blendOpAlpha.IntValue = (int)tempOpCast; + if( EditorGUI.EndChangeCheck() ) + { + m_blendOpAlpha.SetInlineNodeValue(); + } + EditorGUI.EndDisabledGroup(); + EditorGUILayout.Separator(); + } + + void CheckRGBIndex() + { + int count = m_commonBlendTypes.Count; + m_currentIndex = 1; + for( int i = 1; i < count; i++ ) + { + if( m_commonBlendTypes[ i ].SourceFactor == (AvailableBlendFactor)m_sourceFactorRGB.IntValue && m_commonBlendTypes[ i ].DestFactor == (AvailableBlendFactor)m_destFactorRGB.IntValue ) + { + m_currentIndex = i; + return; + } + } + + } + + void CheckAlphaIndex() + { + int count = m_commonBlendTypes.Count; + m_currentAlphaIndex = 1; + for( int i = 1; i < count; i++ ) + { + if( m_commonBlendTypes[ i ].SourceFactor == (AvailableBlendFactor)m_sourceFactorAlpha.IntValue && m_commonBlendTypes[ i ].DestFactor == (AvailableBlendFactor)m_destFactorAlpha.IntValue ) + { + m_currentAlphaIndex = i; + if( m_currentAlphaIndex > 0 && m_currentIndex == 0 ) + m_currentIndex = 1; + return; + } + } + + if( m_currentAlphaIndex > 0 && m_currentIndex == 0 ) + m_currentIndex = 1; + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + m_currentIndex = Convert.ToInt32( nodeParams[ index++ ] ); + if( UIUtils.CurrentShaderVersion() > 15103 ) + { + m_sourceFactorRGB.ReadFromString( ref index, ref nodeParams ); + m_destFactorRGB.ReadFromString( ref index, ref nodeParams ); + } + else + { + m_sourceFactorRGB.IntValue = (int)(AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), nodeParams[ index++ ] ); + m_destFactorRGB.IntValue = (int)(AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), nodeParams[ index++ ] ); + } + + m_currentAlphaIndex = Convert.ToInt32( nodeParams[ index++ ] ); + if( UIUtils.CurrentShaderVersion() > 15103 ) + { + m_sourceFactorAlpha.ReadFromString( ref index, ref nodeParams ); + m_destFactorAlpha.ReadFromString( ref index, ref nodeParams ); + + m_blendOpRGB.ReadFromString( ref index, ref nodeParams ); + m_blendOpAlpha.ReadFromString( ref index, ref nodeParams ); + if( UIUtils.CurrentShaderVersion() < 15404 ) + { + // Now BlendOps enum starts at 0 and not -1 + m_blendOpRGB.FloatValue += 1; + m_blendOpAlpha.FloatValue += 1; + } + } + else + { + m_sourceFactorAlpha.IntValue = (int)(AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), nodeParams[ index++ ] ); + m_destFactorAlpha.IntValue = (int)(AvailableBlendFactor)Enum.Parse( typeof( AvailableBlendFactor ), nodeParams[ index++ ] ); + m_blendOpRGB.IntValue = (int)(AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), nodeParams[ index++ ] ); + m_blendOpAlpha.IntValue = (int)(AvailableBlendOps)Enum.Parse( typeof( AvailableBlendOps ), nodeParams[ index++ ] ); + } + + m_enabled = ( m_currentIndex > 0 || m_currentAlphaIndex > 0 ); + m_blendOpEnabled = ( !m_blendOpRGB.Active && m_blendOpRGB.IntValue > -1 ) || ( m_blendOpRGB.Active && m_blendOpRGB.NodeId > -1 ); + } + + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentIndex ); + m_sourceFactorRGB.WriteToString( ref nodeInfo ); + m_destFactorRGB.WriteToString( ref nodeInfo ); + + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentAlphaIndex ); + m_sourceFactorAlpha.WriteToString( ref nodeInfo ); + m_destFactorAlpha.WriteToString( ref nodeInfo ); + + m_blendOpRGB.WriteToString( ref nodeInfo ); + m_blendOpAlpha.WriteToString( ref nodeInfo ); + } + + public void SetBlendOpsFromBlendMode( AlphaMode mode, bool customBlendAvailable ) + { + switch( mode ) + { + case AlphaMode.Transparent: + m_currentIndex = 2; + m_sourceFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].SourceFactor; + m_destFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].DestFactor; + break; + case AlphaMode.Masked: + case AlphaMode.Translucent: + m_currentIndex = 0; + break; + case AlphaMode.Premultiply: + m_currentIndex = 3; + m_sourceFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].SourceFactor; + m_destFactorRGB.IntValue = (int)m_commonBlendTypes[ m_currentIndex ].DestFactor; + break; + } + m_enabled = customBlendAvailable; + } + + public string CreateBlendOps() + { + + string result = "\t\t" + CurrentBlendFactor + "\n"; + if( m_blendOpEnabled ) + { + result += "\t\t" + CurrentBlendOp + "\n"; + } + return result; + } + + public string CurrentBlendRGB { get { return m_commonBlendTypes[ m_currentIndex ].Name; } } + + public string CurrentBlendFactorSingle { get { return string.Format( SingleBlendFactorStr, m_sourceFactorRGB.GetValueOrProperty( ( (AvailableBlendFactor)m_sourceFactorRGB.IntValue ).ToString() ), m_destFactorRGB.GetValueOrProperty( ( (AvailableBlendFactor)m_destFactorRGB.IntValue ).ToString() ) ); } } + //public string CurrentBlendFactorSingleAlpha { get { return string.Format(SeparateBlendFactorStr, m_sourceFactorRGB, m_destFactorRGB, m_sourceFactorAlpha, m_destFactorAlpha); } } + public string CurrentBlendFactorSeparate + { + get + { + string src = ( m_currentIndex > 0 ? m_sourceFactorRGB.GetValueOrProperty( ( (AvailableBlendFactor)m_sourceFactorRGB.IntValue ).ToString() ) : AvailableBlendFactor.One.ToString() ); + string dst = ( m_currentIndex > 0 ? m_destFactorRGB.GetValueOrProperty( ( (AvailableBlendFactor)m_destFactorRGB.IntValue ).ToString() ) : AvailableBlendFactor.Zero.ToString() ); + string srca = m_sourceFactorAlpha.GetValueOrProperty( ( (AvailableBlendFactor)m_sourceFactorAlpha.IntValue ).ToString() ); + string dsta = m_destFactorAlpha.GetValueOrProperty( ( (AvailableBlendFactor)m_destFactorAlpha.IntValue ).ToString() ); + return string.Format( SeparateBlendFactorStr, src, dst, srca, dsta ); + } + } + public string CurrentBlendFactor { get { return ( ( m_currentAlphaIndex > 0 ) ? CurrentBlendFactorSeparate : CurrentBlendFactorSingle ); } } + + public string CurrentBlendOpSingle + { + get + { + string value = m_blendOpRGB.GetValueOrProperty( ( (AvailableBlendOps)m_blendOpRGB.IntValue ).ToString() ); + if( value.Equals( ( AvailableBlendOps.OFF ).ToString() ) ) + return string.Empty; + + return string.Format( SingleBlendOpStr, value ); + } + } + public string CurrentBlendOpSeparate + { + get + { + string rgbValue = m_blendOpRGB.GetValueOrProperty( ( (AvailableBlendOps)m_blendOpRGB.IntValue ).ToString() ); + + if( rgbValue.Equals( ( AvailableBlendOps.OFF ).ToString() )) + rgbValue = "Add"; + + string alphaValue = m_blendOpAlpha.GetValueOrProperty( ( (AvailableBlendOps)m_blendOpAlpha.IntValue ).ToString() ); + return string.Format( SeparateBlendOpStr, ( m_currentIndex > 0 ? rgbValue : AvailableBlendOps.Add.ToString() ), alphaValue ); + } + } + public string CurrentBlendOp { get { return ( ( m_currentAlphaIndex > 0 && m_blendOpAlpha.GetValueOrProperty( ( (AvailableBlendOps)m_blendOpAlpha.IntValue ).ToString() ) != AvailableBlendOps.OFF.ToString() ) ? CurrentBlendOpSeparate : CurrentBlendOpSingle ); } } + + public bool Active { get { return m_enabled && ( m_currentIndex > 0 || m_currentAlphaIndex > 0 ); } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BlendOpsHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BlendOpsHelper.cs.meta new file mode 100644 index 00000000..95ea7b51 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BlendOpsHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8b59649a5f829e24cb4de8c1a715f8b4 +timeCreated: 1485530925 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CodeGenerationData.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CodeGenerationData.cs new file mode 100644 index 00000000..5245c9f4 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CodeGenerationData.cs @@ -0,0 +1,24 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +namespace AmplifyShaderEditor +{ + [System.Serializable] + public class CodeGenerationData + { + [SerializeField] + public bool IsActive; + [SerializeField] + public string Name; + [SerializeField] + public string Value; + + public CodeGenerationData( string name, string value ) + { + IsActive = false; + Name = name; + Value = value; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CodeGenerationData.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CodeGenerationData.cs.meta new file mode 100644 index 00000000..2c5d759e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CodeGenerationData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7a47d8101acb2e94d95016b69a1c2e41 +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ColorMaskHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ColorMaskHelper.cs new file mode 100644 index 00000000..2280c9f0 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ColorMaskHelper.cs @@ -0,0 +1,107 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +using System; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + class ColorMaskHelper + { + private GUIContent ColorMaskContent = new GUIContent( "Color Mask", "Sets color channel writing mask, turning all off makes the object completely invisible\nDefault: RGBA" ); + private readonly char[] m_colorMaskChar = { 'R', 'G', 'B', 'A' }; + + private GUIStyle m_leftToggleColorMask; + private GUIStyle m_middleToggleColorMask; + private GUIStyle m_rightToggleColorMask; + + + [SerializeField] + private bool[] m_colorMask = { true, true, true, true }; + + [SerializeField] + private InlineProperty m_inlineMask = new InlineProperty(); + + public void Draw( UndoParentNode owner ) + { + m_inlineMask.CustomDrawer( ref owner, DrawColorMaskControls, ColorMaskContent.text ); + } + + private void DrawColorMaskControls( UndoParentNode owner ) + { + if( m_leftToggleColorMask == null || m_leftToggleColorMask.normal.background == null ) + { + m_leftToggleColorMask = GUI.skin.GetStyle( "miniButtonLeft" ); + } + + if( m_middleToggleColorMask == null || m_middleToggleColorMask.normal.background == null ) + { + m_middleToggleColorMask = GUI.skin.GetStyle( "miniButtonMid" ); + } + + if( m_rightToggleColorMask == null || m_rightToggleColorMask.normal.background == null ) + { + m_rightToggleColorMask = GUI.skin.GetStyle( "miniButtonRight" ); + } + + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField( ColorMaskContent, GUILayout.Width( 90 ) ); + + m_colorMask[ 0 ] = owner.GUILayoutToggle( m_colorMask[ 0 ], "R", m_leftToggleColorMask ); + m_colorMask[ 1 ] = owner.GUILayoutToggle( m_colorMask[ 1 ], "G", m_middleToggleColorMask ); + m_colorMask[ 2 ] = owner.GUILayoutToggle( m_colorMask[ 2 ], "B", m_middleToggleColorMask ); + m_colorMask[ 3 ] = owner.GUILayoutToggle( m_colorMask[ 3 ], "A", m_rightToggleColorMask ); + + EditorGUILayout.EndHorizontal(); + } + + public void BuildColorMask( ref string ShaderBody, bool customBlendAvailable ) + { + int count = 0; + string colorMask = string.Empty; + for( int i = 0; i < m_colorMask.Length; i++ ) + { + if( m_colorMask[ i ] ) + { + count++; + colorMask += m_colorMaskChar[ i ]; + } + } + + if( ( count != m_colorMask.Length && customBlendAvailable ) || m_inlineMask.Active ) + { + MasterNode.AddRenderState( ref ShaderBody, "ColorMask", m_inlineMask.GetValueOrProperty( ( ( count == 0 ) ? "0" : colorMask ) ) ); + } + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + for( int i = 0; i < m_colorMask.Length; i++ ) + { + m_colorMask[ i ] = Convert.ToBoolean( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 14501 ) + m_inlineMask.ReadFromString( ref index, ref nodeParams ); + } + + public void WriteToString( ref string nodeInfo ) + { + for( int i = 0; i < m_colorMask.Length; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_colorMask[ i ] ); + } + + m_inlineMask.WriteToString( ref nodeInfo ); + } + + public void Destroy() + { + m_leftToggleColorMask = null; + m_middleToggleColorMask = null; + m_rightToggleColorMask = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ColorMaskHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ColorMaskHelper.cs.meta new file mode 100644 index 00000000..69c24b06 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ColorMaskHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bf65efd881afd1b4cbd2b27f3f17251b +timeCreated: 1488903773 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CustomTagsHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CustomTagsHelper.cs new file mode 100644 index 00000000..11a3ee49 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CustomTagsHelper.cs @@ -0,0 +1,436 @@ +using System; +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class CustomTagData + { + private const string TagFormat = "\"{0}\"=\"{1}\""; + public string TagName; + public string TagValue; + public int TagId = -1; + public bool TagFoldout = true; + + [SerializeField] + private TemplateSpecialTags m_specialTag = TemplateSpecialTags.None; + [SerializeField] + private RenderType m_renderType = RenderType.Opaque; + [SerializeField] + private RenderQueue m_renderQueue = RenderQueue.Geometry; + [SerializeField] + private int m_renderQueueOffset = 0; + + public CustomTagData() + { + TagName = string.Empty; + TagValue = string.Empty; + m_specialTag = TemplateSpecialTags.None; + m_renderType = RenderType.Opaque; + m_renderQueue = RenderQueue.Geometry; + m_renderQueueOffset = 0; + } + + public CustomTagData( CustomTagData other ) + { + TagName = other.TagName; + TagValue = other.TagValue; + TagId = other.TagId; + TagFoldout = other.TagFoldout; + + m_specialTag = other.m_specialTag; + m_renderType = other.m_renderType; + m_renderQueue = other.m_renderQueue; + m_renderQueueOffset = other.m_renderQueueOffset; + } + + public void SetTagValue( params string[] value ) + { + TagValue = value[ 0 ]; + switch( m_specialTag ) + { + case TemplateSpecialTags.RenderType: + { + if( !TemplateHelperFunctions.StringToRenderType.TryGetValue( value[ 0 ], out m_renderType ) ) + { + m_renderType = RenderType.Custom; + TagValue = value[ 0 ]; + } + } + break; + case TemplateSpecialTags.Queue: + { + if( value.Length == 2 ) + { + m_renderQueue = TemplateHelperFunctions.StringToRenderQueue[ value[ 0 ] ]; + int.TryParse( value[ 1 ], out m_renderQueueOffset ); + } + else + { + int indexPlus = value[ 0 ].IndexOf( '+' ); + if( indexPlus > 0 ) + { + string[] args = value[ 0 ].Split( '+' ); + m_renderQueue = TemplateHelperFunctions.StringToRenderQueue[ args[ 0 ] ]; + int.TryParse( args[ 1 ], out m_renderQueueOffset ); + } + else + { + int indexMinus = value[ 0 ].IndexOf( '-' ); + if( indexMinus > 0 ) + { + string[] args = value[ 0 ].Split( '-' ); + m_renderQueue = TemplateHelperFunctions.StringToRenderQueue[ args[ 0 ] ]; + int.TryParse( args[ 1 ], out m_renderQueueOffset ); + m_renderQueueOffset *= -1; + } + else + { + m_renderQueue = TemplateHelperFunctions.StringToRenderQueue[ value[ 0 ] ]; + m_renderQueueOffset = 0; + } + } + } + BuildQueueTagValue(); + } + break; + + } + } + + void CheckSpecialTag() + { + if( TagName.Equals( Constants.RenderTypeHelperStr ) ) + { + m_specialTag = TemplateSpecialTags.RenderType; + if( !TemplateHelperFunctions.StringToRenderType.TryGetValue( TagValue, out m_renderType )) + { + m_renderType = RenderType.Custom; + } + } + else if( TagName.Equals( Constants.RenderQueueHelperStr ) ) + { + m_specialTag = TemplateSpecialTags.Queue; + SetTagValue( TagValue ); + } + else + { + m_specialTag = TemplateSpecialTags.None; + } + } + + public CustomTagData( string name, string value, int id ) + { + TagName = name; + TagValue = value; + TagId = id; + CheckSpecialTag(); + } + + //Used on Template based shaders loading + public CustomTagData( string data, int id ) + { + TagId = id; + string[] arr = data.Split( IOUtils.VALUE_SEPARATOR ); + if( arr.Length > 1 ) + { + TagName = arr[ 0 ]; + TagValue = arr[ 1 ]; + } + + if( arr.Length > 2 ) + { + m_specialTag = (TemplateSpecialTags)Enum.Parse( typeof( TemplateSpecialTags ), arr[ 2 ] ); + switch( m_specialTag ) + { + case TemplateSpecialTags.RenderType: + { + if( !TemplateHelperFunctions.StringToRenderType.TryGetValue( TagValue, out m_renderType ) ) + { + m_renderType = RenderType.Custom; + } + } + break; + case TemplateSpecialTags.Queue: + { + if( arr.Length == 4 ) + { + m_renderQueue = (RenderQueue)Enum.Parse( typeof( RenderQueue ), TagValue ); + int.TryParse( arr[ 3 ], out m_renderQueueOffset ); + } + BuildQueueTagValue(); + } + break; + } + } + else if( UIUtils.CurrentShaderVersion() < 15600 ) + { + CheckSpecialTag(); + } + } + + //Used on Standard Surface shaders loading + public CustomTagData( string data ) + { + string[] arr = data.Split( IOUtils.VALUE_SEPARATOR ); + if( arr.Length > 1 ) + { + TagName = arr[ 0 ]; + TagValue = arr[ 1 ]; + } + } + + public override string ToString() + { + switch( m_specialTag ) + { + case TemplateSpecialTags.RenderType: + return TagName + IOUtils.VALUE_SEPARATOR + + ( RenderType != RenderType.Custom? RenderType.ToString(): TagValue ) + IOUtils.VALUE_SEPARATOR + + m_specialTag; + case TemplateSpecialTags.Queue: + return TagName + IOUtils.VALUE_SEPARATOR + + m_renderQueue.ToString() + IOUtils.VALUE_SEPARATOR + + m_specialTag + IOUtils.VALUE_SEPARATOR + + m_renderQueueOffset; + } + + return TagName + IOUtils.VALUE_SEPARATOR + TagValue; + } + + public string GenerateTag() + { + switch( m_specialTag ) + { + case TemplateSpecialTags.RenderType: + return string.Format( TagFormat, TagName, ( RenderType != RenderType.Custom ? RenderType.ToString() : TagValue ) ); + case TemplateSpecialTags.Queue: + case TemplateSpecialTags.None: + default: + return string.Format( TagFormat, TagName, TagValue ); + } + } + + public void BuildQueueTagValue() + { + TagValue = m_renderQueue.ToString(); + if( m_renderQueueOffset > 0 ) + { + TagValue += "+" + m_renderQueueOffset; + } + else if( m_renderQueueOffset < 0 ) + { + TagValue += m_renderQueueOffset; + } + } + + public TemplateSpecialTags SpecialTag + { + get { return m_specialTag; } + set + { + m_specialTag = value; + switch( value ) + { + case TemplateSpecialTags.RenderType: + { + //if( m_renderType != RenderType.Custom ) + // TagValue = m_renderType.ToString(); + } + break; + case TemplateSpecialTags.Queue: + { + BuildQueueTagValue(); + } + break; + } + } + } + + public RenderType RenderType + { + get { return m_renderType; } + set + { + m_renderType = value; + //if( m_renderType != RenderType.Custom ) + // TagValue = value.ToString(); + } + } + + public RenderQueue RenderQueue + { + get { return m_renderQueue; } + set { m_renderQueue = value; } + } + public int RenderQueueOffset + { + get { return m_renderQueueOffset; } + set { m_renderQueueOffset = value; } + } + + public bool IsValid { get { return ( !string.IsNullOrEmpty( TagValue ) && !string.IsNullOrEmpty( TagName ) ); } } + } + + [Serializable] + public class CustomTagsHelper + { + private const string CustomTagsStr = " Custom SubShader Tags"; + private const string TagNameStr = "Name"; + private const string TagValueStr = "Value"; + + private const float ShaderKeywordButtonLayoutWidth = 15; + private ParentNode m_currentOwner; + + [SerializeField] + private List<CustomTagData> m_availableTags = new List<CustomTagData>(); + + public void Draw( ParentNode owner ) + { + m_currentOwner = owner; + bool value = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedCustomTags; + NodeUtils.DrawPropertyGroup( ref value, CustomTagsStr, DrawMainBody, DrawButtons ); + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedCustomTags = value; + } + + void DrawButtons() + { + EditorGUILayout.Separator(); + + // Add tag + if( GUILayout.Button( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_availableTags.Add( new CustomTagData() ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove tag + if( GUILayout.Button( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + if( m_availableTags.Count > 0 ) + { + m_availableTags.RemoveAt( m_availableTags.Count - 1 ); + EditorGUI.FocusTextInControl( null ); + } + } + } + + void DrawMainBody() + { + EditorGUILayout.Separator(); + int itemCount = m_availableTags.Count; + + if( itemCount == 0 ) + { + EditorGUILayout.HelpBox( "Your list is Empty!\nUse the plus button to add one.", MessageType.Info ); + } + + int markedToDelete = -1; + float originalLabelWidth = EditorGUIUtility.labelWidth; + for( int i = 0; i < itemCount; i++ ) + { + m_availableTags[ i ].TagFoldout = m_currentOwner.EditorGUILayoutFoldout( m_availableTags[ i ].TagFoldout, string.Format( "[{0}] - {1}", i, m_availableTags[ i ].TagName ) ); + if( m_availableTags[ i ].TagFoldout ) + { + EditorGUI.indentLevel += 1; + EditorGUIUtility.labelWidth = 70; + //Tag Name + EditorGUI.BeginChangeCheck(); + m_availableTags[ i ].TagName = EditorGUILayout.TextField( TagNameStr, m_availableTags[ i ].TagName ); + if( EditorGUI.EndChangeCheck() ) + { + m_availableTags[ i ].TagName = UIUtils.RemoveShaderInvalidCharacters( m_availableTags[ i ].TagName ); + } + + //Tag Value + EditorGUI.BeginChangeCheck(); + m_availableTags[ i ].TagValue = EditorGUILayout.TextField( TagValueStr, m_availableTags[ i ].TagValue ); + if( EditorGUI.EndChangeCheck() ) + { + m_availableTags[ i ].TagValue = UIUtils.RemoveShaderInvalidCharacters( m_availableTags[ i ].TagValue ); + } + + EditorGUIUtility.labelWidth = originalLabelWidth; + + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Label( " " ); + // Add new port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_availableTags.Insert( i + 1, new CustomTagData() ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + markedToDelete = i; + } + } + EditorGUILayout.EndHorizontal(); + + EditorGUI.indentLevel -= 1; + } + + } + if( markedToDelete > -1 ) + { + if( m_availableTags.Count > markedToDelete ) + { + m_availableTags.RemoveAt( markedToDelete ); + EditorGUI.FocusTextInControl( null ); + } + } + EditorGUILayout.Separator(); + } + + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + int count = Convert.ToInt32( nodeParams[ index++ ] ); + for( int i = 0; i < count; i++ ) + { + m_availableTags.Add( new CustomTagData( nodeParams[ index++ ] ) ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + int tagsCount = m_availableTags.Count; + IOUtils.AddFieldValueToString( ref nodeInfo, tagsCount ); + for( int i = 0; i < tagsCount; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_availableTags[ i ].ToString() ); + } + } + + public string GenerateCustomTags() + { + int tagsCount = m_availableTags.Count; + string result = tagsCount == 0 ? string.Empty : " "; + + for( int i = 0; i < tagsCount; i++ ) + { + if( m_availableTags[ i ].IsValid ) + { + result += m_availableTags[ i ].GenerateTag(); + if( i < tagsCount - 1 ) + { + result += " "; + } + } + } + return result; + } + + public void Destroy() + { + m_availableTags.Clear(); + m_availableTags = null; + m_currentOwner = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CustomTagsHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CustomTagsHelper.cs.meta new file mode 100644 index 00000000..de6b426c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CustomTagsHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 5ed32be99aefda24483c9e3499a5cd23 +timeCreated: 1500400244 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/DependenciesHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/DependenciesHelper.cs new file mode 100644 index 00000000..915f173c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/DependenciesHelper.cs @@ -0,0 +1,210 @@ +using System; +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class DependenciesData + { + private string DependencyFormat = "Dependency \"{0}\"=\"{1}\"\n"; + public string DependencyName; + public string DependencyValue; + public bool DependencyFoldout = true; + + public DependenciesData() + { + DependencyName = string.Empty; + DependencyValue = string.Empty; + } + + public DependenciesData( string data ) + { + string[] arr = data.Split( IOUtils.VALUE_SEPARATOR ); + if( arr.Length > 1 ) + { + DependencyName = arr[ 0 ]; + DependencyValue = arr[ 1 ]; + } + } + + public override string ToString() + { + return DependencyName + IOUtils.VALUE_SEPARATOR + DependencyValue; + } + + public string GenerateDependency() + { + return string.Format( DependencyFormat, DependencyName, DependencyValue ); + } + + public bool IsValid { get { return ( !string.IsNullOrEmpty( DependencyValue ) && !string.IsNullOrEmpty( DependencyName ) ); } } + } + + [Serializable] + public class DependenciesHelper + { + private const string CustomDependencysStr = " Dependencies"; + private const string DependencyNameStr = "Name"; + private const string DependencyValueStr = "Value"; + + private const float ShaderKeywordButtonLayoutWidth = 15; + private ParentNode m_currentOwner; + + [SerializeField] + private List<DependenciesData> m_availableDependencies = new List<DependenciesData>(); + + public void Draw( ParentNode owner, bool isNested = false ) + { + m_currentOwner = owner; + bool value = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedDependencies; + if( isNested ) + { + NodeUtils.DrawNestedPropertyGroup( ref value, CustomDependencysStr, DrawMainBody, DrawButtons ); + } + else + { + NodeUtils.DrawPropertyGroup( ref value, CustomDependencysStr, DrawMainBody, DrawButtons ); + } + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedDependencies = value; + } + + void DrawButtons() + { + EditorGUILayout.Separator(); + + // Add Dependency + if( GUILayout.Button( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_availableDependencies.Add( new DependenciesData() ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove Dependency + if( GUILayout.Button( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + if( m_availableDependencies.Count > 0 ) + { + m_availableDependencies.RemoveAt( m_availableDependencies.Count - 1 ); + EditorGUI.FocusTextInControl( null ); + } + } + } + + void DrawMainBody() + { + EditorGUILayout.Separator(); + int itemCount = m_availableDependencies.Count; + + if( itemCount == 0 ) + { + EditorGUILayout.HelpBox( "Your list is Empty!\nUse the plus button to add one.", MessageType.Info ); + } + + int markedToDelete = -1; + float originalLabelWidth = EditorGUIUtility.labelWidth; + for( int i = 0; i < itemCount; i++ ) + { + m_availableDependencies[ i ].DependencyFoldout = m_currentOwner.EditorGUILayoutFoldout( m_availableDependencies[ i ].DependencyFoldout, string.Format( "[{0}] - {1}", i, m_availableDependencies[ i ].DependencyName ) ); + if( m_availableDependencies[ i ].DependencyFoldout ) + { + EditorGUI.indentLevel += 1; + EditorGUIUtility.labelWidth = 70; + //Dependency Name + EditorGUI.BeginChangeCheck(); + m_availableDependencies[ i ].DependencyName = EditorGUILayout.TextField( DependencyNameStr, m_availableDependencies[ i ].DependencyName ); + if( EditorGUI.EndChangeCheck() ) + { + m_availableDependencies[ i ].DependencyName = UIUtils.RemoveShaderInvalidCharacters( m_availableDependencies[ i ].DependencyName ); + } + + //Dependency Value + EditorGUI.BeginChangeCheck(); + m_availableDependencies[ i ].DependencyValue = EditorGUILayout.TextField( DependencyValueStr, m_availableDependencies[ i ].DependencyValue ); + if( EditorGUI.EndChangeCheck() ) + { + m_availableDependencies[ i ].DependencyValue = UIUtils.RemoveShaderInvalidCharacters( m_availableDependencies[ i ].DependencyValue ); + } + + EditorGUIUtility.labelWidth = originalLabelWidth; + + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Label( " " ); + // Add new port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_availableDependencies.Insert( i + 1, new DependenciesData() ); + EditorGUI.FocusTextInControl( null ); + } + + //Remove port + if( m_currentOwner.GUILayoutButton( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + markedToDelete = i; + } + } + EditorGUILayout.EndHorizontal(); + + EditorGUI.indentLevel -= 1; + } + + } + if( markedToDelete > -1 ) + { + if( m_availableDependencies.Count > markedToDelete ) + { + m_availableDependencies.RemoveAt( markedToDelete ); + EditorGUI.FocusTextInControl( null ); + } + } + EditorGUILayout.Separator(); + } + + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + int count = Convert.ToInt32( nodeParams[ index++ ] ); + for( int i = 0; i < count; i++ ) + { + m_availableDependencies.Add( new DependenciesData( nodeParams[ index++ ] ) ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + int dependencyCount = m_availableDependencies.Count; + IOUtils.AddFieldValueToString( ref nodeInfo, dependencyCount ); + for( int i = 0; i < dependencyCount; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_availableDependencies[ i ].ToString() ); + } + } + + public string GenerateDependencies() + { + int dependencyCount = m_availableDependencies.Count; + string result = dependencyCount == 0 ? string.Empty : "\n"; + UIUtils.ShaderIndentLevel++; + for( int i = 0; i < dependencyCount; i++ ) + { + if( m_availableDependencies[ i ].IsValid ) + { + result += UIUtils.ShaderIndentTabs + m_availableDependencies[ i ].GenerateDependency(); + } + } + UIUtils.ShaderIndentLevel--; + return result; + } + + public void Destroy() + { + m_availableDependencies.Clear(); + m_availableDependencies = null; + m_currentOwner = null; + } + + public bool HasDependencies { get { return m_availableDependencies.Count > 0; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/DependenciesHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/DependenciesHelper.cs.meta new file mode 100644 index 00000000..92e4d819 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/DependenciesHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2daff2983fe91ac43953017a8be984a7 +timeCreated: 1512404972 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FallbackPickerHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FallbackPickerHelper.cs new file mode 100644 index 00000000..6d006a96 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FallbackPickerHelper.cs @@ -0,0 +1,119 @@ +using System; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class FallbackPickerHelper : ScriptableObject + { + private const string FallbackFormat = "Fallback \"{0}\""; + private const string FallbackShaderStr = "Fallback"; + private const string ShaderPoputContext = "CONTEXT/ShaderPopup"; + + private Material m_dummyMaterial; + private MenuCommand m_dummyCommand; + + [SerializeField] + private string m_fallbackShader = string.Empty; + + public void Init() + { + hideFlags = HideFlags.HideAndDontSave; + m_dummyMaterial = null; + m_dummyCommand = null; + } + + public void Draw( ParentNode owner ) + { + EditorGUILayout.BeginHorizontal(); + m_fallbackShader = owner.EditorGUILayoutTextField( FallbackShaderStr, m_fallbackShader ); + if ( GUILayout.Button( string.Empty, UIUtils.InspectorPopdropdownFallback, GUILayout.Width( 17 ), GUILayout.Height( 19 ) ) ) + { + EditorGUI.FocusTextInControl( null ); + GUI.FocusControl( null ); + DisplayShaderContext( owner, GUILayoutUtility.GetRect( GUIContent.none, EditorStyles.popup ) ); + } + EditorGUILayout.EndHorizontal(); + } + + private void DisplayShaderContext( ParentNode node, Rect r ) + { + if ( m_dummyCommand == null ) + m_dummyCommand = new MenuCommand( this, 0 ); + + if ( m_dummyMaterial == null ) + m_dummyMaterial = new Material( Shader.Find( "Hidden/ASESShaderSelectorUnlit" ) ); + +#pragma warning disable 0618 + UnityEditorInternal.InternalEditorUtility.SetupShaderMenu( m_dummyMaterial ); +#pragma warning restore 0618 + EditorUtility.DisplayPopupMenu( r, ShaderPoputContext, m_dummyCommand ); + } + + private void OnSelectedShaderPopup( string command, Shader shader ) + { + if ( shader != null ) + { + UIUtils.MarkUndoAction(); + Undo.RecordObject( this, "Selected fallback shader" ); + m_fallbackShader = shader.name; + } + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + m_fallbackShader = nodeParams[ index++ ]; + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_fallbackShader ); + } + + public void Destroy() + { + GameObject.DestroyImmediate( m_dummyMaterial ); + m_dummyMaterial = null; + m_dummyCommand = null; + } + + public string TabbedFallbackShader + { + get + { + if( string.IsNullOrEmpty( m_fallbackShader ) ) + return string.Empty; + + return "\t" + string.Format( FallbackFormat, m_fallbackShader ) + "\n"; + } + } + + public string FallbackShader + { + get + { + if( string.IsNullOrEmpty( m_fallbackShader ) ) + return string.Empty; + + return string.Format( FallbackFormat, m_fallbackShader ); + } + } + + public string RawFallbackShader + { + get + { + return m_fallbackShader; + } + set + { + m_fallbackShader = value; + } + } + + + public bool Active { get { return !string.IsNullOrEmpty( m_fallbackShader ); } } + + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FallbackPickerHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FallbackPickerHelper.cs.meta new file mode 100644 index 00000000..2336aa83 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FallbackPickerHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: cd5a03cee1255ba438e2062d215b70b6 +timeCreated: 1490378537 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionInput.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionInput.cs new file mode 100644 index 00000000..a253a5a8 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionInput.cs @@ -0,0 +1,523 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Function Input", "Functions", "Function Input adds an input port to the shader function", NodeAvailabilityFlags = (int)NodeAvailability.ShaderFunction )] + public sealed class FunctionInput : ParentNode + { + private const string InputTypeStr = "Input Type"; + private readonly string[] m_inputValueTypes ={ "Int", + "Float", + "Vector2", + "Vector3", + "Vector4", + "Color", + "Matrix 3x3", + "Matrix 4x4", + "Sampler 1D", + "Sampler 2D", + "Sampler 3D", + "Sampler Cube"}; + + [SerializeField] + private int m_selectedInputTypeInt = 1; + + private WirePortDataType m_selectedInputType = WirePortDataType.FLOAT; + + [SerializeField] + private FunctionNode m_functionNode; + + [SerializeField] + private string m_inputName = "Input"; + + [SerializeField] + private bool m_autoCast = false; + + [SerializeField] + private int m_orderIndex = -1; + + private int m_typeId = -1; + + public bool m_ignoreConnection = false; + + public delegate string PortGeneration( ref MasterNodeDataCollector dataCollector, int index, ParentGraph graph ); + public PortGeneration OnPortGeneration = null; + + //Title editing + [SerializeField] + private string m_uniqueName; + + private bool m_isEditing; + private bool m_stopEditing; + private bool m_startEditing; + private double m_clickTime; + private double m_doubleClickTime = 0.3; + private Rect m_titleClickArea; + private bool m_showTitleWhenNotEditing = true; + + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue ); + m_inputPorts[ 0 ].AutoDrawInternalData = true; + //m_inputPorts[ 0 ].Visible = false; + AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + m_autoWrapProperties = true; + m_textLabelWidth = 100; + SetTitleText( m_inputName ); + UpdatePorts(); + SetAdditonalTitleText( "( " + m_inputValueTypes[ m_selectedInputTypeInt ] + " )" ); + m_previewShaderGUID = "04bc8e7b317dccb4d8da601680dd8140"; + } + + public override void SetPreviewInputs() + { + if( Fnode == null ) + { + m_ignoreConnection = false; + CheckSpherePreview(); + } + else + { + var input = Fnode.GetInput( this ); + if( input != null && ( !InputPorts[ 0 ].IsConnected || input.IsConnected ) ) + { + m_ignoreConnection = true; + InputPorts[ 0 ].PreparePortCacheID(); + Fnode.SetPreviewInput( input ); + if( input.ExternalReferences.Count > 0 ) + { + SpherePreview = Fnode.ContainerGraph.GetNode( input.ExternalReferences[ 0 ].NodeId ).SpherePreview; + } + else + { + SpherePreview = false; + } + PreviewMaterial.SetTexture( InputPorts[ 0 ].CachedPropertyId, input.InputPreviewTexture( Fnode.ContainerGraph ) ); + } + else + { + m_ignoreConnection = false; + CheckSpherePreview(); + } + } + + if( !m_ignoreConnection ) + base.SetPreviewInputs(); + + for( int i = 0; i < OutputPorts[ 0 ].ExternalReferences.Count; i++ ) + { + ContainerGraph.GetNode( OutputPorts[ 0 ].ExternalReferences[ i ].NodeId ).OnNodeChange(); + } + + if( m_typeId == -1 ) + m_typeId = Shader.PropertyToID( "_Type" ); + + if( m_inputPorts[ 0 ].DataType == WirePortDataType.FLOAT || m_inputPorts[ 0 ].DataType == WirePortDataType.INT ) + PreviewMaterial.SetInt( m_typeId, 1 ); + else if( m_inputPorts[ 0 ].DataType == WirePortDataType.FLOAT2 ) + PreviewMaterial.SetInt( m_typeId, 2 ); + else if( m_inputPorts[ 0 ].DataType == WirePortDataType.FLOAT3 ) + PreviewMaterial.SetInt( m_typeId, 3 ); + else + PreviewMaterial.SetInt( m_typeId, 0 ); + + } + + public override bool RecursivePreviewUpdate( Dictionary<string, bool> duplicatesDict = null ) + { + if( duplicatesDict == null ) + { + duplicatesDict = ContainerGraph.ParentWindow.VisitedChanged; + } + + for( int i = 0; i < InputPorts.Count; i++ ) + { + ParentNode outNode = null; + if( Fnode != null ) + { + var input = Fnode.GetInput( this ); + if( input.ExternalReferences.Count > 0 ) + { + outNode = Fnode.ContainerGraph.GetNode( input.ExternalReferences[ 0 ].NodeId ); + } + else if( InputPorts[ i ].ExternalReferences.Count > 0 ) + { + outNode = ContainerGraph.GetNode( InputPorts[ i ].ExternalReferences[ 0 ].NodeId ); + } + } + else + { + if( InputPorts[ i ].ExternalReferences.Count > 0 ) + { + outNode = ContainerGraph.GetNode( InputPorts[ i ].ExternalReferences[ 0 ].NodeId ); + } + } + if( outNode != null ) + { + if( !duplicatesDict.ContainsKey( outNode.OutputId ) ) + { + bool result = outNode.RecursivePreviewUpdate(); + if( result ) + PreviewIsDirty = true; + } + else if( duplicatesDict[ outNode.OutputId ] ) + { + PreviewIsDirty = true; + } + } + } + + bool needsUpdate = PreviewIsDirty; + RenderNodePreview(); + if( !duplicatesDict.ContainsKey( OutputId ) ) + duplicatesDict.Add( OutputId, needsUpdate ); + return needsUpdate; + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + UIUtils.RegisterFunctionInputNode( this ); + if( m_nodeAttribs != null ) + m_uniqueName = m_nodeAttribs.Name + UniqueId; + } + + public override void Destroy() + { + base.Destroy(); + OnPortGeneration = null; + UIUtils.UnregisterFunctionInputNode( this ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + if( AutoCast ) + { + m_inputPorts[ 0 ].MatchPortToConnection(); + SetIntTypeFromPort(); + UpdatePorts(); + SetAdditonalTitleText( "( " + m_inputValueTypes[ m_selectedInputTypeInt ] + " )" ); + } + } + + public override void OnConnectedOutputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( portId, otherNodeId, otherPortId, name, type ); + if( AutoCast ) + { + m_inputPorts[ 0 ].MatchPortToConnection(); + SetIntTypeFromPort(); + UpdatePorts(); + SetAdditonalTitleText( "( " + m_inputValueTypes[ m_selectedInputTypeInt ] + " )" ); + } + } + + public void SetIntTypeFromPort() + { + switch( m_inputPorts[ 0 ].DataType ) + { + case WirePortDataType.INT: m_selectedInputTypeInt = 0; break; + default: + case WirePortDataType.FLOAT: m_selectedInputTypeInt = 1; break; + case WirePortDataType.FLOAT2: m_selectedInputTypeInt = 2; break; + case WirePortDataType.FLOAT3: m_selectedInputTypeInt = 3; break; + case WirePortDataType.FLOAT4: m_selectedInputTypeInt = 4; break; + case WirePortDataType.COLOR: m_selectedInputTypeInt = 5; break; + case WirePortDataType.FLOAT3x3: m_selectedInputTypeInt = 6; break; + case WirePortDataType.FLOAT4x4: m_selectedInputTypeInt = 7; break; + case WirePortDataType.SAMPLER1D: m_selectedInputTypeInt = 8; break; + case WirePortDataType.SAMPLER2D: m_selectedInputTypeInt = 9; break; + case WirePortDataType.SAMPLER3D: m_selectedInputTypeInt = 10; break; + case WirePortDataType.SAMPLERCUBE: m_selectedInputTypeInt = 11; break; + } + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + // Custom Editable Title + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 ) + { + if( !m_isEditing && ( ( !ContainerGraph.ParentWindow.MouseInteracted && drawInfo.CurrentEventType == EventType.MouseDown && m_titleClickArea.Contains( drawInfo.MousePosition ) ) ) ) + { + if( ( EditorApplication.timeSinceStartup - m_clickTime ) < m_doubleClickTime ) + m_startEditing = true; + else + GUI.FocusControl( null ); + m_clickTime = EditorApplication.timeSinceStartup; + } + else if( m_isEditing && ( ( drawInfo.CurrentEventType == EventType.MouseDown && !m_titleClickArea.Contains( drawInfo.MousePosition ) ) || !EditorGUIUtility.editingTextField ) ) + { + m_stopEditing = true; + } + + if( m_isEditing || m_startEditing ) + { + EditorGUI.BeginChangeCheck(); + GUI.SetNextControlName( m_uniqueName ); + m_inputName = EditorGUITextField( m_titleClickArea, string.Empty, m_inputName, UIUtils.GetCustomStyle( CustomStyle.NodeTitle ) ); + if( EditorGUI.EndChangeCheck() ) + { + SetTitleText( m_inputName ); + UIUtils.UpdateFunctionInputData( UniqueId, m_inputName ); + } + + if( m_startEditing ) + EditorGUI.FocusTextInControl( m_uniqueName ); + + } + + if( drawInfo.CurrentEventType == EventType.Repaint ) + { + if( m_startEditing ) + { + m_startEditing = false; + m_isEditing = true; + } + + if( m_stopEditing ) + { + m_stopEditing = false; + m_isEditing = false; + GUI.FocusControl( null ); + } + } + + + } + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + // RUN LAYOUT CHANGES AFTER TITLES CHANGE + base.OnNodeLayout( drawInfo ); + m_titleClickArea = m_titlePos; + m_titleClickArea.height = Constants.NODE_HEADER_HEIGHT; + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if( !m_isVisible ) + return; + + // Fixed Title ( only renders when not editing ) + if( m_showTitleWhenNotEditing && !m_isEditing && !m_startEditing && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 ) + { + GUI.Label( m_titleClickArea, m_content, UIUtils.GetCustomStyle( CustomStyle.NodeTitle ) ); + } + } + + public override void OnNodeDoubleClicked( Vector2 currentMousePos2D ) + { + if( currentMousePos2D.y - m_globalPosition.y > ( Constants.NODE_HEADER_HEIGHT + Constants.NODE_HEADER_EXTRA_HEIGHT ) * ContainerGraph.ParentWindow.CameraDrawInfo.InvertedZoom ) + { + ContainerGraph.ParentWindow.ParametersWindow.IsMaximized = !ContainerGraph.ParentWindow.ParametersWindow.IsMaximized; + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUILayout.BeginVertical(); + EditorGUI.BeginChangeCheck(); + m_inputName = EditorGUILayoutTextField( "Name", m_inputName ); + if( EditorGUI.EndChangeCheck() ) + { + SetTitleText( m_inputName ); + UIUtils.UpdateFunctionInputData( UniqueId, m_inputName ); + } + EditorGUI.BeginChangeCheck(); + m_selectedInputTypeInt = EditorGUILayoutPopup( InputTypeStr, m_selectedInputTypeInt, m_inputValueTypes ); + if( EditorGUI.EndChangeCheck() ) + { + UpdatePorts(); + SetAdditonalTitleText( "( " + m_inputValueTypes[ m_selectedInputTypeInt ] + " )" ); + } + + m_autoCast = EditorGUILayoutToggle( "Auto Cast", m_autoCast ); + + EditorGUILayout.Separator(); + if( !m_inputPorts[ 0 ].IsConnected && m_inputPorts[ 0 ].ValidInternalData ) + { + m_inputPorts[ 0 ].ShowInternalData( this, true, "Default Value" ); + } + + + EditorGUILayout.EndVertical(); + } + + void UpdatePorts() + { + //switch( m_inputPorts[ 0 ].DataType ) + //{ + // case WirePortDataType.INT: m_selectedInputTypeInt = 0; break; + // default: + // case WirePortDataType.FLOAT: m_selectedInputTypeInt = 1; break; + // case WirePortDataType.FLOAT2: m_selectedInputTypeInt = 2; break; + // case WirePortDataType.FLOAT3: m_selectedInputTypeInt = 3; break; + + // //case 2: m_selectedInputType = WirePortDataType.FLOAT2; break; + // //case 3: m_selectedInputType = WirePortDataType.FLOAT3; break; + // //case 4: m_selectedInputType = WirePortDataType.FLOAT4; break; + // //case 5: m_selectedInputType = WirePortDataType.COLOR; break; + // //case 6: m_selectedInputType = WirePortDataType.FLOAT3x3; break; + // //case 7: m_selectedInputType = WirePortDataType.FLOAT4x4; break; + // //case 8: m_selectedInputType = WirePortDataType.SAMPLER1D; break; + // //case 9: m_selectedInputType = WirePortDataType.SAMPLER2D; break; + // //case 10: m_selectedInputType = WirePortDataType.SAMPLER3D; break; + // //case 11: m_selectedInputType = WirePortDataType.SAMPLERCUBE; break; + //} + + switch( m_selectedInputTypeInt ) + { + case 0: m_selectedInputType = WirePortDataType.INT; break; + default: + case 1: m_selectedInputType = WirePortDataType.FLOAT; break; + case 2: m_selectedInputType = WirePortDataType.FLOAT2; break; + case 3: m_selectedInputType = WirePortDataType.FLOAT3; break; + case 4: m_selectedInputType = WirePortDataType.FLOAT4; break; + case 5: m_selectedInputType = WirePortDataType.COLOR; break; + case 6: m_selectedInputType = WirePortDataType.FLOAT3x3; break; + case 7: m_selectedInputType = WirePortDataType.FLOAT4x4; break; + case 8: m_selectedInputType = WirePortDataType.SAMPLER1D; break; + case 9: m_selectedInputType = WirePortDataType.SAMPLER2D; break; + case 10: m_selectedInputType = WirePortDataType.SAMPLER3D; break; + case 11: m_selectedInputType = WirePortDataType.SAMPLERCUBE; break; + } + + ChangeInputType( m_selectedInputType, false ); + + //This node doesn't have any restrictions but changing types should be restricted to prevent invalid connections + m_outputPorts[ 0 ].ChangeTypeWithRestrictions( m_selectedInputType, PortCreateRestriction( m_selectedInputType ) ); + m_sizeIsDirty = true; + } + + public int PortCreateRestriction( WirePortDataType dataType ) + { + int restrictions = 0; + WirePortDataType[] types = null; + switch( dataType ) + { + case WirePortDataType.OBJECT: + break; + case WirePortDataType.FLOAT: + case WirePortDataType.FLOAT2: + case WirePortDataType.FLOAT3: + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + case WirePortDataType.INT: + { + types = new WirePortDataType[] { WirePortDataType.FLOAT, WirePortDataType.FLOAT2, WirePortDataType.FLOAT3, WirePortDataType.FLOAT4, WirePortDataType.COLOR, WirePortDataType.INT, WirePortDataType.OBJECT }; + } + break; + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + { + types = new WirePortDataType[] { WirePortDataType.FLOAT3x3, WirePortDataType.FLOAT4x4, WirePortDataType.OBJECT }; + } + break; + case WirePortDataType.SAMPLER1D: + case WirePortDataType.SAMPLER2D: + case WirePortDataType.SAMPLER3D: + case WirePortDataType.SAMPLERCUBE: + { + types = new WirePortDataType[] { WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE, WirePortDataType.OBJECT }; + } + break; + default: + break; + } + + if( types != null ) + { + for( int i = 0; i < types.Length; i++ ) + { + restrictions = restrictions | (int)types[ i ]; + } + } + + return restrictions; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_outputPorts[ outputId ].IsLocalValue( dataCollector.PortCategory ) ) + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + + string result = string.Empty; + if( OnPortGeneration != null ) + result = OnPortGeneration( ref dataCollector, m_orderIndex, ContainerGraph.ParentWindow.CustomGraph ); + else + result = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + + if( m_outputPorts[ outputId ].ConnectionCount > 1 ) + RegisterLocalVariable( outputId, result, ref dataCollector ); + else + m_outputPorts[ outputId ].SetLocalValue( result, dataCollector.PortCategory ); + + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_inputName ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedInputTypeInt ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_orderIndex ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autoCast ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_inputName = GetCurrentParam( ref nodeParams ); + m_selectedInputTypeInt = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_orderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_autoCast = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + + SetTitleText( m_inputName ); + UpdatePorts(); + SetAdditonalTitleText( "( " + m_inputValueTypes[ m_selectedInputTypeInt ] + " )" ); + } + + public WirePortDataType SelectedInputType + { + get { return m_selectedInputType; } + } + + public string InputName + { + get { return m_inputName; } + } + + public int OrderIndex + { + get { return m_orderIndex; } + set { m_orderIndex = value; } + } + + public bool AutoCast + { + get { return m_autoCast; } + set { m_autoCast = value; } + } + + public FunctionNode Fnode + { + get { return m_functionNode; } + set { m_functionNode = value; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionInput.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionInput.cs.meta new file mode 100644 index 00000000..c5aa5505 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionInput.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 64064ea01705e084cbe00a3bbeef2c3d +timeCreated: 1491927259 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionNode.cs new file mode 100644 index 00000000..de297c2e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionNode.cs @@ -0,0 +1,1236 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +//#define ADD_SHADER_FUNCTION_HEADERS + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System; +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Function Node", "Functions", "Function Node", KeyCode.None, false, 0, int.MaxValue, typeof( AmplifyShaderFunction ) )] + public class FunctionNode : ParentNode + { + [SerializeField] + private AmplifyShaderFunction m_function; + + [SerializeField] + private ParentGraph m_functionGraph; + + [SerializeField] + private int m_functionGraphId = -1; + + [SerializeField] + private List<FunctionInput> m_allFunctionInputs; + private Dictionary<int, FunctionInput> m_allFunctionInputsDict = new Dictionary<int, FunctionInput>(); + + [SerializeField] + private List<FunctionOutput> m_allFunctionOutputs; + private Dictionary<int, FunctionOutput> m_allFunctionOutputsDict = new Dictionary<int, FunctionOutput>(); + + [SerializeField] + private List<FunctionSwitch> m_allFunctionSwitches; + private Dictionary<int, FunctionSwitch> m_allFunctionSwitchesDict = new Dictionary<int, FunctionSwitch>(); + + [SerializeField] + private ReordenatorNode m_reordenator; + + [SerializeField] + private string m_filename; + + [SerializeField] + private string m_headerTitle = string.Empty; + + [SerializeField] + private int m_orderIndex; + + [SerializeField] + private string m_functionCheckSum; + + [SerializeField] + private string m_functionGUID = string.Empty; + + //[SerializeField] + //private List<string> m_includes = new List<string>(); + + //[SerializeField] + //private List<string> m_pragmas = new List<string>(); + + [SerializeField] + private List<AdditionalDirectiveContainer> m_directives = new List<AdditionalDirectiveContainer>(); + + private bool m_parametersFoldout = true; + [SerializeField] + private ParentGraph m_outsideGraph = null; + + [SerializeField] + private FunctionOutput m_mainPreviewNode; + + bool m_portsChanged = false; + //[SerializeField] + bool m_initialGraphDraw = false; + + private bool m_refreshIdsRequired = false; + + public string[] ReadOptionsHelper = new string[] { }; + + private bool m_lateRefresh = false; + + private Dictionary<int, bool> m_duplicatesBuffer = new Dictionary<int, bool>(); + string LastLine( string text ) + { + string[] lines = text.Replace( "\r", "" ).Split( '\n' ); + return lines[ lines.Length - 1 ]; + } + + public void CommonInit( AmplifyShaderFunction function, int uniqueId ) + { + SetBaseUniqueId( uniqueId ); + + if( function == null ) + return; + + m_refreshIdsRequired = UIUtils.IsLoading && ( UIUtils.CurrentShaderVersion() < 14004 ); + + m_function = function; + + if( Function.FunctionName.Length > 1 ) + { + SetTitleText( GraphContextMenu.AddSpacesToSentence( Function.FunctionName ) ); + } + else + { + SetTitleText( Function.FunctionName ); + } + m_tooltipText = Function.Description; + m_hasTooltipLink = false; + if( m_functionGraph == null ) + { + //m_functionGraph = new ParentGraph(); + m_functionGraph = CreateInstance<ParentGraph>(); + m_functionGraph.Init(); + m_functionGraph.ParentWindow = ContainerGraph.ParentWindow; + } + + if( string.IsNullOrEmpty( m_functionGUID ) ) + { + m_functionGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_function ) ); + } + + m_functionGraphId = Mathf.Max( m_functionGraphId, ContainerGraph.ParentWindow.GraphCount ); + ContainerGraph.ParentWindow.GraphCount = m_functionGraphId + 1; + m_functionGraph.SetGraphId( m_functionGraphId ); + + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + + AmplifyShaderEditorWindow.LoadFromMeta( ref m_functionGraph, ContainerGraph.ParentWindow.ContextMenuInstance, Function.FunctionInfo ); + //m_functionCheckSum = LastLine( m_function.FunctionInfo ); + m_functionCheckSum = AssetDatabase.GetAssetDependencyHash( AssetDatabase.GetAssetPath( m_function ) ).ToString(); + List<PropertyNode> propertyList = UIUtils.PropertyNodesList(); + m_allFunctionInputs = UIUtils.FunctionInputList(); + m_allFunctionOutputs = UIUtils.FunctionOutputList(); + m_allFunctionSwitches = UIUtils.FunctionSwitchList(); + + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + + m_allFunctionInputs.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + m_allFunctionOutputs.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + m_allFunctionSwitches.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + + int inputCount = m_allFunctionInputs.Count; + for( int i = 0; i < inputCount; i++ ) + { + if( m_refreshIdsRequired ) + { + AddInputPort( m_allFunctionInputs[ i ].SelectedInputType, false, m_allFunctionInputs[ i ].InputName ); + } + else + { + AddInputPort( m_allFunctionInputs[ i ].SelectedInputType, false, m_allFunctionInputs[ i ].InputName, -1, MasterNodePortCategory.Fragment, m_allFunctionInputs[ i ].UniqueId ); + } + InputPortSwitchRestriction( m_inputPorts[ i ] ); + + if( !m_allFunctionInputs[ i ].InputPorts[ 0 ].IsConnected ) + { + m_inputPorts[ i ].AutoDrawInternalData = true; + m_inputPorts[ i ].InternalData = m_allFunctionInputs[ i ].InputPorts[ 0 ].InternalData; + } + m_allFunctionInputs[ i ].Fnode = this; + } + + int outputCount = m_allFunctionOutputs.Count; + FunctionOutput first = null; + for( int i = 0; i < outputCount; i++ ) + { + if( i == 0 ) + first = m_allFunctionOutputs[ i ]; + + if( m_allFunctionOutputs[ i ].PreviewNode ) + { + m_mainPreviewNode = m_allFunctionOutputs[ i ]; + } + + if( m_refreshIdsRequired ) + { + AddOutputPort( m_allFunctionOutputs[ i ].AutoOutputType, m_allFunctionOutputs[ i ].OutputName ); + } + else + { + AddOutputPort( m_allFunctionOutputs[ i ].AutoOutputType, m_allFunctionOutputs[ i ].OutputName, m_allFunctionOutputs[ i ].UniqueId ); + } + OutputPortSwitchRestriction( m_outputPorts[ i ] ); + } + + // make sure to hide the ports properly + CheckPortVisibility(); + + if( m_mainPreviewNode == null ) + m_mainPreviewNode = first; + + //create reordenator to main graph + bool inside = false; + if( ContainerGraph.ParentWindow.CustomGraph != null ) + inside = true; + + if( /*hasConnectedProperties*/propertyList.Count > 0 ) + { + m_reordenator = ScriptableObject.CreateInstance<ReordenatorNode>(); + m_reordenator.Init( "_" + Function.FunctionName, Function.FunctionName, propertyList, false ); + m_reordenator.OrderIndex = m_orderIndex; + m_reordenator.HeaderTitle = Function.FunctionName; + m_reordenator.IsInside = inside; + } + + if( m_reordenator != null ) + { + cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = null; + UIUtils.RegisterPropertyNode( m_reordenator ); + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + + if( inside ) + { + UIUtils.RegisterPropertyNode( m_reordenator ); + } + } + + m_textLabelWidth = 120; + + UIUtils.RegisterFunctionNode( this ); + + m_previewShaderGUID = "aca70c900c50c004e8ef0b47c4fac4d4"; + m_useInternalPortData = false; + m_selectedLocation = function.PreviewPosition; + UIUtils.CurrentWindow.OutsideGraph.OnLODMasterNodesAddedEvent += OnLODMasterNodesAddedEvent; + } + + public InputPort GetInput( FunctionInput input ) + { + int index = m_allFunctionInputs.FindIndex( ( x ) => { return x.Equals( input ); } ); + if( index >= 0 ) + return InputPorts[ index ]; + else + return null; + } + + private void OnLODMasterNodesAddedEvent( int lod ) + { + AddShaderFunctionDirectivesInternal( lod ); + } + + public void SetPreviewInput( InputPort input ) + { + if( !HasPreviewShader || !m_initialized ) + return; + + if( input.IsConnected && input.InputNodeHasPreview( ContainerGraph ) ) + { + input.SetPreviewInputTexture( ContainerGraph ); + } + else + { + input.SetPreviewInputValue( ContainerGraph ); + } + } + + public override bool RecursivePreviewUpdate( Dictionary<string, bool> duplicatesDict = null ) + { + if( duplicatesDict == null ) + { + duplicatesDict = ContainerGraph.ParentWindow.VisitedChanged; + } + + if( m_allFunctionOutputs == null || m_allFunctionOutputs.Count == 0 ) + return false; + + for( int i = 0; i < m_allFunctionOutputs.Count; i++ ) + { + ParentNode outNode = m_allFunctionOutputs[ i ]; + if( outNode != null ) + { + if( !duplicatesDict.ContainsKey( outNode.OutputId ) ) + { + bool result = outNode.RecursivePreviewUpdate(); + if( result ) + PreviewIsDirty = true; + } + else if( duplicatesDict[ outNode.OutputId ] ) + { + PreviewIsDirty = true; + } + } + } + + bool needsUpdate = PreviewIsDirty; + RenderNodePreview(); + if( !duplicatesDict.ContainsKey( OutputId ) ) + duplicatesDict.Add( OutputId, needsUpdate ); + return needsUpdate; + } + + public override void RenderNodePreview() + { + if( m_outputPorts == null ) + return; + + if( !PreviewIsDirty && !m_continuousPreviewRefresh ) + return; + + // this is in the wrong place?? + if( m_drawPreviewAsSphere != m_mainPreviewNode.SpherePreview ) + { + m_drawPreviewAsSphere = m_mainPreviewNode.SpherePreview; + OnNodeChange(); + } + + int count = m_outputPorts.Count; + for( int i = 0; i < count; i++ ) + { + m_outputPorts[ i ].OutputPreviewTexture = m_allFunctionOutputs[ i ].PreviewTexture; + } + + if( PreviewIsDirty ) + FinishPreviewRender = true; + + PreviewIsDirty = false; + } + + public override RenderTexture PreviewTexture + { + get + { + if( m_mainPreviewNode != null ) + return m_mainPreviewNode.PreviewTexture; + else + return base.PreviewTexture; + } + } + + private void AddShaderFunctionDirectivesInternal( int lod ) + { + List<TemplateMultiPassMasterNode> nodes = ContainerGraph.ParentWindow.OutsideGraph.GetMultiPassMasterNodes( lod ); + int count = nodes.Count; + for( int i = 0; i < count; i++ ) + { + nodes[ i ].PassModule.AdditionalDirectives.AddShaderFunctionItems( OutputId, Function.AdditionalDirectives.DirectivesList ); + } + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + if( Function == null ) + return; + + //Debug.Log( "RefreshExternalReferences " + m_function.FunctionName + " " + UIUtils.CurrentWindow.IsShaderFunctionWindow ); + + Function.UpdateDirectivesList(); + + MasterNode masterNode = UIUtils.CurrentWindow.OutsideGraph.CurrentMasterNode; + StandardSurfaceOutputNode surface = masterNode as StandardSurfaceOutputNode; + + + + if( surface != null ) + { + //for( int i = 0; i < Function.AdditionalIncludes.IncludeList.Count; i++ ) + //{ + // //ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalIncludes.OutsideList.Add( Function.AdditionalIncludes.IncludeList[ i ] ); + // ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalDirectives.AddShaderFunctionItem( AdditionalLineType.Include, Function.AdditionalIncludes.IncludeList[ i ] ); + // m_includes.Add( Function.AdditionalIncludes.IncludeList[ i ] ); + //} + + //for( int i = 0; i < Function.AdditionalPragmas.PragmaList.Count; i++ ) + //{ + // //ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalPragmas.OutsideList.Add( Function.AdditionalPragmas.PragmaList[ i ] ); + // ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalDirectives.AddShaderFunctionItem(AdditionalLineType.Pragma, Function.AdditionalPragmas.PragmaList[ i ] ); + // m_pragmas.Add( Function.AdditionalPragmas.PragmaList[ i ] ); + //} + surface.AdditionalDirectives.AddShaderFunctionItems( OutputId, Function.AdditionalDirectives.DirectivesList ); + } + else + { + if( ContainerGraph.ParentWindow.OutsideGraph.MultiPassMasterNodes.Count > 0 ) + { + for( int lod = -1; lod < ContainerGraph.ParentWindow.OutsideGraph.LodMultiPassMasternodes.Count; lod++ ) + { + AddShaderFunctionDirectivesInternal( lod ); + } + } + else + { + // Assuring that we're not editing a Shader Function, as directives setup is not needed there + if( !UIUtils.CurrentWindow.IsShaderFunctionWindow ) + { + // This function is nested inside a shader function itself and this method + // was called before the main output node was created. + // This is possible since all nodes RefreshExternalReferences(...) are called at the end + // of a LoadFromMeta + // Need to delay this setup to after all nodes are loaded to then setup the directives + m_lateRefresh = true; + return; + } + } + + } + m_directives.AddRange( Function.AdditionalDirectives.DirectivesList ); + + if( m_refreshIdsRequired ) + { + m_refreshIdsRequired = false; + int inputCount = m_inputPorts.Count; + for( int i = 0; i < inputCount; i++ ) + { + m_inputPorts[ i ].ChangePortId( m_allFunctionInputs[ i ].UniqueId ); + } + + int outputCount = m_outputPorts.Count; + for( int i = 0; i < outputCount; i++ ) + { + m_outputPorts[ i ].ChangePortId( m_allFunctionOutputs[ i ].UniqueId ); + } + } + + if( ContainerGraph.ParentWindow.CurrentGraph != m_functionGraph ) + ContainerGraph.ParentWindow.CurrentGraph.InstancePropertyCount += m_functionGraph.InstancePropertyCount; + + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + + if( ReadOptionsHelper.Length > 2 ) + { + for( int i = 1; i < ReadOptionsHelper.Length; i += 2 ) + { + int optionId = Convert.ToInt32( ReadOptionsHelper[ i ] ); + int optionValue = Convert.ToInt32( ReadOptionsHelper[ i + 1 ] ); + for( int j = 0; j < m_allFunctionSwitches.Count; j++ ) + { + if( m_allFunctionSwitches[ j ].UniqueId == optionId ) + { + m_allFunctionSwitches[ j ].SetCurrentSelectedInput( optionValue, m_allFunctionSwitches[ j ].GetCurrentSelectedInput() ); + break; + } + } + } + } + + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + + m_portsChanged = true; + } + + void InputPortSwitchRestriction( WirePort port ) + { + switch( port.DataType ) + { + case WirePortDataType.OBJECT: + break; + case WirePortDataType.FLOAT: + case WirePortDataType.FLOAT2: + case WirePortDataType.FLOAT3: + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + case WirePortDataType.INT: + { + port.CreatePortRestrictions( WirePortDataType.FLOAT, WirePortDataType.FLOAT2, WirePortDataType.FLOAT3, WirePortDataType.FLOAT4, WirePortDataType.COLOR, WirePortDataType.INT, WirePortDataType.OBJECT ); + } + break; + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + { + port.CreatePortRestrictions( WirePortDataType.FLOAT3x3, WirePortDataType.FLOAT4x4, WirePortDataType.OBJECT ); + } + break; + case WirePortDataType.SAMPLER1D: + case WirePortDataType.SAMPLER2D: + case WirePortDataType.SAMPLER3D: + case WirePortDataType.SAMPLERCUBE: + { + port.CreatePortRestrictions( WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE, WirePortDataType.OBJECT ); + } + break; + default: + break; + } + } + + void OutputPortSwitchRestriction( WirePort port ) + { + switch( port.DataType ) + { + case WirePortDataType.OBJECT: + break; + case WirePortDataType.FLOAT: + case WirePortDataType.FLOAT2: + case WirePortDataType.FLOAT3: + case WirePortDataType.FLOAT4: + case WirePortDataType.COLOR: + case WirePortDataType.INT: + case WirePortDataType.FLOAT3x3: + case WirePortDataType.FLOAT4x4: + { + port.AddPortForbiddenTypes( WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE ); + } + break; + case WirePortDataType.SAMPLER1D: + case WirePortDataType.SAMPLER2D: + case WirePortDataType.SAMPLER3D: + case WirePortDataType.SAMPLERCUBE: + { + port.CreatePortRestrictions( WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE, WirePortDataType.OBJECT ); + } + break; + default: + break; + } + } + + public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + { + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + m_outsideGraph = cachedGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + + for( int i = 0; i < m_allFunctionOutputs.Count; i++ ) + { + m_allFunctionOutputs[ i ].PropagateNodeData( nodeData, ref dataCollector ); + } + + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + + base.PropagateNodeData( nodeData, ref dataCollector ); + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + UIUtils.RegisterFunctionNode( this ); + } + + public override void SetupFromCastObject( UnityEngine.Object obj ) + { + base.SetupFromCastObject( obj ); + AmplifyShaderFunction function = obj as AmplifyShaderFunction; + CommonInit( function, UniqueId ); + RefreshExternalReferences(); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + FunctionInput functionInput = m_refreshIdsRequired ? m_allFunctionInputs[ portId ] : GetFunctionInputByUniqueId( portId ); + functionInput.PreviewIsDirty = true; + if( functionInput.AutoCast ) + { + InputPort inputPort = m_refreshIdsRequired ? m_inputPorts[ portId ] : GetInputPortByUniqueId( portId ); + inputPort.MatchPortToConnection(); + + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + functionInput.ChangeOutputType( inputPort.DataType, false ); + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + } + + for( int i = 0; i < m_allFunctionOutputs.Count; i++ ) + { + m_outputPorts[ i ].ChangeType( m_allFunctionOutputs[ i ].InputPorts[ 0 ].DataType, false ); + } + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + + FunctionInput functionInput = m_refreshIdsRequired ? m_allFunctionInputs[ portId ] : GetFunctionInputByUniqueId( portId ); + functionInput.PreviewIsDirty = true; + } + + public override void OnConnectedOutputNodeChanges( int inputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( inputPortId, otherNodeId, otherPortId, name, type ); + FunctionInput functionInput = m_refreshIdsRequired ? m_allFunctionInputs[ inputPortId ] : GetFunctionInputByUniqueId( inputPortId ); + functionInput.PreviewIsDirty = true; + if( functionInput.AutoCast ) + { + InputPort inputPort = m_refreshIdsRequired ? m_inputPorts[ inputPortId ] : GetInputPortByUniqueId( inputPortId ); + inputPort.MatchPortToConnection(); + + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + functionInput.ChangeOutputType( inputPort.DataType, false ); + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + } + + for( int i = 0; i < m_allFunctionOutputs.Count; i++ ) + { + m_outputPorts[ i ].ChangeType( m_allFunctionOutputs[ i ].InputPorts[ 0 ].DataType, false ); + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + + if( Function == null ) + return; + + if( Function.Description.Length > 0 || m_allFunctionSwitches.Count > 0 ) + NodeUtils.DrawPropertyGroup( ref m_parametersFoldout, "Parameters", DrawDescription ); + + bool drawInternalDataUI = false; + int inputCount = m_inputPorts.Count; + if( inputCount > 0 ) + { + for( int i = 0; i < inputCount; i++ ) + { + if( m_inputPorts[ i ].Available && m_inputPorts[ i ].ValidInternalData && !m_inputPorts[ i ].IsConnected && m_inputPorts[ i ].AutoDrawInternalData /*&& ( m_inputPorts[ i ].AutoDrawInternalData || ( m_autoDrawInternalPortData && m_useInternalPortData ) )*/ /*&& m_inputPorts[ i ].AutoDrawInternalData*/ ) + { + drawInternalDataUI = true; + break; + } + } + } + + if( drawInternalDataUI ) + NodeUtils.DrawPropertyGroup( ref m_internalDataFoldout, Constants.InternalDataLabelStr, () => + { + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + if( m_inputPorts[ i ].ValidInternalData && !m_inputPorts[ i ].IsConnected && m_inputPorts[ i ].Visible && m_inputPorts[ i ].AutoDrawInternalData ) + { + EditorGUI.BeginChangeCheck(); + m_inputPorts[ i ].ShowInternalData( this ); + if( EditorGUI.EndChangeCheck() ) + { + m_allFunctionInputs[ i ].PreviewIsDirty = true; + } + } + } + } ); + } + + private void DrawDescription() + { + if( Function.Description.Length > 0 ) + EditorGUILayout.HelpBox( Function.Description, MessageType.Info ); + + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + for( int i = 0; i < m_allFunctionSwitches.Count; i++ ) + { + m_allFunctionSwitches[ i ].AsDrawn = false; + } + + for( int i = 0; i < m_allFunctionSwitches.Count; i++ ) + { + if( m_allFunctionSwitches[ i ].DrawOption( this ) ) + { + m_portsChanged = true; + } + } + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + } + + private void RemoveShaderFunctionDirectivesInternal( int lod ) + { + List<TemplateMultiPassMasterNode> nodes = ContainerGraph.ParentWindow.OutsideGraph.GetMultiPassMasterNodes( lod ); + int count = nodes.Count; + for( int i = 0; i < count; i++ ) + { + nodes[ i ].PassModule.AdditionalDirectives.RemoveShaderFunctionItems( OutputId ); + } + } + + public override void Destroy() + { + m_mainPreviewNode = null; + base.Destroy(); + + m_duplicatesBuffer.Clear(); + m_duplicatesBuffer = null; + + if( m_functionGraph != null && ContainerGraph.ParentWindow.CurrentGraph != m_functionGraph ) + ContainerGraph.ParentWindow.CurrentGraph.InstancePropertyCount -= m_functionGraph.InstancePropertyCount; + + if( ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface != null ) + { + //for( int i = 0; i < m_includes.Count; i++ ) + //{ + // //if( ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalIncludes.OutsideList.Contains( m_includes[ i ] ) ) + // //{ + // // ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalIncludes.OutsideList.Remove( m_includes[ i ] ); + // //} + // ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalDirectives.RemoveShaderFunctionItem( AdditionalLineType.Include, m_includes[ i ] ); + //} + + //for( int i = 0; i < m_pragmas.Count; i++ ) + //{ + // //if( ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalPragmas.OutsideList.Contains( m_pragmas[ i ] ) ) + // //{ + // // ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalPragmas.OutsideList.Remove( m_pragmas[ i ] ); + // //} + // ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalDirectives.RemoveShaderFunctionItem( AdditionalLineType.Pragma, m_pragmas[ i ] ); + //} + ContainerGraph.ParentWindow.OutsideGraph.CurrentStandardSurface.AdditionalDirectives.RemoveShaderFunctionItems( OutputId/*, m_directives */); + } + else + { + if( ContainerGraph.ParentWindow.OutsideGraph.MultiPassMasterNodes.Count > 0 ) + { + for( int lod = -1; lod < ContainerGraph.ParentWindow.OutsideGraph.LodMultiPassMasternodes.Count; lod++ ) + { + RemoveShaderFunctionDirectivesInternal( lod ); + } + } + } + + + + + // Cannot GameObject.Destroy(m_directives[i]) since we would be removing them from + // the shader function asset itself + + m_directives.Clear(); + m_directives = null; + + if( m_reordenator != null ) + { + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = null; + UIUtils.UnregisterPropertyNode( m_reordenator ); + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + + m_reordenator.Destroy(); + m_reordenator = null; + } + + UIUtils.UnregisterFunctionNode( this ); + + ParentGraph cachedGraph2 = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + + if( m_allFunctionInputs != null ) + m_allFunctionInputs.Clear(); + m_allFunctionInputs = null; + + if( m_allFunctionOutputs != null ) + m_allFunctionOutputs.Clear(); + m_allFunctionOutputs = null; + + if( m_functionGraph != null ) + m_functionGraph.SoftDestroy(); + m_functionGraph = null; + + ContainerGraph.ParentWindow.CustomGraph = cachedGraph2; + m_function = null; + + m_allFunctionOutputsDict.Clear(); + m_allFunctionOutputsDict = null; + + m_allFunctionSwitchesDict.Clear(); + m_allFunctionSwitchesDict = null; + + m_allFunctionInputsDict.Clear(); + m_allFunctionInputsDict = null; + + UIUtils.CurrentWindow.OutsideGraph.OnLODMasterNodesAddedEvent -= OnLODMasterNodesAddedEvent; + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + if( m_lateRefresh ) + { + m_lateRefresh = false; + RefreshExternalReferences(); + } + + CheckForChangesRecursively(); + + base.OnNodeLogicUpdate( drawInfo ); + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + + if( m_functionGraph != null ) + { + int nodeCount = m_functionGraph.AllNodes.Count; + for( int i = 0; i < nodeCount; i++ ) + { + m_functionGraph.AllNodes[ i ].OnNodeLogicUpdate( drawInfo ); + } + + if( !string.IsNullOrEmpty( FunctionGraph.CurrentFunctionOutput.SubTitle ) ) + { + SetAdditonalTitleText( FunctionGraph.CurrentFunctionOutput.SubTitle ); + } + } + + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + if( m_portsChanged ) + { + m_portsChanged = false; + for( int i = 0; i < m_allFunctionOutputs.Count; i++ ) + { + m_outputPorts[ i ].ChangeType( m_allFunctionOutputs[ i ].InputPorts[ 0 ].DataType, false ); + } + + CheckPortVisibility(); + } + } + + public override void Draw( DrawInfo drawInfo ) + { + //CheckForChangesRecursively(); + + if( !m_initialGraphDraw && drawInfo.CurrentEventType == EventType.Repaint ) + { + m_initialGraphDraw = true; + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; + if( m_functionGraph != null ) + { + for( int i = 0; i < m_functionGraph.AllNodes.Count; i++ ) + { + ParentNode node = m_functionGraph.AllNodes[ i ]; + if( node != null ) + { + node.OnNodeLayout( drawInfo ); + } + } + } + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + } + + base.Draw( drawInfo ); + } + + public bool CheckForChanges( bool forceCheck = false, bool forceChange = false ) + { + if( ( ContainerGraph.ParentWindow.CheckFunctions || forceCheck || forceChange ) && m_function != null ) + { + //string newCheckSum = LastLine( m_function.FunctionInfo ); + string newCheckSum = AssetDatabase.GetAssetDependencyHash( AssetDatabase.GetAssetPath( m_function ) ).ToString(); + if( !m_functionCheckSum.Equals( newCheckSum ) || forceChange ) + { + m_functionCheckSum = newCheckSum; + ContainerGraph.OnDuplicateEvent += DuplicateMe; + return true; + } + } + return false; + } + + public bool CheckForChangesRecursively() + { + if( m_functionGraph == null ) + return false; + + bool result = false; + for( int i = 0; i < m_functionGraph.FunctionNodes.NodesList.Count; i++ ) + { + if( m_functionGraph.FunctionNodes.NodesList[ i ].CheckForChangesRecursively() ) + result = true; + } + if( CheckForChanges( false, result ) ) + result = true; + + return result; + } + + public void DuplicateMe() + { + bool previewOpen = m_showPreview; + + string allOptions = m_allFunctionSwitches.Count.ToString(); + for( int i = 0; i < m_allFunctionSwitches.Count; i++ ) + { + allOptions += "," + m_allFunctionSwitches[ i ].UniqueId + "," + m_allFunctionSwitches[ i ].GetCurrentSelectedInput(); + } + + ReadOptionsHelper = allOptions.Split( ',' ); + + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = null; + MasterNode masterNode = ContainerGraph.ParentWindow.CurrentGraph.CurrentMasterNode; + if( masterNode != null ) + masterNode.InvalidateMaterialPropertyCount(); + + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + + ParentNode newNode = ContainerGraph.CreateNode( m_function, false, Vec2Position ); + newNode.ShowPreview = previewOpen; + ( newNode as FunctionNode ).ReadOptionsHelper = ReadOptionsHelper; + newNode.RefreshExternalReferences(); + if( ( newNode as FunctionNode ).m_reordenator && m_reordenator ) + ( newNode as FunctionNode ).m_reordenator.OrderIndex = m_reordenator.OrderIndex; + + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + if( m_outputPorts[ i ].IsConnected ) + { + OutputPort newOutputPort = newNode.GetOutputPortByUniqueId( m_outputPorts[ i ].PortId ); + if( newNode.OutputPorts != null && newOutputPort != null ) + { + for( int j = m_outputPorts[ i ].ExternalReferences.Count - 1; j >= 0; j-- ) + { + ContainerGraph.CreateConnection( m_outputPorts[ i ].ExternalReferences[ j ].NodeId, m_outputPorts[ i ].ExternalReferences[ j ].PortId, newOutputPort.NodeId, newOutputPort.PortId ); + } + } + } + //else + //{ + //if( newNode.OutputPorts != null && newNode.OutputPorts[ i ] != null ) + //{ + // ContainerGraph.DeleteConnection( false, newNode.UniqueId, newNode.OutputPorts[ i ].PortId, false, false, false ); + //} + //} + } + + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + if( m_inputPorts[ i ].IsConnected ) + { + InputPort newInputPort = newNode.GetInputPortByUniqueId( m_inputPorts[ i ].PortId ); + if( newNode.InputPorts != null && newInputPort != null ) + { + ContainerGraph.CreateConnection( newInputPort.NodeId, newInputPort.PortId, m_inputPorts[ i ].ExternalReferences[ 0 ].NodeId, m_inputPorts[ i ].ExternalReferences[ 0 ].PortId ); + } + } + } + + ContainerGraph.OnDuplicateEvent -= DuplicateMe; + + if( Selected ) + { + ContainerGraph.DeselectNode( this ); + ContainerGraph.SelectNode( newNode, true, false ); + } + + ContainerGraph.DestroyNode( this, false ); + } + + private FunctionOutput GetFunctionOutputByUniqueId( int uniqueId ) + { + int listCount = m_allFunctionOutputs.Count; + if( m_allFunctionOutputsDict.Count != m_allFunctionOutputs.Count ) + { + m_allFunctionOutputsDict.Clear(); + for( int i = 0; i < listCount; i++ ) + { + m_allFunctionOutputsDict.Add( m_allFunctionOutputs[ i ].UniqueId, m_allFunctionOutputs[ i ] ); + } + } + + if( m_allFunctionOutputsDict.ContainsKey( uniqueId ) ) + return m_allFunctionOutputsDict[ uniqueId ]; + + return null; + } + + private FunctionInput GetFunctionInputByUniqueId( int uniqueId ) + { + int listCount = m_allFunctionInputs.Count; + if( m_allFunctionInputsDict.Count != m_allFunctionInputs.Count ) + { + m_allFunctionInputsDict.Clear(); + for( int i = 0; i < listCount; i++ ) + { + m_allFunctionInputsDict.Add( m_allFunctionInputs[ i ].UniqueId, m_allFunctionInputs[ i ] ); + } + } + + if( m_allFunctionInputsDict.ContainsKey( uniqueId ) ) + return m_allFunctionInputsDict[ uniqueId ]; + + return null; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + OutputPort outputPort = GetOutputPortByUniqueId( outputId ); + FunctionOutput functionOutput = GetFunctionOutputByUniqueId( outputId ); + + if( outputPort.IsLocalValue( dataCollector.PortCategory ) ) + return outputPort.LocalValue( dataCollector.PortCategory ); + + m_functionGraph.CurrentPrecision = ContainerGraph.ParentWindow.CurrentGraph.CurrentPrecision; + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + m_outsideGraph = cachedGraph; + ContainerGraph.ParentWindow.CustomGraph = m_functionGraph; +#if ADD_SHADER_FUNCTION_HEADERS + if( m_reordenator != null && m_reordenator.RecursiveCount() > 0 && m_reordenator.HasTitle ) + { + dataCollector.AddToProperties( UniqueId, "[Header(" + m_reordenator.HeaderTitle.Replace( "-", " " ) + ")]", m_reordenator.OrderIndex ); + } +#endif + string result = string.Empty; + for( int i = 0; i < m_allFunctionInputs.Count; i++ ) + { + if( !m_allFunctionInputs[ i ].InputPorts[ 0 ].IsConnected || m_inputPorts[ i ].IsConnected ) + m_allFunctionInputs[ i ].OnPortGeneration += FunctionNodeOnPortGeneration; + } + + result += functionOutput.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + + for( int i = 0; i < m_allFunctionInputs.Count; i++ ) + { + if( !m_allFunctionInputs[ i ].InputPorts[ 0 ].IsConnected || m_inputPorts[ i ].IsConnected ) + m_allFunctionInputs[ i ].OnPortGeneration -= FunctionNodeOnPortGeneration; + } + + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + + if( outputPort.ConnectionCount > 1 ) + RegisterLocalVariable( outputId, result, ref dataCollector ); + else + outputPort.SetLocalValue( result, dataCollector.PortCategory ); + + return outputPort.LocalValue( dataCollector.PortCategory ); + } + + private string FunctionNodeOnPortGeneration( ref MasterNodeDataCollector dataCollector, int index, ParentGraph graph ) + { + ParentGraph cachedGraph = ContainerGraph.ParentWindow.CustomGraph; + ContainerGraph.ParentWindow.CustomGraph = m_outsideGraph; + string result = m_inputPorts[ index ].GeneratePortInstructions( ref dataCollector ); + ContainerGraph.ParentWindow.CustomGraph = cachedGraph; + return result; + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + + if( Function != null ) + IOUtils.AddFieldValueToString( ref nodeInfo, m_function.name ); + else + IOUtils.AddFieldValueToString( ref nodeInfo, m_filename ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_reordenator != null ? m_reordenator.RawOrderIndex : -1 ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_headerTitle ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_functionGraphId ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_functionGUID ); + + int functionSwitchCount = m_allFunctionSwitches != null ? m_allFunctionSwitches.Count : 0; + string allOptions = functionSwitchCount.ToString(); + for( int i = 0; i < functionSwitchCount; i++ ) + { + allOptions += "," + m_allFunctionSwitches[ i ].UniqueId + "," + m_allFunctionSwitches[ i ].GetCurrentSelectedInput(); + } + IOUtils.AddFieldValueToString( ref nodeInfo, allOptions ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_filename = GetCurrentParam( ref nodeParams ); + m_orderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_headerTitle = GetCurrentParam( ref nodeParams ); + + if( UIUtils.CurrentShaderVersion() > 7203 ) + { + m_functionGraphId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() > 13704 ) + { + m_functionGUID = GetCurrentParam( ref nodeParams ); + } + + AmplifyShaderFunction loaded = AssetDatabase.LoadAssetAtPath<AmplifyShaderFunction>( AssetDatabase.GUIDToAssetPath( m_functionGUID ) ); + if( loaded != null ) + { + CommonInit( loaded, UniqueId ); + } + else + { + string[] guids = AssetDatabase.FindAssets( "t:AmplifyShaderFunction " + m_filename ); + if( guids.Length > 0 ) + { + string sfGuid = null; + + foreach( string guid in guids ) + { + string assetPath = AssetDatabase.GUIDToAssetPath( guid ); + string name = System.IO.Path.GetFileNameWithoutExtension( assetPath ); + if( name.Equals( m_filename, StringComparison.OrdinalIgnoreCase ) ) + { + sfGuid = guid; + break; + } + } + loaded = AssetDatabase.LoadAssetAtPath<AmplifyShaderFunction>( AssetDatabase.GUIDToAssetPath( sfGuid ) ); + + if( loaded != null ) + { + CommonInit( loaded, UniqueId ); + } + else + { + SetTitleText( "ERROR" ); + UIUtils.ShowMessage( UniqueId, string.Format( "Error loading {0} shader function from project folder", m_filename ), MessageSeverity.Error ); + } + } + else + { + SetTitleText( "Missing Function" ); + UIUtils.ShowMessage( UniqueId, string.Format( "Missing {0} shader function on project folder", m_filename ), MessageSeverity.Error ); + } + } + if( UIUtils.CurrentShaderVersion() > 14203 ) + { + ReadOptionsHelper = GetCurrentParam( ref nodeParams ).Split( ',' ); + } + } + + public override void ReadOutputDataFromString( ref string[] nodeParams ) + { + if( Function == null ) + return; + + base.ReadOutputDataFromString( ref nodeParams ); + + ConfigureInputportsAfterRead(); + } + + public override void OnNodeDoubleClicked( Vector2 currentMousePos2D ) + { + if( Function == null ) + return; + + ContainerGraph.DeSelectAll(); + this.Selected = true; + + ContainerGraph.ParentWindow.OnLeftMouseUp(); + AmplifyShaderEditorWindow.LoadShaderFunctionToASE( Function, true ); + this.Selected = false; + } + + private void ConfigureInputportsAfterRead() + { + if( InputPorts != null ) + { + int inputCount = InputPorts.Count; + for( int i = 0; i < inputCount; i++ ) + { + InputPorts[ i ].ChangeProperties( m_allFunctionInputs[ i ].InputName, m_allFunctionInputs[ i ].SelectedInputType, false ); + } + } + + if( OutputPorts != null ) + { + int outputCount = OutputPorts.Count; + for( int i = 0; i < outputCount; i++ ) + { + OutputPorts[ i ].ChangeProperties( m_allFunctionOutputs[ i ].OutputName, m_allFunctionOutputs[ i ].AutoOutputType, false ); + } + } + } + + private void CheckPortVisibility() + { + bool changes = false; + if( InputPorts != null ) + { + for( int i = 0; i < m_allFunctionInputs.Count; i++ ) + { + if( m_inputPorts[ i ].Visible != m_allFunctionInputs[ i ].IsConnected ) + { + m_inputPorts[ i ].Visible = m_allFunctionInputs[ i ].IsConnected; + changes = true; + } + } + } + + if( changes ) + m_sizeIsDirty = true; + } + + public bool HasProperties { get { return m_reordenator != null; } } + + public ParentGraph FunctionGraph + { + get { return m_functionGraph; } + set { m_functionGraph = value; } + } + + public AmplifyShaderFunction Function + { + get { return m_function; } + set { m_function = value; } + } + + public override void RecordObjectOnDestroy( string Id ) + { + base.RecordObjectOnDestroy( Id ); + if( m_reordenator != null ) + m_reordenator.RecordObject( Id ); + + if( m_functionGraph != null ) + { + Undo.RegisterCompleteObjectUndo( m_functionGraph, Id ); + for( int i = 0; i < m_functionGraph.AllNodes.Count; i++ ) + { + m_functionGraph.AllNodes[ i ].RecordObject( Id ); + } + } + } + + public override void SetContainerGraph( ParentGraph newgraph ) + { + base.SetContainerGraph( newgraph ); + if( m_functionGraph == null ) + return; + for( int i = 0; i < m_functionGraph.AllNodes.Count; i++ ) + { + m_functionGraph.AllNodes[ i ].SetContainerGraph( m_functionGraph ); + } + } + + public override void OnMasterNodeReplaced( MasterNode newMasterNode ) + { + base.OnMasterNodeReplaced( newMasterNode ); + if( m_functionGraph == null ) + return; + + m_functionGraph.FireMasterNodeReplacedEvent( newMasterNode ); + + StandardSurfaceOutputNode surface = newMasterNode as StandardSurfaceOutputNode; + if( surface != null ) + { + surface.AdditionalDirectives.AddShaderFunctionItems( OutputId, Function.AdditionalDirectives.DirectivesList ); + } + else + { + if( ContainerGraph.ParentWindow.OutsideGraph.MultiPassMasterNodes.Count > 0 ) + { + for( int lod = -1; lod < ContainerGraph.ParentWindow.OutsideGraph.LodMultiPassMasternodes.Count; lod++ ) + { + AddShaderFunctionDirectivesInternal( lod ); + } + } + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionNode.cs.meta new file mode 100644 index 00000000..15ea8d35 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7b3de46feda5b0f4ea58c852c4a521a9 +timeCreated: 1492001141 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionOutput.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionOutput.cs new file mode 100644 index 00000000..baa49631 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionOutput.cs @@ -0,0 +1,318 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Function Output", "Functions", "Function Output adds an output port to the shader function, it's port type is determined automatically.", NodeAvailabilityFlags = (int)NodeAvailability.ShaderFunction )] + public sealed class FunctionOutput : OutputNode + { + public FunctionOutput() : base() { CommonInit(); } + public FunctionOutput( int uniqueId, float x, float y, float width, float height ) : base( uniqueId, x, y, width, height ) { CommonInit(); } + + [SerializeField] + private bool m_previewNode = false; + + [SerializeField] + private string m_outputName = "Output"; + + [SerializeField] + private int m_orderIndex = -1; + + [SerializeField] + private AmplifyShaderFunction m_function; + + //Title editing + [SerializeField] + private string m_uniqueName; + + private bool m_isEditing; + private bool m_stopEditing; + private bool m_startEditing; + private double m_clickTime; + private double m_doubleClickTime = 0.3; + private Rect m_titleClickArea; + private bool m_showTitleWhenNotEditing = true; + + [SerializeField] + private string m_subTitle = string.Empty; + + + void CommonInit() + { + m_isMainOutputNode = false; + m_connStatus = NodeConnectionStatus.Connected; + m_activeType = GetType(); + m_currentPrecisionType = PrecisionType.Inherit; + m_textLabelWidth = 100; + m_autoWrapProperties = true; + AddInputPort( WirePortDataType.FLOAT, false, " " ); + AddOutputPort( WirePortDataType.FLOAT, " " ); + m_outputPorts[ 0 ].Visible = false; + SetTitleText( m_outputName ); + m_previewShaderGUID = "e6d5f64114b18e24f99dc65290c0fe98"; + } + + public override void SetupNodeCategories() + { + //base.SetupNodeCategories(); + ContainerGraph.ResetNodesData(); + MasterNode masterNode = ContainerGraph.ParentWindow.CurrentGraph.CurrentMasterNode; + if( masterNode != null ) + { + int count = m_inputPorts.Count; + for( int i = 0; i < count; i++ ) + { + if( m_inputPorts[ i ].IsConnected ) + { + NodeData nodeData = new NodeData( m_inputPorts[ i ].Category ); + ParentNode node = m_inputPorts[ i ].GetOutputNode(); + MasterNodeDataCollector temp = masterNode.CurrentDataCollector; + node.PropagateNodeData( nodeData, ref temp ); + temp = null; + } + } + } + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + UIUtils.RegisterFunctionOutputNode( this ); + if( m_nodeAttribs != null ) + m_uniqueName = m_nodeAttribs.Name + UniqueId; + } + + + public override void Destroy() + { + base.Destroy(); + UIUtils.UnregisterFunctionOutputNode( this ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + + public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + return m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUI.BeginChangeCheck(); + m_outputName = EditorGUILayoutTextField( "Name", m_outputName ); + + if( EditorGUI.EndChangeCheck() ) + { + SetTitleText( m_outputName ); + UIUtils.UpdateFunctionOutputData( UniqueId, m_outputName ); + } + + EditorGUI.BeginDisabledGroup( m_previewNode ); + if( GUILayout.Button( "Set as Preview" ) ) + { + List<FunctionOutput> allOutputs = UIUtils.FunctionOutputList(); + + foreach( FunctionOutput item in allOutputs ) + item.PreviewNode = false; + + m_previewNode = true; + } + EditorGUI.EndDisabledGroup(); + } + [SerializeField] + private string m_currentTitle = string.Empty; + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + if( m_previewNode ) + m_currentTitle = "Preview"; + else + m_currentTitle = string.Empty; + + SetAdditonalTitleTextOnCallback( m_currentTitle, ( instance, newSubTitle ) => instance.AdditonalTitleContent.text = newSubTitle ); + + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 ) + { + if( !m_isEditing && ( ( !ContainerGraph.ParentWindow.MouseInteracted && drawInfo.CurrentEventType == EventType.MouseDown && m_titleClickArea.Contains( drawInfo.MousePosition ) ) ) ) + { + if( ( EditorApplication.timeSinceStartup - m_clickTime ) < m_doubleClickTime ) + m_startEditing = true; + else + GUI.FocusControl( null ); + m_clickTime = EditorApplication.timeSinceStartup; + } + else if( m_isEditing && ( ( drawInfo.CurrentEventType == EventType.MouseDown && !m_titleClickArea.Contains( drawInfo.MousePosition ) ) || !EditorGUIUtility.editingTextField ) ) + { + m_stopEditing = true; + } + + if( m_isEditing || m_startEditing ) + { + EditorGUI.BeginChangeCheck(); + GUI.SetNextControlName( m_uniqueName ); + m_outputName = EditorGUITextField( m_titleClickArea, string.Empty, m_outputName, UIUtils.GetCustomStyle( CustomStyle.NodeTitle ) ); + if( EditorGUI.EndChangeCheck() ) + { + SetTitleText( m_outputName ); + UIUtils.UpdateFunctionInputData( UniqueId, m_outputName ); + } + + if( m_startEditing ) + EditorGUI.FocusTextInControl( m_uniqueName ); + + } + + if( drawInfo.CurrentEventType == EventType.Repaint ) + { + if( m_startEditing ) + { + m_startEditing = false; + m_isEditing = true; + } + + if( m_stopEditing ) + { + m_stopEditing = false; + m_isEditing = false; + GUI.FocusControl( null ); + } + } + } + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + // RUN LAYOUT CHANGES AFTER TITLES CHANGE + base.OnNodeLayout( drawInfo ); + m_titleClickArea = m_titlePos; + m_titleClickArea.height = Constants.NODE_HEADER_HEIGHT; + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if( !m_isVisible ) + return; + + // Fixed Title ( only renders when not editing ) + if( m_showTitleWhenNotEditing && !m_isEditing && !m_startEditing && ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD3 ) + { + GUI.Label( m_titleClickArea, m_content, UIUtils.GetCustomStyle( CustomStyle.NodeTitle ) ); + } + } + + public override void OnNodeDoubleClicked( Vector2 currentMousePos2D ) + { + if( currentMousePos2D.y - m_globalPosition.y > ( Constants.NODE_HEADER_HEIGHT + Constants.NODE_HEADER_EXTRA_HEIGHT ) * ContainerGraph.ParentWindow.CameraDrawInfo.InvertedZoom ) + { + ContainerGraph.ParentWindow.ParametersWindow.IsMaximized = !ContainerGraph.ParentWindow.ParametersWindow.IsMaximized; + } + } + + public WirePortDataType AutoOutputType + { + get { return m_inputPorts[ 0 ].DataType; } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_outputName ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_orderIndex ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_previewNode ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_outputName = GetCurrentParam( ref nodeParams ); + m_orderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + + if( UIUtils.CurrentShaderVersion() > 13706 ) + m_previewNode = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + + if( IsNodeBeingCopied ) + PreviewNode = false; + + if( m_function == null ) + m_function = UIUtils.CurrentWindow.OpenedShaderFunction; + + if( m_isMainOutputNode && m_function != null ) + { + m_function.UpdateDirectivesList(); + } + + SetTitleText( m_outputName ); + UIUtils.UpdateFunctionOutputData( UniqueId, m_outputName ); + } + + public AmplifyShaderFunction Function + { + get { return m_function; } + set + { + m_function = value; + if( m_isMainOutputNode && m_function != null ) + { + m_function.UpdateDirectivesList(); + } + } + } + + public string OutputName + { + get { return m_outputName; } + } + + public int OrderIndex + { + get { return m_orderIndex; } + set { m_orderIndex = value; } + } + + public string SubTitle + { + get { return m_subTitle; } + set { m_subTitle = value; } + } + + public bool PreviewNode + { + get { return m_previewNode; } + set + { + m_previewNode = value; + m_sizeIsDirty = true; + if( m_previewNode ) + { + m_currentTitle = "Preview"; + } + else + { + m_currentTitle = ""; + } + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionOutput.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionOutput.cs.meta new file mode 100644 index 00000000..7ece5125 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionOutput.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6293b1f56d13d6c4ca6a8e2a8099cca9 +timeCreated: 1491917775 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSubtitle.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSubtitle.cs new file mode 100644 index 00000000..42cf0b5f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSubtitle.cs @@ -0,0 +1,124 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Function Subtitle", "Functions", "Adds a subtitle to its shader function", NodeAvailabilityFlags = (int)NodeAvailability.ShaderFunction )] + public sealed class FunctionSubtitle : ParentNode + { + + //protected override void CommonInit( int uniqueId ) + //{ + // base.CommonInit( uniqueId ); + // AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue ); + // AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + // m_autoWrapProperties = true; + // m_textLabelWidth = 100; + // //SetTitleText( m_inputName ); + // //SetAdditonalTitleText( "( " + m_inputValueTypes[ m_selectedInputTypeInt ] + " )" ); + // m_previewShaderGUID = "04bc8e7b317dccb4d8da601680dd8140"; + //} + [SerializeField] + private string m_subttile = "Subtitle"; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue ); + AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + m_autoWrapProperties = true; + m_textLabelWidth = 100; + SetTitleText( m_subttile ); + m_previewShaderGUID = "74e4d859fbdb2c0468de3612145f4929"; + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + + public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type ); + m_inputPorts[ 0 ].MatchPortToConnection(); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + return m_inputPorts[ 0 ].GenerateShaderForOutput( ref dataCollector, m_inputPorts[ 0 ].DataType, ignoreLocalvar ); + } + + //public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + //{ + // base.PropagateNodeData( nodeData, ref dataCollector ); + + // //if( m_containerGraph.CurrentShaderFunction != null ) + // //m_containerGraph.CurrentShaderFunction.FunctionSubtitle = m_subttile; + //} + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + //public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + //{ + // base.PropagateNodeData( nodeData, ref dataCollector ); + //Debug.Log( IsConnected + " " + m_containerGraph.CurrentFunctionOutput ); + if( m_containerGraph.CurrentFunctionOutput != null && IsConnected ) + m_containerGraph.CurrentFunctionOutput.SubTitle = m_subttile; + // m_containerGraph.CurrentShaderFunction.FunctionSubtitle = m_subttile; + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUILayout.BeginVertical(); + EditorGUI.BeginChangeCheck(); + m_subttile = EditorGUILayoutTextField( "Name", m_subttile ); + if( EditorGUI.EndChangeCheck() ) + { + SetTitleText( m_subttile ); + //UIUtils.UpdateFunctionInputData( UniqueId, m_inputName ); + } + EditorGUI.BeginChangeCheck(); + //m_selectedInputTypeInt = EditorGUILayoutPopup( InputTypeStr, m_selectedInputTypeInt, m_inputValueTypes ); + //if( EditorGUI.EndChangeCheck() ) + //{ + // UpdatePorts(); + // SetAdditonalTitleText( "( " + m_inputValueTypes[ m_selectedInputTypeInt ] + " )" ); + //} + + //m_autoCast = EditorGUILayoutToggle( "Auto Cast", m_autoCast ); + + //EditorGUILayout.Separator(); + //if( !m_inputPorts[ 0 ].IsConnected && m_inputPorts[ 0 ].ValidInternalData ) + //{ + // m_inputPorts[ 0 ].ShowInternalData( this, true, "Default Value" ); + //} + + + EditorGUILayout.EndVertical(); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_subttile ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_subttile = GetCurrentParam( ref nodeParams ); + SetTitleText( m_subttile ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSubtitle.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSubtitle.cs.meta new file mode 100644 index 00000000..bd87bd97 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSubtitle.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 97d5e0cd26200a64fa9d127599406008 +timeCreated: 1522434121 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitch.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitch.cs new file mode 100644 index 00000000..e25ad54a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitch.cs @@ -0,0 +1,867 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Function Switch", "Functions", "Function Switch allows switching options at compile time for shader function", NodeAvailabilityFlags = (int)NodeAvailability.ShaderFunction )] + public sealed class FunctionSwitch : ParentNode + { + private const string InputPortNameStr = "In "; + + private const string ToggleFalseStr = "False"; + private const string ToggleTrueStr = "True"; + + private const string CurrSelectedStr = "Current"; + private const string MaxAmountStr = "Amount"; + private const int MaxAllowedAmount = 9; + + private const int MinComboSize = 50; + private const int MaxComboSize = 105; + + [SerializeField] + private string m_optionLabel = "Option"; + + [SerializeField] + private string[] AvailableInputsLabels = { "In 0", "In 1" }; + + [SerializeField] + private int[] AvailableInputsValues = { 0, 1 }; + + [SerializeField] + private int m_previousSelectedInput = 0; + + [SerializeField] + private int m_currentSelectedInput = 0; + + [SerializeField] + private int m_maxAmountInputs = 2; + + [SerializeField] + private bool m_toggleMode = false; + + [SerializeField] + private string[] m_optionNames = { "In 0", "In 1", "In 2", "In 3", "In 4", "In 5", "In 6", "In 7", "In 8" }; + + [SerializeField] + private int m_orderIndex = -1; + + [SerializeField] + private TexReferenceType m_referenceType = TexReferenceType.Object; + + [SerializeField] + private FunctionSwitch m_functionSwitchReference = null; + + [SerializeField] + private int m_referenceUniqueId = -1; + + [SerializeField] + private bool m_validReference = false; + + private bool m_asDrawn = false; + + private GUIContent m_checkContent; + private GUIContent m_popContent; + + private const double MaxTimestamp = 1; + private bool m_nameModified = false; + private double m_lastTimeNameModified = 0; + + private Rect m_varRect; + private Rect m_imgRect; + private bool m_editing; + + private int m_cachedPropertyId = -1; + + [SerializeField] + private int m_refMaxInputs = -1; + + [SerializeField] + private string m_refOptionLabel = string.Empty; + + [SerializeField] + private int m_refSelectedInput = -1; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + AddInputPort( WirePortDataType.FLOAT, false, InputPortNameStr + i ); + m_inputPorts[ i ].Visible = ( i < 2 ); + } + AddOutputPort( WirePortDataType.FLOAT, " " ); + + m_checkContent = new GUIContent(); + m_checkContent.image = UIUtils.CheckmarkIcon; + + m_popContent = new GUIContent(); + m_popContent.image = UIUtils.PopupIcon; + + m_textLabelWidth = 100; + m_autoWrapProperties = true; + m_insideSize.Set( 80, 25 ); + m_previewShaderGUID = "a58e46feaa5e3d14383bfeac24d008bc"; + } + + public void SetCurrentSelectedInput( int newValue, int prevValue ) + { + m_previousSelectedInput = prevValue; + if( m_validReference ) + m_currentSelectedInput = Mathf.Clamp( newValue, 0, m_refMaxInputs - 1 ); + else + m_currentSelectedInput = Mathf.Clamp( newValue, 0, m_maxAmountInputs - 1 ); + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ m_currentSelectedInput ].DataType, false ); + PreviewIsDirty = true; + ChangeSignalPropagation(); + } + + public int GetCurrentSelectedInput() + { + return m_currentSelectedInput; + } + + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + + if( m_cachedPropertyId == -1 ) + m_cachedPropertyId = Shader.PropertyToID( "_Current" ); + + PreviewMaterial.SetInt( m_cachedPropertyId, m_currentSelectedInput ); + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + if( m_referenceType == TexReferenceType.Object ) + { + UIUtils.RegisterFunctionSwitchNode( this ); + } + else + { + if( ContainerGraph.ParentWindow.CustomGraph != null ) + UIUtils.RegisterFunctionSwitchNode( this ); + UIUtils.RegisterFunctionSwitchCopyNode( this ); + } + } + + public override void Destroy() + { + base.Destroy(); + + m_functionSwitchReference = null; + m_referenceUniqueId = -1; + + if( m_referenceType == TexReferenceType.Object ) + { + UIUtils.UnregisterFunctionSwitchNode( this ); + } + else + { + UIUtils.UnregisterFunctionSwitchNode( this ); + UIUtils.UnregisterFunctionSwitchCopyNode( this ); + } + } + + public override void OnConnectedOutputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( portId, otherNodeId, otherPortId, name, type ); + m_inputPorts[ portId ].MatchPortToConnection(); + if( portId == m_currentSelectedInput ) + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ portId ].DataType, false ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + InputPort port = GetInputPortByUniqueId( portId ); + int arrayPos = m_inputPorts.IndexOf( port ); + if( activateNode && m_connStatus == NodeConnectionStatus.Connected && arrayPos == m_currentSelectedInput ) + { + port.GetOutputNode().ActivateNode( m_activeNode, m_activePort, m_activeType ); + } + + OnNodeChange(); + SetSaveIsDirty(); + + m_inputPorts[ portId ].MatchPortToConnection(); + if( arrayPos == m_currentSelectedInput ) + m_outputPorts[ 0 ].ChangeType( m_inputPorts[ portId ].DataType, false ); + } + + public override void ActivateNode( int signalGenNodeId, int signalGenPortId, Type signalGenNodeType ) + { + if( m_selfPowered ) + return; + + ConnStatus = m_restrictions.GetRestiction( signalGenNodeType, signalGenPortId ) ? NodeConnectionStatus.Error : NodeConnectionStatus.Connected; + m_activeConnections += 1; + + m_activeType = signalGenNodeType; + m_activeNode = signalGenNodeId; + m_activePort = signalGenPortId; + if( m_activeConnections == 1 ) + if( m_inputPorts[ m_currentSelectedInput ].IsConnected ) + m_inputPorts[ m_currentSelectedInput ].GetOutputNode().ActivateNode( signalGenNodeId, signalGenPortId, signalGenNodeType ); + + SetSaveIsDirty(); + } + + public override void DeactivateInputPortNode( int deactivatedPort, bool forceComplete ) + { + InputPort port = GetInputPortByUniqueId( deactivatedPort ); + if( deactivatedPort == m_currentSelectedInput ) + port.GetOutputNode().DeactivateNode( deactivatedPort, false ); + } + + public override void DeactivateNode( int deactivatedPort, bool forceComplete ) + { + if( m_selfPowered ) + return; + + SetSaveIsDirty(); + m_activeConnections -= 1; + + if( ( forceComplete || m_activeConnections <= 0 ) ) + { + m_activeConnections = 0; + ConnStatus = NodeConnectionStatus.Not_Connected; + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + if( m_inputPorts[ i ].IsConnected && i == m_currentSelectedInput ) + { + ParentNode node = m_inputPorts[ i ].GetOutputNode(); + if( node != null ) + node.DeactivateNode( deactivatedPort == -1 ? m_inputPorts[ i ].PortId : deactivatedPort, false ); + } + } + } + } + + public void ChangeSignalPropagation() + { + if( m_previousSelectedInput != m_currentSelectedInput && ConnStatus == NodeConnectionStatus.Connected ) + { + if( m_inputPorts[ m_previousSelectedInput ].IsConnected ) + m_inputPorts[ m_previousSelectedInput ].GetOutputNode().DeactivateNode( m_inputPorts[ m_previousSelectedInput ].PortId, false ); + + if( m_inputPorts[ m_currentSelectedInput ].IsConnected ) + m_inputPorts[ m_currentSelectedInput ].GetOutputNode().ActivateNode( UniqueId, m_inputPorts[ m_currentSelectedInput ].PortId, m_activeType ); + } + } + + public bool DrawOption( ParentNode owner, bool forceDraw = false ) + { + if( !IsConnected && !forceDraw ) + { + //EditorGUILayout.LabelField( "Not Connected" ); + return false; + } + + if( m_asDrawn ) //used to prevent the same property to be drawn more than once + return false; + + if( m_validReference ) + { + return m_functionSwitchReference.DrawOption( owner, true ); + } + + int prev = m_currentSelectedInput; + m_asDrawn = true; + if( m_toggleMode ) + { + m_currentSelectedInput = owner.EditorGUILayoutToggle( m_optionLabel, ( m_currentSelectedInput != 0 ? true : false ) ) ? 1 : 0; + + if( m_currentSelectedInput != prev ) + { + SetCurrentSelectedInput( m_currentSelectedInput, prev ); + return true; + } + else + { + return false; + } + } + else + { + m_currentSelectedInput = owner.EditorGUILayoutIntPopup( m_optionLabel, m_currentSelectedInput, AvailableInputsLabels, AvailableInputsValues ); + + if( m_currentSelectedInput != prev ) + { + SetCurrentSelectedInput( m_currentSelectedInput, prev ); + return true; + } + else + { + return false; + } + } + } + + public void CheckReference() + { + if( m_referenceType != TexReferenceType.Instance ) + { + m_validReference = false; + return; + } + + if( m_functionSwitchReference == null ) + { + m_validReference = false; + ResetToSelf(); + return; + } + + if( m_referenceUniqueId != m_functionSwitchReference.UniqueId ) + { + UpdateFromSelected(); + } + if( m_refSelectedInput != m_functionSwitchReference.GetCurrentSelectedInput() || m_refMaxInputs != m_functionSwitchReference.MaxAmountInputs || m_refOptionLabel != m_functionSwitchReference.OptionLabel ) + { + UpdateFromSelected(); + } + + m_validReference = true; + } + + void ResetToSelf() + { + m_functionSwitchReference = null; + m_validReference = false; + m_referenceUniqueId = -1; + m_refMaxInputs = -1; + m_refOptionLabel = string.Empty; + m_refSelectedInput = -1; + + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs ); + m_inputPorts[ i ].Name = m_optionNames[ i ]; + } + + if( m_currentSelectedInput >= m_maxAmountInputs ) + { + m_currentSelectedInput = m_maxAmountInputs - 1; + } + + UpdateLabels(); + m_sizeIsDirty = true; + } + + void UpdateFromSelected() + { + if( m_referenceUniqueId < 0 ) + return; + + m_functionSwitchReference = UIUtils.GetNode( m_referenceUniqueId ) as FunctionSwitch; + if( m_functionSwitchReference != null ) + { + m_validReference = true; + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + m_inputPorts[ i ].Visible = ( i < m_functionSwitchReference.MaxAmountInputs ); + m_inputPorts[ i ].Name = m_functionSwitchReference.InputPorts[ i ].Name; + } + UpdateLabels(); + m_refMaxInputs = m_functionSwitchReference.m_maxAmountInputs; + m_refOptionLabel = m_functionSwitchReference.OptionLabel; + m_refSelectedInput = m_functionSwitchReference.GetCurrentSelectedInput(); + OrderIndex = m_functionSwitchReference.OrderIndex; + + SetCurrentSelectedInput( m_functionSwitchReference.GetCurrentSelectedInput(), m_currentSelectedInput ); + } + + m_sizeIsDirty = true; + m_isDirty = true; + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUI.BeginChangeCheck(); + m_referenceType = (TexReferenceType)EditorGUILayoutPopup( Constants.ReferenceTypeStr, (int)m_referenceType, Constants.ReferenceArrayLabels ); + if( EditorGUI.EndChangeCheck() ) + { + if( m_referenceType == TexReferenceType.Object ) + { + if( ContainerGraph.ParentWindow.CustomGraph == null ) + UIUtils.UnregisterFunctionSwitchCopyNode( this ); + UIUtils.RegisterFunctionSwitchNode( this ); + ResetToSelf(); + } + else + { + if( ContainerGraph.ParentWindow.CustomGraph == null ) + UIUtils.UnregisterFunctionSwitchNode( this ); + UIUtils.RegisterFunctionSwitchCopyNode( this ); + } + } + + if( m_referenceType == TexReferenceType.Instance ) + { + EditorGUI.BeginChangeCheck(); + string[] arr = new string[ UIUtils.FunctionSwitchList().Count ]; + int[] ids = new int[ UIUtils.FunctionSwitchList().Count ]; + for( int i = 0; i < arr.Length; i++ ) + { + arr[ i ] = i + " - " + UIUtils.FunctionSwitchList()[ i ].OptionLabel; + ids[ i ] = UIUtils.FunctionSwitchList()[ i ].UniqueId; + } + m_referenceUniqueId = EditorGUILayout.IntPopup( Constants.AvailableReferenceStr, m_referenceUniqueId, arr, ids ); + if( EditorGUI.EndChangeCheck() ) + { + UpdateFromSelected(); + } + return; + } + + EditorGUI.BeginChangeCheck(); + m_optionLabel = EditorGUILayoutTextField( "Option Label", m_optionLabel ); + if( EditorGUI.EndChangeCheck() ) + { + m_optionLabel = UIUtils.RemoveInvalidEnumCharacters( m_optionLabel ); + if( string.IsNullOrEmpty( m_optionLabel ) ) + { + m_optionLabel = "Option"; + } + + UIUtils.UpdateFunctionSwitchData( UniqueId, m_optionLabel ); + } + + EditorGUI.BeginChangeCheck(); + m_toggleMode = EditorGUILayoutToggle( "Toggle Mode", m_toggleMode ); + if( EditorGUI.EndChangeCheck() ) + { + if( m_toggleMode ) + { + m_inputPorts[ 0 ].Name = ToggleFalseStr; + m_inputPorts[ 1 ].Name = ToggleTrueStr; + + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + m_inputPorts[ i ].Visible = ( i < 2 ); + } + + if( m_currentSelectedInput >= 2 ) + { + m_currentSelectedInput = 1; + } + UpdateLabels(); + m_sizeIsDirty = true; + } + else + { + m_inputPorts[ 0 ].Name = m_optionNames[ 0 ]; + m_inputPorts[ 1 ].Name = m_optionNames[ 1 ]; + + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs ); + } + + if( m_currentSelectedInput >= m_maxAmountInputs ) + { + m_currentSelectedInput = m_maxAmountInputs - 1; + } + + UpdateLabels(); + m_sizeIsDirty = true; + } + } + + if( !m_toggleMode ) + { + EditorGUI.BeginChangeCheck(); + m_maxAmountInputs = EditorGUILayoutIntSlider( MaxAmountStr, m_maxAmountInputs, 2, MaxAllowedAmount ); + if( EditorGUI.EndChangeCheck() ) + { + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs ); + } + + if( m_currentSelectedInput >= m_maxAmountInputs ) + { + m_currentSelectedInput = m_maxAmountInputs - 1; + } + + UpdateLabels(); + m_sizeIsDirty = true; + } + + EditorGUI.indentLevel++; + for( int i = 0; i < m_maxAmountInputs; i++ ) + { + EditorGUI.BeginChangeCheck(); + m_inputPorts[ i ].Name = EditorGUILayoutTextField( "Item " + i, m_inputPorts[ i ].Name ); + if( EditorGUI.EndChangeCheck() ) + { + m_nameModified = true; + m_lastTimeNameModified = EditorApplication.timeSinceStartup; + m_inputPorts[ i ].Name = UIUtils.RemoveInvalidEnumCharacters( m_inputPorts[ i ].Name ); + m_optionNames[ i ] = m_inputPorts[ i ].Name; + if( string.IsNullOrEmpty( m_inputPorts[ i ].Name ) ) + { + m_inputPorts[ i ].Name = InputPortNameStr + i; + } + m_sizeIsDirty = true; + } + } + EditorGUI.indentLevel--; + + if( m_nameModified ) + { + UpdateLabels(); + } + } + + if( m_toggleMode ) + { + EditorGUI.BeginChangeCheck(); + int prevVal = m_currentSelectedInput; + m_currentSelectedInput = EditorGUILayoutToggle( CurrSelectedStr, ( m_currentSelectedInput != 0 ? true : false ) ) ? 1 : 0; + if( EditorGUI.EndChangeCheck() ) + SetCurrentSelectedInput( m_currentSelectedInput, prevVal ); + } + else + { + EditorGUI.BeginChangeCheck(); + int prevVal = m_currentSelectedInput; + m_currentSelectedInput = EditorGUILayoutIntPopup( CurrSelectedStr, m_currentSelectedInput, AvailableInputsLabels, AvailableInputsValues ); + if( EditorGUI.EndChangeCheck() ) + { + SetCurrentSelectedInput( m_currentSelectedInput, prevVal ); + } + } + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + if( UIUtils.CurrentShaderVersion() > 14205 ) + { + if( m_referenceType == TexReferenceType.Instance ) + { + m_functionSwitchReference = UIUtils.GetNode( m_referenceUniqueId ) as FunctionSwitch; + UpdateFromSelected(); + } + } + + SetCurrentSelectedInput( m_currentSelectedInput, m_previousSelectedInput ); + } + + public void UpdateLabels() + { + int maxinputs = m_maxAmountInputs; + if( m_validReference ) + maxinputs = m_functionSwitchReference.MaxAmountInputs; + + AvailableInputsLabels = new string[ maxinputs ]; + AvailableInputsValues = new int[ maxinputs ]; + + for( int i = 0; i < maxinputs; i++ ) + { + AvailableInputsLabels[ i ] = m_optionNames[ i ]; + AvailableInputsValues[ i ] = i; + } + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + CheckReference(); + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + float finalSize = 0; + if( !m_toggleMode ) + { + GUIContent dropdown = new GUIContent( m_inputPorts[ m_currentSelectedInput ].Name ); + int cacheSize = UIUtils.GraphDropDown.fontSize; + UIUtils.GraphDropDown.fontSize = 10; + Vector2 calcSize = UIUtils.GraphDropDown.CalcSize( dropdown ); + UIUtils.GraphDropDown.fontSize = cacheSize; + finalSize = Mathf.Clamp( calcSize.x, MinComboSize, MaxComboSize ); + if( m_insideSize.x != finalSize ) + { + m_insideSize.Set( finalSize, 25 ); + m_sizeIsDirty = true; + } + } + + base.OnNodeLayout( drawInfo ); + + bool toggleMode = m_toggleMode; + if( m_validReference ) + { + toggleMode = m_functionSwitchReference.m_toggleMode; + } + + if( toggleMode ) + { + m_varRect = m_remainingBox; + m_varRect.size = Vector2.one * 22 * drawInfo.InvertedZoom; + m_varRect.center = m_remainingBox.center; + if( m_showPreview ) + m_varRect.y = m_remainingBox.y; + } + else + { + m_varRect = m_remainingBox; + m_varRect.width = finalSize * drawInfo.InvertedZoom; + m_varRect.height = 16 * drawInfo.InvertedZoom; + m_varRect.x = m_remainingBox.xMax - m_varRect.width; + m_varRect.y += 1 * drawInfo.InvertedZoom; + + m_imgRect = m_varRect; + m_imgRect.x = m_varRect.xMax - 16 * drawInfo.InvertedZoom; + m_imgRect.width = 16 * drawInfo.InvertedZoom; + m_imgRect.height = m_imgRect.width; + } + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + if( m_validReference ) + { + base.DrawGUIControls( drawInfo ); + } + else + { + base.DrawGUIControls( drawInfo ); + + if( drawInfo.CurrentEventType != EventType.MouseDown ) + return; + + if( m_varRect.Contains( drawInfo.MousePosition ) ) + { + m_editing = true; + } + else if( m_editing ) + { + m_editing = false; + } + } + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + if( m_nameModified ) + { + if( ( EditorApplication.timeSinceStartup - m_lastTimeNameModified ) > MaxTimestamp ) + { + m_nameModified = false; + } + } + + if( m_validReference ) + { + SetAdditonalTitleTextOnCallback( m_functionSwitchReference.OptionLabel, ( instance, newSubTitle ) => instance.AdditonalTitleContent.text = string.Format( Constants.SubTitleVarNameFormatStr, newSubTitle ) ); + } + else + { + SetAdditonalTitleTextOnCallback( m_optionLabel, ( instance, newSubTitle ) => instance.AdditonalTitleContent.text = string.Format( Constants.SubTitleValueFormatStr, newSubTitle ) ); + + if( m_editing ) + { + if( m_toggleMode ) + { + if( GUI.Button( m_varRect, GUIContent.none, UIUtils.GraphButton ) ) + { + PreviewIsDirty = true; + int prevVal = m_currentSelectedInput; + m_currentSelectedInput = m_currentSelectedInput == 1 ? 0 : 1; + if( m_currentSelectedInput != prevVal ) + SetCurrentSelectedInput( m_currentSelectedInput, prevVal ); + m_editing = false; + } + + if( m_currentSelectedInput == 1 ) + { + GUI.Label( m_varRect, m_checkContent, UIUtils.GraphButtonIcon ); + } + } + else + { + EditorGUI.BeginChangeCheck(); + int prevVal = m_currentSelectedInput; + m_currentSelectedInput = EditorGUIIntPopup( m_varRect, m_currentSelectedInput, AvailableInputsLabels, AvailableInputsValues, UIUtils.GraphDropDown ); + if( EditorGUI.EndChangeCheck() ) + { + PreviewIsDirty = true; + SetCurrentSelectedInput( m_currentSelectedInput, prevVal ); + m_editing = false; + } + } + } + } + + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if( !m_isVisible ) + return; + + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 ) + { + if( m_validReference ) + { + bool cacheState = GUI.enabled; + GUI.enabled = false; + if( m_functionSwitchReference.m_toggleMode ) + { + GUI.Label( m_varRect, GUIContent.none, UIUtils.GraphButton ); + if( m_functionSwitchReference.GetCurrentSelectedInput() == 1 ) + { + GUI.Label( m_varRect, m_checkContent, UIUtils.GraphButtonIcon ); + } + } + else + { + GUI.Label( m_varRect, m_functionSwitchReference.AvailableInputsLabels[ m_currentSelectedInput ], UIUtils.GraphDropDown ); + } + GUI.enabled = cacheState; + } + else + { + if( !m_editing ) + { + if( m_toggleMode ) + { + GUI.Label( m_varRect, GUIContent.none, UIUtils.GraphButton ); + + if( m_currentSelectedInput == 1 ) + { + GUI.Label( m_varRect, m_checkContent, UIUtils.GraphButtonIcon ); + } + } + else + { + GUI.Label( m_varRect, AvailableInputsLabels[ m_currentSelectedInput ], UIUtils.GraphDropDown ); + GUI.Label( m_imgRect, m_popContent, UIUtils.GraphButtonIcon ); + } + } + } + } + } + + public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + { + m_inputPorts[ m_currentSelectedInput ].GetOutputNode().PropagateNodeData( nodeData, ref dataCollector ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + return m_inputPorts[ m_currentSelectedInput ].GeneratePortInstructions( ref dataCollector ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_optionLabel = GetCurrentParam( ref nodeParams ); + m_toggleMode = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_currentSelectedInput = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_previousSelectedInput = m_currentSelectedInput; + m_maxAmountInputs = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_orderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + + for( int i = 0; i < MaxAllowedAmount; i++ ) + { + m_inputPorts[ i ].Visible = ( i < m_maxAmountInputs ); + } + + if( m_currentSelectedInput >= m_maxAmountInputs ) + { + m_currentSelectedInput = m_maxAmountInputs - 1; + } + + for( int i = 0; i < m_maxAmountInputs; i++ ) + { + m_optionNames[ i ] = GetCurrentParam( ref nodeParams ); + m_inputPorts[ i ].Name = m_optionNames[ i ]; + } + + if( m_toggleMode ) + { + m_inputPorts[ 0 ].Name = ToggleFalseStr; + m_inputPorts[ 1 ].Name = ToggleTrueStr; + } + + UpdateLabels(); + m_sizeIsDirty = true; + + UIUtils.UpdateFunctionSwitchData( UniqueId, m_optionLabel ); + UIUtils.UpdateFunctionSwitchCopyData( UniqueId, m_optionLabel ); + if( UIUtils.CurrentShaderVersion() > 14205 ) + { + m_referenceType = (TexReferenceType)Enum.Parse( typeof( TexReferenceType ), GetCurrentParam( ref nodeParams ) ); + m_referenceUniqueId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + + if( m_referenceType == TexReferenceType.Object ) + { + if( ContainerGraph.ParentWindow.CustomGraph == null ) + UIUtils.UnregisterFunctionSwitchCopyNode( this ); + UIUtils.RegisterFunctionSwitchNode( this ); + ResetToSelf(); + } + else + { + if( ContainerGraph.ParentWindow.CustomGraph == null ) + UIUtils.UnregisterFunctionSwitchNode( this ); + UIUtils.RegisterFunctionSwitchCopyNode( this ); + } + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_optionLabel ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_toggleMode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentSelectedInput ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_maxAmountInputs ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_orderIndex ); + + for( int i = 0; i < m_maxAmountInputs; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_optionNames[ i ] ); + } + + IOUtils.AddFieldValueToString( ref nodeInfo, m_referenceType ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_functionSwitchReference != null ? m_functionSwitchReference.UniqueId : -1 ) ); + } + + public int OrderIndex + { + get { return m_orderIndex; } + set { m_orderIndex = value; } + } + + public string OptionLabel + { + get { return m_optionLabel; } + set { m_optionLabel = value; } + } + + public bool AsDrawn { get { return m_asDrawn; } set { m_asDrawn = value; } } + + public override string DataToArray { get { return m_optionLabel; } } + public int MaxAmountInputs + { + get { return m_maxAmountInputs; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitch.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitch.cs.meta new file mode 100644 index 00000000..8929a454 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitch.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2bd66b9ffd0acf84ab46c9f83300495c +timeCreated: 1515408158 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitchByPipeline.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitchByPipeline.cs new file mode 100644 index 00000000..5a05605e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitchByPipeline.cs @@ -0,0 +1,102 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Switch by Pipeline", "Functions", "Executes branch according to current pipeline", NodeAvailabilityFlags = (int)NodeAvailability.ShaderFunction )] + public sealed class FunctionSwitchByPipeline : ParentNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, "Surface", -1, MasterNodePortCategory.Fragment, 0 ); + AddInputPort( WirePortDataType.FLOAT, false, "Default RP", -1, MasterNodePortCategory.Fragment, 3 ); + AddInputPort( WirePortDataType.FLOAT, false, "Lightweight", -1, MasterNodePortCategory.Fragment, 1 ); + AddInputPort( WirePortDataType.FLOAT, false, "HD", -1, MasterNodePortCategory.Fragment, 2 ); + AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + GetInputPortByUniqueId( portId ).MatchPortToConnection(); + UpdateOutputPort(); + } + + public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type ); + GetInputPortByUniqueId( outputPortId ).MatchPortToConnection(); + UpdateOutputPort(); + } + + void UpdateOutputPort() + { + switch( UIUtils.CurrentWindow.OutsideGraph.CurrentSRPType ) + { + case TemplateSRPType.BuiltIn: + { + InputPort port = UIUtils.CurrentWindow.OutsideGraph.IsStandardSurface ? GetInputPortByUniqueId( 0 ) : GetInputPortByUniqueId( 3 ); + m_outputPorts[ 0 ].ChangeType( port.DataType, false ); + } + break; + case TemplateSRPType.Lightweight: + { + InputPort port = GetInputPortByUniqueId( 1 ); + m_outputPorts[ 0 ].ChangeType( port.DataType, false ); + } + break; + case TemplateSRPType.HD: + { + InputPort port = GetInputPortByUniqueId( 2 ); + m_outputPorts[ 0 ].ChangeType( port.DataType, false ); + } + break; + } + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + switch( dataCollector.CurrentSRPType ) + { + case TemplateSRPType.BuiltIn: + { + InputPort port = UIUtils.CurrentWindow.OutsideGraph.IsStandardSurface ? GetInputPortByUniqueId( 0 ) : GetInputPortByUniqueId( 3 ); + return port.GeneratePortInstructions( ref dataCollector ); + } + case TemplateSRPType.Lightweight: + { + InputPort port = GetInputPortByUniqueId( 1 ); + return port.GeneratePortInstructions( ref dataCollector ); + } + case TemplateSRPType.HD: + { + InputPort port = GetInputPortByUniqueId( 2 ); + return port.GeneratePortInstructions( ref dataCollector ); + } + } + + return "0"; + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + if( UIUtils.CurrentShaderVersion() < 16303 ) + { + InputPort standardPort = GetInputPortByUniqueId( 0 ); + if( standardPort.IsConnected ) + { + UIUtils.SetConnection( UniqueId, 3, standardPort.GetConnection().NodeId, standardPort.GetConnection().PortId ); + } + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitchByPipeline.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitchByPipeline.cs.meta new file mode 100644 index 00000000..9ecd8080 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitchByPipeline.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 84a4868e0b1e8dd4bb0e71c8d9a9c130 +timeCreated: 1535365719 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/LogNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/LogNode.cs new file mode 100644 index 00000000..d431cbb8 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/LogNode.cs @@ -0,0 +1,80 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [System.Serializable] + [NodeAttributes( "Log", "Master", "Debug node to dump output to log", null, KeyCode.None, false )] + public sealed class LogNode : MasterNode + { + private const string InputAmountStr = "Input amount"; + + [SerializeField] + private int m_inputCount = 1; + + [SerializeField] + private int m_lastInputCount = 1; + + public LogNode() : base() { } + public LogNode( int uniqueId, float x, float y, float width, float height ) : base( uniqueId, x, y, width, height ) { } + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddMasterPorts(); + } + + public override void AddMasterPorts() + { + DeleteAllInputConnections( true ); + base.AddMasterPorts(); + + for ( int i = 0; i < m_inputCount; i++ ) + { + AddInputPort( WirePortDataType.OBJECT, false, i.ToString() ); + } + m_sizeIsDirty = true; + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUILayout.BeginVertical(); + { + EditorGUILayout.LabelField( InputAmountStr ); + m_inputCount = EditorGUILayoutIntField( m_inputCount ); + } + EditorGUILayout.EndVertical(); + if ( m_inputCount != m_lastInputCount ) + { + m_lastInputCount = Mathf.Max( m_inputCount, 1 ); + AddMasterPorts(); + } + } + + public override void Execute( Shader currentSelected ) + { + string valueDump = ""; + string valueInstructions = ""; + + MasterNodeDataCollector dataCollector = new MasterNodeDataCollector( this ); + foreach ( InputPort port in InputPorts ) + { + if ( port.IsConnected ) + { + valueInstructions += "Port: " + port.PortId + " Value: " + port.GenerateShaderForOutput( ref dataCollector, port.DataType, false ); + } + } + Debug.Log( "Value: " + valueDump ); + Debug.Log( "Instructions: " + valueInstructions ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + } + + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/LogNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/LogNode.cs.meta new file mode 100644 index 00000000..d2debabc --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/LogNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3b0e734d4c354c74999e20ce054628d2 +timeCreated: 1481126955 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs new file mode 100644 index 00000000..5e4ec937 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs @@ -0,0 +1,979 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditorInternal; + +namespace AmplifyShaderEditor +{ + public enum PrecisionType + { + Float = 0, + Half, + Inherit + } + + public enum AvailableShaderTypes + { + SurfaceShader = 0, + Template + } + + [Serializable] + public class MasterNodeCategoriesData + { + public AvailableShaderTypes Category; + public string Name; + public MasterNodeCategoriesData( AvailableShaderTypes category, string name ) { Category = category; Name = name; } + } + + [Serializable] + public class MasterNode : OutputNode + { + protected const string CustomInspectorStr = "Custom Editor"; + protected const string CustomInspectorFormat = "CustomEditor \"{0}\""; + + private const string PropertyOrderFoldoutStr = " Material Properties"; + private const string PropertyOrderTemplateFoldoutStr = "Material Properties"; + + protected MasterNodeDataCollector m_currentDataCollector; + + protected const string ShaderNameStr = "Shader Name"; + protected GUIContent m_shaderNameContent; + + private const string IndentationHelper = "\t\t{0}\n"; + private const string ShaderLODFormat = "\t\tLOD {0}\n"; + + public delegate void OnMaterialUpdated( MasterNode masterNode ); + public event OnMaterialUpdated OnMaterialUpdatedEvent; + public event OnMaterialUpdated OnShaderUpdatedEvent; + + protected const string GeneralFoldoutStr = " General"; + + protected readonly string[] ShaderModelTypeArr = { "2.0", "2.5", "3.0", "3.5", "4.0", "4.5", "4.6", "5.0" }; + private const string ShaderKeywordsStr = "Shader Keywords"; + + [SerializeField] + protected int m_shaderLOD = 0; + + [SerializeField] + protected int m_shaderModelIdx = 2; + + [SerializeField] + protected Shader m_currentShader; + + [SerializeField] + protected Material m_currentMaterial; + + //[SerializeField] + //private bool m_isMainMasterNode = false; + + [SerializeField] + private Rect m_masterNodeIconCoords; + + [SerializeField] + protected string m_shaderName = Constants.DefaultShaderName; + + [SerializeField] + protected string m_croppedShaderName = Constants.DefaultShaderName; + + [SerializeField] + protected string m_customInspectorName = Constants.DefaultCustomInspector; + + [SerializeField] + protected int m_masterNodeCategory = 0;// MasterNodeCategories.SurfaceShader; + + [SerializeField] + protected string m_currentShaderData = string.Empty; + + private Texture2D m_masterNodeOnTex; + private Texture2D m_masterNodeOffTex; + + private Texture2D m_gpuInstanceOnTex; + private Texture2D m_gpuInstanceOffTex; + + // Shader Keywords + [SerializeField] + private List<string> m_shaderKeywords = new List<string>(); + + [SerializeField] + private bool m_shaderKeywordsFoldout = true; + + private GUIStyle m_addShaderKeywordStyle; + private GUIStyle m_removeShaderKeywordStyle; + private GUIStyle m_smallAddShaderKeywordItemStyle; + private GUIStyle m_smallRemoveShaderKeywordStyle; + private const float ShaderKeywordButtonLayoutWidth = 15; + + + public MasterNode() : base() { CommonInit(); } + public MasterNode( int uniqueId, float x, float y, float width, float height ) : base( uniqueId, x, y, width, height ) { CommonInit(); } + + protected GUIContent m_categoryLabel = new GUIContent( "Shader Type ", "Specify the shader type you want to be working on" ); + + protected GUIContent[] m_availableCategoryLabels; + protected MasterNodeCategoriesData[] m_availableCategories; + + [SerializeField] + private List<PropertyNode> m_propertyNodesVisibleList = new List<PropertyNode>(); + + private ReorderableList m_propertyReordableList; + protected bool m_propertyOrderChanged = false; + //private int m_availableCount = 0; + private int m_lastCount = 0; + + private GUIStyle m_propertyAdjustment; + protected bool m_shaderNameIsTitle = true; + + void CommonInit() + { + m_currentMaterial = null; + m_masterNodeIconCoords = new Rect( 0, 0, 64, 64 ); + m_isMainOutputNode = false; + m_connStatus = NodeConnectionStatus.Connected; + m_activeType = GetType(); + m_currentPrecisionType = PrecisionType.Float; + m_textLabelWidth = 120; + m_shaderNameContent = new GUIContent( ShaderNameStr, string.Empty ); + + AddMasterPorts(); + } + + void InitAvailableCategories() + { + int templateCount = m_containerGraph.ParentWindow.TemplatesManagerInstance.TemplateCount; + m_availableCategories = new MasterNodeCategoriesData[ templateCount + 1 ]; + m_availableCategoryLabels = new GUIContent[ templateCount + 1 ]; + + m_availableCategories[ 0 ] = new MasterNodeCategoriesData( AvailableShaderTypes.SurfaceShader, string.Empty ); + m_availableCategoryLabels[ 0 ] = new GUIContent( "Surface" ); + + for( int i = 0; i < templateCount; i++ ) + { + int idx = i + 1; + TemplateDataParent templateData = m_containerGraph.ParentWindow.TemplatesManagerInstance.GetTemplate( i ); + m_availableCategories[ idx ] = new MasterNodeCategoriesData( AvailableShaderTypes.Template, templateData.GUID ); + m_availableCategoryLabels[ idx ] = new GUIContent( templateData.Name ); + } + } + + public void SetMasterNodeCategoryFromGUID( string GUID ) + { + if( m_availableCategories == null ) + InitAvailableCategories(); + + m_masterNodeCategory = 0; + for( int i = 1; i < m_availableCategories.Length; i++ ) + { + if( m_availableCategories[ i ].Name.Equals( GUID ) ) + m_masterNodeCategory = i; + } + + } + + public override void SetupNodeCategories() + { + //base.SetupNodeCategories(); + ContainerGraph.ResetNodesData(); + int count = m_inputPorts.Count; + for( int i = 0; i < count; i++ ) + { + if( m_inputPorts[ i ].IsConnected ) + { + NodeData nodeData = new NodeData( m_inputPorts[ i ].Category ); + ParentNode node = m_inputPorts[ i ].GetOutputNode(); + node.PropagateNodeData( nodeData, ref m_currentDataCollector ); + } + else if( m_inputPorts[ i ].HasExternalLink ) + { + InputPort linkedPort = m_inputPorts[ i ].ExternalLink; + if( linkedPort != null && linkedPort.IsConnected ) + { + NodeData nodeData = new NodeData( linkedPort.Category ); + ParentNode node = linkedPort.GetOutputNode(); + node.PropagateNodeData( nodeData, ref m_currentDataCollector ); + } + } + } + } + + public virtual void RefreshAvailableCategories() + { + InitAvailableCategories(); + } + + public virtual void AddMasterPorts() { } + + public virtual void ForcePortType() { } + + public virtual void UpdateMasterNodeMaterial( Material material ) { } + + public virtual void SetName( string name ) { } + + public void CopyFrom( MasterNode other ) + { + Vec2Position = other.Vec2Position; + CurrentShader = other.CurrentShader; + CurrentMaterial = other.CurrentMaterial; + ShaderName = other.ShaderName; + m_masterNodeCategory = other.CurrentMasterNodeCategoryIdx; + } + + protected void DrawCurrentShaderType() + { + if( m_availableCategories == null ) + InitAvailableCategories(); + + int oldType = m_masterNodeCategory; + m_masterNodeCategory = EditorGUILayoutPopup( m_categoryLabel, m_masterNodeCategory, m_availableCategoryLabels ); + if( oldType != m_masterNodeCategory ) + { + m_containerGraph.ParentWindow.ReplaceMasterNode( m_availableCategories[ m_masterNodeCategory ], false ); + } + } + + protected void DrawCustomInspector( bool dropdown ) + { +#if !UNITY_2018_3_OR_NEWER + dropdown = false; +#else + if( ASEPackageManagerHelper.CurrentHDVersion <= ASESRPVersions.ASE_SRP_5_16_1 ) + dropdown = false; +#endif + + EditorGUILayout.BeginHorizontal(); + m_customInspectorName = EditorGUILayoutTextField( CustomInspectorStr, m_customInspectorName ); + if( !dropdown ) + { + if( GUILayoutButton( string.Empty, UIUtils.GetCustomStyle( CustomStyle.ResetToDefaultInspectorButton ), GUILayout.Width( 15 ), GUILayout.Height( 15 ) ) ) + { + GUIUtility.keyboardControl = 0; + m_customInspectorName = Constants.DefaultCustomInspector; + } + } + else + { + if( GUILayoutButton( string.Empty, UIUtils.InspectorPopdropdownFallback, GUILayout.Width( 17 ), GUILayout.Height( 19 ) ) ) + { + EditorGUI.FocusTextInControl( null ); + GUI.FocusControl( null ); + + GenericMenu menu = new GenericMenu(); + AddMenuItem( menu, Constants.DefaultCustomInspector ); +#if UNITY_2018_3_OR_NEWER + if( ASEPackageManagerHelper.CurrentHDVersion > ASESRPVersions.ASE_SRP_6_9_1 ) + { + AddMenuItem( menu, "UnityEditor.Rendering.HighDefinition.HDLitGUI" ); + AddMenuItem( menu, "UnityEditor.ShaderGraph.PBRMasterGUI" ); + } + else + { + AddMenuItem( menu, "UnityEditor.Experimental.Rendering.HDPipeline.HDLitGUI" ); + } +#else + AddMenuItem( menu, "UnityEditor.Experimental.Rendering.HDPipeline.HDLitGUI" ); +#endif + menu.ShowAsContext(); + } + } + EditorGUILayout.EndHorizontal(); + } + + private void AddMenuItem( GenericMenu menu, string newClass ) + { + menu.AddItem( new GUIContent( newClass ), m_customInspectorName.Equals( newClass ), OnSelection, newClass ); + } + + private void OnSelection( object newClass ) + { + m_customInspectorName = (string)newClass; + } + + protected void DrawShaderName() + { + EditorGUI.BeginChangeCheck(); + string newShaderName = EditorGUILayoutTextField( m_shaderNameContent, m_shaderName ); + if( EditorGUI.EndChangeCheck() ) + { + if( newShaderName.Length > 0 ) + { + newShaderName = UIUtils.RemoveShaderInvalidCharacters( newShaderName ); + } + else + { + newShaderName = Constants.DefaultShaderName; + } + ShaderName = newShaderName; + ContainerGraph.ParentWindow.UpdateTabTitle( ShaderName, true ); + } + m_shaderNameContent.tooltip = m_shaderName; + } + + public void DrawShaderKeywords() + { + if( m_addShaderKeywordStyle == null ) + m_addShaderKeywordStyle = UIUtils.PlusStyle; + + if( m_removeShaderKeywordStyle == null ) + m_removeShaderKeywordStyle = UIUtils.MinusStyle; + + if( m_smallAddShaderKeywordItemStyle == null ) + m_smallAddShaderKeywordItemStyle = UIUtils.PlusStyle; + + if( m_smallRemoveShaderKeywordStyle == null ) + m_smallRemoveShaderKeywordStyle = UIUtils.MinusStyle; + + EditorGUILayout.BeginHorizontal(); + { + m_shaderKeywordsFoldout = EditorGUILayout.Foldout( m_shaderKeywordsFoldout, ShaderKeywordsStr ); + + // Add keyword + if( GUILayout.Button( string.Empty, m_addShaderKeywordStyle ) ) + { + m_shaderKeywords.Insert( 0, "" ); + } + + //Remove keyword + if( GUILayout.Button( string.Empty, m_removeShaderKeywordStyle ) ) + { + m_shaderKeywords.RemoveAt( m_shaderKeywords.Count - 1 ); + } + } + EditorGUILayout.EndHorizontal(); + + if( m_shaderKeywordsFoldout ) + { + EditorGUI.indentLevel += 1; + int itemCount = m_shaderKeywords.Count; + int markedToDelete = -1; + for( int i = 0; i < itemCount; i++ ) + { + EditorGUILayout.BeginHorizontal(); + { + GUILayout.Label( " " ); + // Add new port + if( GUILayoutButton( string.Empty, m_smallAddShaderKeywordItemStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + m_shaderKeywords.Insert( i, "" ); + } + + //Remove port + if( GUILayoutButton( string.Empty, m_smallRemoveShaderKeywordStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + markedToDelete = i; + } + } + EditorGUILayout.EndHorizontal(); + } + if( markedToDelete > -1 ) + { + m_shaderKeywords.RemoveAt( markedToDelete ); + } + EditorGUI.indentLevel -= 1; + } + } + + public override void Draw( DrawInfo drawInfo ) + { + if( m_availableCategories == null ) + InitAvailableCategories(); + + base.Draw( drawInfo ); + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if( m_isMainOutputNode ) + { + if( m_masterNodeOnTex == null ) + { + m_masterNodeOnTex = UIUtils.MasterNodeOnTexture; + } + + if( m_masterNodeOffTex == null ) + { + m_masterNodeOffTex = UIUtils.MasterNodeOffTexture; + } + + if( m_gpuInstanceOnTex == null ) + { + m_gpuInstanceOnTex = UIUtils.GPUInstancedOnTexture; + } + + if( m_gpuInstanceOffTex == null ) + { + m_gpuInstanceOffTex = UIUtils.GPUInstancedOffTexture; + } + + m_masterNodeIconCoords = m_globalPosition; + m_masterNodeIconCoords.x += m_globalPosition.width - m_masterNodeOffTex.width * drawInfo.InvertedZoom; + m_masterNodeIconCoords.y += m_globalPosition.height - m_masterNodeOffTex.height * drawInfo.InvertedZoom; + m_masterNodeIconCoords.width = m_masterNodeOffTex.width * drawInfo.InvertedZoom; + m_masterNodeIconCoords.height = m_masterNodeOffTex.height * drawInfo.InvertedZoom; + + GUI.DrawTexture( m_masterNodeIconCoords, m_masterNodeOffTex ); + + if( m_gpuInstanceOnTex == null ) + { + m_gpuInstanceOnTex = UIUtils.GPUInstancedOnTexture; + } + } + } + + protected void DrawInstancedIcon( DrawInfo drawInfo ) + { + if( m_gpuInstanceOffTex == null || drawInfo.CurrentEventType != EventType.Repaint ) + return; + + m_masterNodeIconCoords = m_globalPosition; + m_masterNodeIconCoords.x += m_globalPosition.width - 5 - m_gpuInstanceOffTex.width * drawInfo.InvertedZoom; + m_masterNodeIconCoords.y += m_headerPosition.height; + m_masterNodeIconCoords.width = m_gpuInstanceOffTex.width * drawInfo.InvertedZoom; + m_masterNodeIconCoords.height = m_gpuInstanceOffTex.height * drawInfo.InvertedZoom; + GUI.DrawTexture( m_masterNodeIconCoords, m_gpuInstanceOffTex ); + } + //public override void DrawProperties() + //{ + // base.DrawProperties(); + // //EditorGUILayout.LabelField( _shaderTypeLabel ); + //} + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + //IOUtils.AddFieldValueToString( ref nodeInfo, m_isMainMasterNode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_shaderModelIdx ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_customInspectorName ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_shaderLOD ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_masterNodeCategory ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + if( UIUtils.CurrentShaderVersion() > 21 ) + { + m_shaderModelIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() < 17005 ) + { + string val = GetCurrentParam( ref nodeParams ); + if( m_customPrecision ) + { + if( val.Equals( "Fixed" ) ) + m_currentPrecisionType = PrecisionType.Half; + else + m_currentPrecisionType = (PrecisionType)Enum.Parse( typeof( PrecisionType ), val ); + } + else + { + m_currentPrecisionType = PrecisionType.Inherit; + } + } + } + + if( UIUtils.CurrentShaderVersion() > 2404 ) + { + m_customInspectorName = GetCurrentParam( ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 6101 ) + { + ShaderLOD = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() >= 13001 ) + { + //Debug.LogWarning( "Add correct version as soon as it is merged into master" ); + m_masterNodeCategory = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + if( activateNode ) + { + InputPort port = GetInputPortByUniqueId( portId ); + port.GetOutputNode().ActivateNode( UniqueId, portId, m_activeType ); + } + } + + public void FireMaterialChangedEvt() + { + if( OnMaterialUpdatedEvent != null ) + { + OnMaterialUpdatedEvent( this ); + } + } + + public void FireShaderChangedEvt() + { + if( OnShaderUpdatedEvent != null ) + OnShaderUpdatedEvent( this ); + } + + public void RegisterStandaloneFuntions() + { + List<CustomExpressionNode> nodes = m_containerGraph.CustomExpressionOnFunctionMode.NodesList; + int count = nodes.Count; + Dictionary<int, CustomExpressionNode> examinedNodes = new Dictionary<int, CustomExpressionNode>(); + for( int i = 0; i < count; i++ ) + { + if( nodes[ i ].AutoRegisterMode ) + { + nodes[ i ].CheckDependencies( ref m_currentDataCollector, ref examinedNodes ); + } + } + examinedNodes.Clear(); + examinedNodes = null; + } + + // What operation this node does + public virtual void Execute( Shader selectedShader ) + { + Execute( AssetDatabase.GetAssetPath( selectedShader ), false ); + } + + public virtual Shader Execute( string pathname, bool isFullPath ) + { + ContainerGraph.ResetNodesLocalVariables(); + m_currentDataCollector = new MasterNodeDataCollector( this ); + return null; + } + + protected void SortInputPorts( ref List<InputPort> vertexPorts, ref List<InputPort> fragmentPorts ) + { + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + if( m_inputPorts[ i ].Category == MasterNodePortCategory.Fragment || m_inputPorts[ i ].Category == MasterNodePortCategory.Debug ) + { + if( fragmentPorts != null ) + fragmentPorts.Add( m_inputPorts[ i ] ); + } + else + { + if( vertexPorts != null ) + vertexPorts.Add( m_inputPorts[ i ] ); + } + } + + if( fragmentPorts.Count > 0 ) + { + fragmentPorts.Sort( ( x, y ) => x.OrderId.CompareTo( y.OrderId ) ); + } + + if( vertexPorts.Count > 0 ) + { + vertexPorts.Sort( ( x, y ) => x.OrderId.CompareTo( y.OrderId ) ); + } + } + + protected void UpdateShaderAsset( ref string pathname, ref string shaderBody, bool isFullPath ) + { + // Generate Graph info + shaderBody += ContainerGraph.ParentWindow.GenerateGraphInfo(); + + //TODO: Remove current SaveDebugShader and uncomment SaveToDisk as soon as pathname is editable + if( !String.IsNullOrEmpty( pathname ) ) + { + IOUtils.StartSaveThread( shaderBody, ( isFullPath ? pathname : ( IOUtils.dataPath + pathname ) ) ); + } + else + { + IOUtils.StartSaveThread( shaderBody, Application.dataPath + "/AmplifyShaderEditor/Samples/Shaders/" + m_shaderName + ".shader" ); + } + + + if( CurrentShader == null ) + { + AssetDatabase.Refresh( ImportAssetOptions.ForceUpdate ); + CurrentShader = Shader.Find( ShaderName ); + } + //else + //{ + // // need to always get asset datapath because a user can change and asset location from the project window + // AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( m_currentShader ) ); + // //ShaderUtil.UpdateShaderAsset( m_currentShader, ShaderBody ); + // //ShaderImporter importer = (ShaderImporter)ShaderImporter.GetAtPath( AssetDatabase.GetAssetPath( CurrentShader ) ); + // //importer.SaveAndReimport(); + //} + + if( m_currentShader != null ) + { + m_currentDataCollector.UpdateShaderImporter( ref m_currentShader ); + if( m_currentMaterial != null ) + { + if( m_currentMaterial.shader != m_currentShader ) + m_currentMaterial.shader = m_currentShader; + + //m_currentDataCollector.UpdateMaterialOnPropertyNodes( m_currentMaterial ); + //This master node UpdateMaterial is needed on Standard Surface node to update its internal properties + UpdateMaterial( m_currentMaterial ); + + UIUtils.CurrentWindow.OutsideGraph.UpdateMaterialOnPropertyNodes( m_currentMaterial ); + + FireMaterialChangedEvt(); + // need to always get asset datapath because a user can change and asset location from the project window + //AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( m_currentMaterial ) ); + } + + } + + m_currentDataCollector.Destroy(); + m_currentDataCollector = null; + } + + + public void InvalidateMaterialPropertyCount() + { + m_lastCount = -1; + } + + private void RefreshVisibleList( ref List<PropertyNode> allNodes ) + { + // temp reference for lambda expression + List<PropertyNode> nodes = allNodes; + m_propertyNodesVisibleList.Clear(); + + for( int i = 0; i < nodes.Count; i++ ) + { + ReordenatorNode rnode = nodes[ i ] as ReordenatorNode; + if( ( rnode == null || !rnode.IsInside ) && ( !m_propertyNodesVisibleList.Exists( x => x.PropertyName.Equals( nodes[ i ].PropertyName ) ) ) ) + m_propertyNodesVisibleList.Add( nodes[ i ] ); + } + + m_propertyNodesVisibleList.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + } + + public void DrawMaterialInputs( GUIStyle toolbarstyle, bool style = true ) + { + m_propertyOrderChanged = false; + Color cachedColor = GUI.color; + GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, 0.5f ); + EditorGUILayout.BeginHorizontal( toolbarstyle ); + GUI.color = cachedColor; + + EditorGUI.BeginChangeCheck(); + if( style ) + { + ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedProperties = GUILayoutToggle( ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedProperties, PropertyOrderFoldoutStr, UIUtils.MenuItemToggleStyle ); + } + else + { + ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedProperties = GUILayoutToggle( ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedProperties, PropertyOrderTemplateFoldoutStr, UIUtils.MenuItemToggleStyle ); + } + + if( EditorGUI.EndChangeCheck() ) + { + EditorPrefs.SetBool( "ExpandedProperties", ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedProperties ); + } + + EditorGUILayout.EndHorizontal(); + if( !ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedProperties ) + return; + + cachedColor = GUI.color; + GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, ( EditorGUIUtility.isProSkin ? 0.5f : 0.25f ) ); + EditorGUILayout.BeginVertical( UIUtils.MenuItemBackgroundStyle ); + GUI.color = cachedColor; + + List<PropertyNode> nodes = UIUtils.PropertyNodesList(); + + if( nodes.Count != m_lastCount ) + { + RefreshVisibleList( ref nodes ); + m_lastCount = nodes.Count; + } + + if( m_propertyReordableList == null ) + { + m_propertyReordableList = new ReorderableList( m_propertyNodesVisibleList, typeof( PropertyNode ), true, false, false, false ) + { + headerHeight = 0, + footerHeight = 0, + showDefaultBackground = false, + + drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) => + { + var first = rect; + first.width *= 0.60f; + EditorGUI.LabelField( first, m_propertyNodesVisibleList[ index ].PropertyInspectorName ); + var second = rect; + second.width *= 0.4f; + second.x += first.width; + if( GUI.Button( second, m_propertyNodesVisibleList[ index ].PropertyName, new GUIStyle( "AssetLabel Partial" ) ) ) + { + UIUtils.FocusOnNode( m_propertyNodesVisibleList[ index ], 1, false ); + } + }, + + onReorderCallback = ( list ) => + { + ReorderList( ref nodes ); + m_propertyOrderChanged = true; + //RecursiveLog(); + } + }; + ReorderList( ref nodes ); + } + + if( m_propertyReordableList != null ) + { + if( m_propertyAdjustment == null ) + { + m_propertyAdjustment = new GUIStyle(); + m_propertyAdjustment.padding.left = 17; + } + EditorGUILayout.BeginVertical( m_propertyAdjustment ); + m_propertyReordableList.DoLayoutList(); + EditorGUILayout.EndVertical(); + } + EditorGUILayout.EndVertical(); + } + + public void ForceReordering() + { + List<PropertyNode> nodes = UIUtils.PropertyNodesList(); + + if( nodes.Count != m_lastCount ) + { + RefreshVisibleList( ref nodes ); + m_lastCount = nodes.Count; + } + + ReorderList( ref nodes ); + //RecursiveLog(); + } + + private void RecursiveLog() + { + List<PropertyNode> nodes = UIUtils.PropertyNodesList(); + nodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + for( int i = 0; i < nodes.Count; i++ ) + { + if( ( nodes[ i ] is ReordenatorNode ) ) + ( nodes[ i ] as ReordenatorNode ).RecursiveLog(); + else + Debug.Log( nodes[ i ].OrderIndex + " " + nodes[ i ].PropertyName ); + } + } + + private void ReorderList( ref List<PropertyNode> nodes ) + { + // clear lock list before reordering because of multiple sf being used + for( int i = 0; i < nodes.Count; i++ ) + { + ReordenatorNode rnode = nodes[ i ] as ReordenatorNode; + if( rnode != null ) + rnode.RecursiveClear(); + } + + int propoffset = 0; + int count = 0; + for( int i = 0; i < m_propertyNodesVisibleList.Count; i++ ) + { + ReordenatorNode renode = m_propertyNodesVisibleList[ i ] as ReordenatorNode; + if( renode != null ) + { + if( !renode.IsInside ) + { + m_propertyNodesVisibleList[ i ].OrderIndex = count + propoffset; + + if( renode.PropertyListCount > 0 ) + { + propoffset += renode.RecursiveCount(); + // the same reordenator can exist multiple times, apply ordering to all of them + for( int j = 0; j < nodes.Count; j++ ) + { + ReordenatorNode pnode = ( nodes[ j ] as ReordenatorNode ); + if( pnode != null && pnode.PropertyName.Equals( renode.PropertyName ) ) + { + pnode.OrderIndex = renode.RawOrderIndex; + pnode.RecursiveSetOrderOffset( renode.RawOrderIndex, true ); + } + } + } + else + { + count++; + } + } + else + { + m_propertyNodesVisibleList[ i ].OrderIndex = 0; + } + } + else + { + m_propertyNodesVisibleList[ i ].OrderIndex = count + propoffset; + count++; + } + } + } + + public void CopyPropertyListFrom( MasterNode masterNode ) + { + m_lastCount = masterNode.ReordableListLastCount; + m_propertyNodesVisibleList.Clear(); + m_propertyNodesVisibleList.AddRange( masterNode.PropertyNodesVisibleList ); + } + + public virtual void UpdateFromShader( Shader newShader ) { } + + public void ClearUpdateEvents() + { + OnShaderUpdatedEvent = null; + OnMaterialUpdatedEvent = null; + } + + public Material CurrentMaterial { get { return m_currentMaterial; } set { m_currentMaterial = value; } } + public Shader CurrentShader + { + set + { + if( value != null ) + { + SetName( value.name ); + } + + m_currentShader = value; + FireShaderChangedEvt(); + } + get { return m_currentShader; } + } + public virtual void OnRefreshLinkedPortsComplete() { } + public virtual void ReleaseResources() { } + public override void Destroy() + { + base.Destroy(); + OnMaterialUpdatedEvent = null; + OnShaderUpdatedEvent = null; + m_masterNodeOnTex = null; + m_masterNodeOffTex = null; + m_gpuInstanceOnTex = null; + m_gpuInstanceOffTex = null; + m_addShaderKeywordStyle = null; + m_removeShaderKeywordStyle = null; + m_smallAddShaderKeywordItemStyle = null; + m_smallRemoveShaderKeywordStyle = null; + m_shaderKeywords.Clear(); + m_shaderKeywords = null; + m_propertyReordableList = null; + m_propertyAdjustment = null; + if( m_currentDataCollector != null ) + { + m_currentDataCollector.Destroy(); + m_currentDataCollector = null; + } + } + + public static void OpenShaderBody( ref string result, string name ) + { + result += string.Format( "Shader \"{0}\"\n", name ) + "{\n"; + } + + public static void CloseShaderBody( ref string result ) + { + result += "}\n"; + } + + public static void OpenSubShaderBody( ref string result ) + { + result += "\n\tSubShader\n\t{\n"; + } + + public static void CloseSubShaderBody( ref string result ) + { + result += "\t}\n"; + } + + public static void AddShaderProperty( ref string result, string name, string value ) + { + result += string.Format( "\t{0} \"{1}\"\n", name, value ); + } + + public static void AddShaderPragma( ref string result, string value ) + { + result += string.Format( "\t\t#pragma {0}\n", value ); + } + + public static void AddRenderState( ref string result, string state, string stateParams ) + { + result += string.Format( "\t\t{0} {1}\n", state, stateParams ); + } + + public static void AddRenderTags( ref string result, string tags ) + { + result += string.Format( IndentationHelper, tags ); ; + } + + public static void AddShaderLOD( ref string result, int shaderLOD ) + { + if( shaderLOD > 0 ) + { + result += string.Format( ShaderLODFormat, shaderLOD ); + } + } + + public static void AddMultilineBody( ref string result, string[] lines ) + { + for( int i = 0; i < lines.Length; i++ ) + { + result += string.Format( IndentationHelper, lines[ i ] ); + } + } + + public static void OpenCGInclude( ref string result ) + { + result += "\t\tCGINCLUDE\n"; + } + + public static void OpenCGProgram( ref string result ) + { + result += "\t\tCGPROGRAM\n"; + } + + public static void CloseCGProgram( ref string result ) + { + result += "\n\t\tENDCG\n"; + } + + public string ShaderName + { + //get { return ( ( _isHidden ? "Hidden/" : string.Empty ) + ( String.IsNullOrEmpty( _shaderCategory ) ? "" : ( _shaderCategory + "/" ) ) + _shaderName ); } + get { return m_shaderName; } + set + { + m_shaderName = value; + string[] shaderNameArr = m_shaderName.Split( '/' ); + m_croppedShaderName = shaderNameArr[ shaderNameArr.Length - 1 ]; + + if( m_shaderNameIsTitle ) + m_content.text = GenerateClippedTitle( m_croppedShaderName ); + + m_sizeIsDirty = true; + } + } + public string CustomInspectorFormatted { get { return string.Format( CustomInspectorFormat, m_customInspectorName ); } } + public string CroppedShaderName { get { return m_croppedShaderName; } } + public AvailableShaderTypes CurrentMasterNodeCategory { get { return ( m_masterNodeCategory == 0 ) ? AvailableShaderTypes.SurfaceShader : AvailableShaderTypes.Template; } } + public int CurrentMasterNodeCategoryIdx { get { return m_masterNodeCategory; } } + public MasterNodeDataCollector CurrentDataCollector { get { return m_currentDataCollector; } set { m_currentDataCollector = value; } } + public List<PropertyNode> PropertyNodesVisibleList { get { return m_propertyNodesVisibleList; } } + public ReorderableList PropertyReordableList { get { return m_propertyReordableList; } } + public int ReordableListLastCount { get { return m_lastCount; } } + public MasterNodeCategoriesData CurrentCategoriesData { get { return m_availableCategories[ m_masterNodeCategory ]; } } + public int ShaderLOD + { + get { return m_shaderLOD; } + set + { + m_shaderLOD = Mathf.Max( 0, value ); + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs.meta new file mode 100644 index 00000000..8a8a9339 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7fc2c839ab9f3a045877b59493c51502 +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNodeDataCollector.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNodeDataCollector.cs new file mode 100644 index 00000000..d6fce5fd --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNodeDataCollector.cs @@ -0,0 +1,2038 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using System.Text.RegularExpressions; + +namespace AmplifyShaderEditor +{ + public class PropertyDataCollector + { + public int NodeId; + public int OrderIndex; + public string PropertyName; + public WirePortDataType DataType; + + public PropertyDataCollector( int nodeId, string propertyName, int orderIndex = -1 ) + { + NodeId = nodeId; + PropertyName = propertyName; + OrderIndex = orderIndex; + } + } + + public class InputCoordsCollector + { + public int NodeId; + public string CoordName; + public WirePortDataType DataType; + public PrecisionType Precision; + public int TextureSlot; + public int TextureIndex; + + public InputCoordsCollector( int nodeId, string coordName, WirePortDataType dataType, PrecisionType precision, int textureSlot, int textureIndex ) + { + NodeId = nodeId; + CoordName = coordName; + DataType = dataType; + Precision = precision; + TextureSlot = textureSlot; + TextureIndex = textureIndex; + } + } + + public class TextureDefaultsDataColector + { + private List<string> m_names = new List<string>(); + private List<Texture> m_values = new List<Texture>(); + public void AddValue( string newName, Texture newValue ) + { + m_names.Add( newName ); + m_values.Add( newValue ); + } + + public void Destroy() + { + m_names.Clear(); + m_names = null; + + m_values.Clear(); + m_values = null; + } + + public string[] NamesArr { get { return m_names.ToArray(); } } + public Texture[] ValuesArr { get { return m_values.ToArray(); } } + } + + public enum TextureChannelUsage + { + Not_Used, + Used, + Required + } + + public class MasterNodeDataCollector + { + private bool m_showDebugMessages = false; + private string m_input; + private string m_customInput; + private string m_properties; + private string m_instancedProperties; + private string m_instanceBlockName; + private string m_uniforms; + private string m_includes; + private string m_pragmas; + private string m_defines; + private string m_instructions; + private string m_localVariables; + private string m_vertexLocalVariables; + private string m_specialLocalVariables; + private string m_vertexData; + private string m_customOutput; + private string m_functions; + private string m_grabPass; + + private List<PropertyDataCollector> m_inputList; + private List<PropertyDataCollector> m_customInputList; + private List<PropertyDataCollector> m_propertiesList; + private List<PropertyDataCollector> m_instancedPropertiesList; + private List<PropertyDataCollector> m_dotsPropertiesList; + private List<PropertyDataCollector> m_dotsDefinesList; + private List<PropertyDataCollector> m_uniformsList; + private List<PropertyDataCollector> m_includesList; + private List<PropertyDataCollector> m_additionalDirectivesList; + //private List<PropertyDataCollector> m_tagsList; + private List<PropertyDataCollector> m_pragmasList; + private List<PropertyDataCollector> m_definesList; + private List<PropertyDataCollector> m_instructionsList; + private List<PropertyDataCollector> m_localVariablesList; + private List<PropertyDataCollector> m_vertexLocalVariablesList; + private List<PropertyDataCollector> m_specialLocalVariablesList; + private List<PropertyDataCollector> m_vertexDataList; + private List<PropertyDataCollector> m_customOutputList; + private List<PropertyDataCollector> m_functionsList; + private List<PropertyDataCollector> m_grabPassList; + private List<PropertyDataCollector> m_aboveUsePassesList; + private List<PropertyDataCollector> m_belowUsePassesList; + + private List<InputCoordsCollector> m_customShadowCoordsList; + private List<int> m_packSlotsList; + private string m_customAppDataItems; + + private Dictionary<string, PropertyDataCollector> m_inputDict; + private Dictionary<string, PropertyDataCollector> m_customInputDict; + private Dictionary<string, PropertyDataCollector> m_propertiesDict; + private Dictionary<string, PropertyDataCollector> m_instancedPropertiesDict; + private Dictionary<string, PropertyDataCollector> m_dotsPropertiesDict; + private Dictionary<string, PropertyDataCollector> m_uniformsDict; + private Dictionary<string, PropertyDataCollector> m_softRegisteredUniformsDict; + private Dictionary<string, PropertyDataCollector> m_includesDict; + private Dictionary<string, PropertyDataCollector> m_additionalDirectivesDict; + private Dictionary<string, string> m_includesExclusionDict; + + //private Dictionary<string, PropertyDataCollector> m_tagsDict; + private Dictionary<string, PropertyDataCollector> m_pragmasDict; + private Dictionary<string, PropertyDataCollector> m_definesDict; + private Dictionary<string, int> m_virtualCoordinatesDict; + private Dictionary<string, string> m_virtualVariablesDict; + private Dictionary<string, PropertyDataCollector> m_localVariablesDict; + private Dictionary<string, PropertyDataCollector> m_vertexLocalVariablesDict; + private Dictionary<string, PropertyDataCollector> m_specialLocalVariablesDict; + private Dictionary<string, PropertyDataCollector> m_vertexDataDict; + private Dictionary<string, PropertyDataCollector> m_customOutputDict; + private Dictionary<string, string> m_localFunctions; + private Dictionary<string, string> m_grabPassDict; + private Dictionary<string, string> m_usePassesDict; + private Dictionary<string, string> m_customAppDataItemsDict; + + private Dictionary<string, InputCoordsCollector> m_customShadowCoordsDict; + + private TextureChannelUsage[] m_requireTextureProperty = { TextureChannelUsage.Not_Used, TextureChannelUsage.Not_Used, TextureChannelUsage.Not_Used, TextureChannelUsage.Not_Used }; + + private bool m_dirtyAppData; + private bool m_dirtyInputs; + private bool m_dirtyCustomInputs; + private bool m_dirtyFunctions; + private bool m_dirtyProperties; + private bool m_dirtyInstancedProperties; + private bool m_dirtyUniforms; + private bool m_dirtyIncludes; + private bool m_dirtyPragmas; + private bool m_dirtyDefines; + private bool m_dirtyAdditionalDirectives; + private bool m_dirtyInstructions; + private bool m_dirtyLocalVariables; + private bool m_dirtyVertexLocalVariables; + private bool m_dirtySpecialLocalVariables; + private bool m_dirtyPerVertexData; + private bool m_dirtyNormal; + private bool m_forceNormal; + + private bool m_usingInternalData; + private bool m_usingVertexColor; + private bool m_usingWorldPosition; + private bool m_usingWorldNormal; + private bool m_usingScreenPos; + private bool m_usingWorldReflection; + private bool m_usingViewDirection; + private bool m_usingLightAttenuation; + private bool m_usingArrayDerivatives; + + private bool m_usingHigherSizeTexcoords; + private bool m_usingCustomScreenPos; + + private bool m_usingCustomOutlineColor; + private bool m_usingCustomOutlineWidth; + private bool m_usingCustomOutlineAlpha; + private int m_customOutlineSelectedAlpha = 0; + private bool m_usingCustomOutput; + + private bool m_safeNormalizeLightDir; + private bool m_safeNormalizeViewDir; + + private bool m_isOutlineDataCollector = false; + + private bool m_forceNormalIsDirty; + private bool m_grabPassIsDirty; + private bool m_tesselationActive; + + private Dictionary<int, PropertyNode> m_propertyNodes; + private MasterNode m_masterNode; + + private int m_availableVertexTempId = 0; + private int m_availableFragTempId = 0; + + private MasterNodePortCategory m_portCategory; + private PortGenType m_genType; + private RenderPath m_renderPath = RenderPath.All; + private NodeAvailability m_currentCanvasMode = NodeAvailability.SurfaceShader; + + //Templates specific data + private AvailableShaderTypes m_masterNodeCategory; + private List<string> m_vertexInputList; + private Dictionary<string, string> m_vertexInputDict; + private List<string> m_interpolatorsList; + private Dictionary<string, string> m_interpolatorsDict; + private List<string> m_vertexInterpDeclList; + private Dictionary<string, string> m_vertexInterpDeclDict; + private TemplateDataCollector m_templateDataCollector; + + public MasterNodeDataCollector( MasterNode masterNode ) : this() + { + m_masterNode = masterNode; + m_masterNodeCategory = masterNode.CurrentMasterNodeCategory; + m_currentCanvasMode = masterNode.ContainerGraph.CurrentCanvasMode; + } + + public MasterNodeDataCollector() + { + //m_masterNode = masterNode; + m_input = "struct Input\n\t\t{\n"; + m_customInput = "\t\tstruct SurfaceOutput{0}\n\t\t{\n"; + m_properties = IOUtils.PropertiesBegin;//"\tProperties\n\t{\n"; + m_uniforms = string.Empty; + m_instructions = string.Empty; + m_includes = string.Empty; + m_pragmas = string.Empty; + m_defines = string.Empty; + m_localVariables = string.Empty; + m_specialLocalVariables = string.Empty; + m_customOutput = string.Empty; + + m_inputList = new List<PropertyDataCollector>(); + m_customInputList = new List<PropertyDataCollector>(); + m_propertiesList = new List<PropertyDataCollector>(); + m_instancedPropertiesList = new List<PropertyDataCollector>(); + m_dotsPropertiesList = new List<PropertyDataCollector>(); + m_dotsDefinesList = new List<PropertyDataCollector>(); + m_uniformsList = new List<PropertyDataCollector>(); + m_includesList = new List<PropertyDataCollector>(); + m_additionalDirectivesList = new List<PropertyDataCollector>(); + //m_tagsList = new List<PropertyDataCollector>(); + m_pragmasList = new List<PropertyDataCollector>(); + m_definesList = new List<PropertyDataCollector>(); + m_instructionsList = new List<PropertyDataCollector>(); + m_localVariablesList = new List<PropertyDataCollector>(); + m_vertexLocalVariablesList = new List<PropertyDataCollector>(); + m_specialLocalVariablesList = new List<PropertyDataCollector>(); + m_vertexDataList = new List<PropertyDataCollector>(); + m_customOutputList = new List<PropertyDataCollector>(); + m_functionsList = new List<PropertyDataCollector>(); + m_grabPassList = new List<PropertyDataCollector>(); + m_aboveUsePassesList = new List<PropertyDataCollector>(); + m_belowUsePassesList = new List<PropertyDataCollector>(); + m_customAppDataItems = string.Empty; + m_customAppDataItemsDict = new Dictionary<string, string>(); + m_customShadowCoordsList = new List<InputCoordsCollector>(); + m_packSlotsList = new List<int>(); + + m_inputDict = new Dictionary<string, PropertyDataCollector>(); + m_customInputDict = new Dictionary<string, PropertyDataCollector>(); + + m_propertiesDict = new Dictionary<string, PropertyDataCollector>(); + m_instancedPropertiesDict = new Dictionary<string, PropertyDataCollector>(); + m_dotsPropertiesDict = new Dictionary<string, PropertyDataCollector>(); + m_uniformsDict = new Dictionary<string, PropertyDataCollector>(); + m_softRegisteredUniformsDict = new Dictionary<string, PropertyDataCollector>(); + m_includesDict = new Dictionary<string, PropertyDataCollector>(); + m_additionalDirectivesDict = new Dictionary<string, PropertyDataCollector>(); + m_includesExclusionDict = new Dictionary<string, string>(); + + //m_tagsDict = new Dictionary<string, PropertyDataCollector>(); + m_pragmasDict = new Dictionary<string, PropertyDataCollector>(); + m_definesDict = new Dictionary<string, PropertyDataCollector>(); + m_virtualCoordinatesDict = new Dictionary<string, int>(); + m_localVariablesDict = new Dictionary<string, PropertyDataCollector>(); + m_virtualVariablesDict = new Dictionary<string, string>(); + m_specialLocalVariablesDict = new Dictionary<string, PropertyDataCollector>(); + m_vertexLocalVariablesDict = new Dictionary<string, PropertyDataCollector>(); + m_localFunctions = new Dictionary<string, string>(); + m_vertexDataDict = new Dictionary<string, PropertyDataCollector>(); + m_customOutputDict = new Dictionary<string, PropertyDataCollector>(); + m_grabPassDict = new Dictionary<string, string>(); + m_usePassesDict = new Dictionary<string, string>(); + + m_customShadowCoordsDict = new Dictionary<string, InputCoordsCollector>(); + + m_dirtyAppData = false; + m_dirtyInputs = false; + m_dirtyCustomInputs = false; + m_dirtyProperties = false; + m_dirtyInstancedProperties = false; + m_dirtyUniforms = false; + m_dirtyInstructions = false; + m_dirtyIncludes = false; + m_dirtyPragmas = false; + m_dirtyDefines = false; + m_dirtyAdditionalDirectives = false; + m_dirtyLocalVariables = false; + m_dirtySpecialLocalVariables = false; + m_grabPassIsDirty = false; + + m_portCategory = MasterNodePortCategory.Fragment; + m_propertyNodes = new Dictionary<int, PropertyNode>(); + m_showDebugMessages = ( m_showDebugMessages && DebugConsoleWindow.DeveloperMode ); + + //templates + //m_masterNodeCategory = masterNode.CurrentMasterNodeCategory; + + m_vertexInputList = new List<string>(); + m_vertexInputDict = new Dictionary<string, string>(); + + m_interpolatorsList = new List<string>(); + m_interpolatorsDict = new Dictionary<string, string>(); + + m_vertexInterpDeclList = new List<string>(); + m_vertexInterpDeclDict = new Dictionary<string, string>(); + + m_templateDataCollector = new TemplateDataCollector(); + } + + public void SetChannelUsage( int channelId, TextureChannelUsage usage ) + { + if( channelId > -1 && channelId < 4 ) + m_requireTextureProperty[ channelId ] = usage; + } + + public TextureChannelUsage GetChannelUsage( int channelId ) + { + if( channelId > -1 && channelId < 4 ) + return m_requireTextureProperty[ channelId ]; + + return TextureChannelUsage.Not_Used; + } + public string SurfaceVertexStructure { get { return ( m_dirtyAppData ? Constants.CustomAppDataFullName : Constants.AppDataFullName ); } } + public void OpenPerVertexHeader( bool includeCustomData ) + { + string appData = "inout " + ( m_dirtyAppData ? Constants.CustomAppDataFullName : Constants.AppDataFullName ) + " "; + if( m_dirtyPerVertexData ) + return; + + m_dirtyPerVertexData = true; + if( m_tesselationActive ) + { + m_vertexData = "\t\tvoid " + Constants.VertexDataFunc + "( " + appData + Constants.VertexShaderInputStr + " )\n\t\t{\n"; + } + else + { + m_vertexData = "\t\tvoid " + Constants.VertexDataFunc + "( " + appData + Constants.VertexShaderInputStr + ( includeCustomData ? ( string.Format( ", out Input {0}", Constants.VertexShaderOutputStr ) ) : string.Empty ) + " )\n\t\t{\n"; + if( includeCustomData ) + m_vertexData += string.Format( "\t\t\tUNITY_INITIALIZE_OUTPUT( Input, {0} );\n", Constants.VertexShaderOutputStr ); + } + } + + public void ClosePerVertexHeader() + { + if( m_dirtyPerVertexData ) + m_vertexData += "\t\t}\n\n"; + } + + public void AddToVertexDisplacement( string value, VertexMode vertexMode ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( !m_dirtyPerVertexData ) + { + OpenPerVertexHeader( true ); + } + + switch( vertexMode ) + { + default: + case VertexMode.Relative: + { + m_vertexData += "\t\t\t" + Constants.VertexShaderInputStr + ".vertex.xyz += " + value + ";\n"; + } + break; + case VertexMode.Absolute: + { + m_vertexData += "\t\t\t" + Constants.VertexShaderInputStr + ".vertex.xyz = " + value + ";\n"; + } + break; + } + } + + + public void AddToVertexNormal( string value ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( !m_dirtyPerVertexData ) + { + OpenPerVertexHeader( true ); + } + + m_vertexData += "\t\t\t" + Constants.VertexShaderInputStr + ".normal = " + value + ";\n"; + } + + + public void AddVertexInstruction( string value, int nodeId = -1, bool addDelimiters = true ) + { + if( !m_dirtyPerVertexData && !IsOutlineDataCollector/*&& !(m_usingCustomOutlineColor || m_usingCustomOutlineWidth)*/ ) + { + OpenPerVertexHeader( true ); + } + if( !m_vertexDataDict.ContainsKey( value ) ) + { + m_vertexDataDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + m_vertexDataList.Add( m_vertexDataDict[ value ] ); + m_vertexData += ( addDelimiters ? ( "\t\t\t" + value + ";\n" ) : value ); + } + } + + public bool ContainsInput( string value ) + { + return m_inputDict.ContainsKey( value ); + } + + public void AddToInput( int nodeId, string interpName, WirePortDataType dataType, PrecisionType precision = PrecisionType.Float, bool addSemiColon = true ) + { + string value = UIUtils.PrecisionWirePortToCgType( precision, dataType ) + " " + interpName; + AddToInput( nodeId, value, addSemiColon ); + + if( !m_customShadowCoordsDict.ContainsKey( interpName ) ) + { + int slot = 0; + int index = 0; + int size = UIUtils.GetChannelsAmount( dataType ); + + if( m_packSlotsList.Count == 0 ) + m_packSlotsList.Add( 4 ); + + for( int i = 0; i < m_packSlotsList.Count; i++ ) + { + slot = i; + if( m_packSlotsList[ i ] >= size ) + { + index = 4 - m_packSlotsList[ i ]; + m_packSlotsList[ i ] -= size; + break; + } + else if( i == m_packSlotsList.Count - 1 ) + { + m_packSlotsList.Add( 4 ); + } + } + m_customShadowCoordsDict.Add( interpName, new InputCoordsCollector( nodeId, interpName, dataType, precision, slot, index ) ); + m_customShadowCoordsList.Add( m_customShadowCoordsDict[ interpName ] ); + } + } + + public void AddToInput( int nodeId, SurfaceInputs surfaceInput, PrecisionType precision = PrecisionType.Float, bool addSemiColon = true ) + { + switch( surfaceInput ) + { + case SurfaceInputs.VIEW_DIR: + UsingViewDirection = true; + break; + case SurfaceInputs.SCREEN_POS: + UsingScreenPos = true; + break; + case SurfaceInputs.WORLD_POS: + UsingWorldPosition = true; + break; + case SurfaceInputs.WORLD_REFL: + UsingWorldReflection = true; + break; + case SurfaceInputs.WORLD_NORMAL: + UsingWorldNormal = true; + break; + case SurfaceInputs.INTERNALDATA: + UsingInternalData = true; + break; + case SurfaceInputs.COLOR: + UsingVertexColor = true; + break; + } + + AddToInput( nodeId, UIUtils.GetInputDeclarationFromType( precision, surfaceInput ), addSemiColon ); + } + + /// <summary> + /// Direct access to inputs, plese use another overload + /// </summary> + /// <param name="nodeId"></param> + /// <param name="value"></param> + /// <param name="addSemiColon"></param> + public void AddToInput( int nodeId, string value, bool addSemiColon ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( !m_inputDict.ContainsKey( value ) ) + { + m_inputDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + m_inputList.Add( m_inputDict[ value ] ); + + m_input += "\t\t\t" + value + ( ( addSemiColon ) ? ( ";\n" ) : "\n" ); + m_dirtyInputs = true; + } + } + + public void CloseInputs() + { + m_input += "\t\t};"; + } + + public void ChangeCustomInputHeader( string value ) + { + m_customInput = m_customInput.Replace( "{0}", value ); + } + + public void AddToCustomInput( int nodeId, string value, bool addSemiColon ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( !m_customInputDict.ContainsKey( value ) ) + { + m_customInputDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + m_customInputList.Add( m_customInputDict[ value ] ); + m_customInput += "\t\t\t" + value + ( ( addSemiColon ) ? ( ";\n" ) : "\n" ); + m_dirtyCustomInputs = true; + } + } + + public void CloseCustomInputs() + { + m_customInput += "\t\t};"; + } + + + // Used by Template Master Node to add tabs into variable declaration + public void TabifyInstancedVars() + { + for( int i = 0; i < m_instancedPropertiesList.Count; i++ ) + { + m_instancedPropertiesList[ i ].PropertyName = '\t' + m_instancedPropertiesList[ i ].PropertyName; + } + } + + private int GetWeightForInstancedType( WirePortDataType type ) + { + switch( type ) + { + case WirePortDataType.INT: + case WirePortDataType.FLOAT: return -1; + case WirePortDataType.FLOAT2: return -2; + case WirePortDataType.FLOAT3: return -3; + case WirePortDataType.COLOR: + case WirePortDataType.FLOAT4: return -4; + case WirePortDataType.FLOAT3x3: return -9; + case WirePortDataType.FLOAT4x4: return -16; + default: + case WirePortDataType.OBJECT: + case WirePortDataType.SAMPLER1D: + case WirePortDataType.SAMPLER2D: + case WirePortDataType.SAMPLER3D: + case WirePortDataType.SAMPLERCUBE: + return 0; + } + } + + public void OptimizeInstancedProperties() + { + if( m_instancedPropertiesList.Count > 0 ) + { + m_instancedProperties = string.Empty; + m_instancedPropertiesList.Sort( ( x, y ) => { return GetWeightForInstancedType( x.DataType ).CompareTo( GetWeightForInstancedType( y.DataType ) ); } ); + int count = m_instancedPropertiesList.Count; + for( int i = 0; i < count; i++ ) + { + m_instancedProperties += m_instancedPropertiesList[ i ].PropertyName; + } + } + } + // Instanced properties + public void SetupInstancePropertiesBlock( string blockName ) + { + m_instanceBlockName = blockName; + if( IsTemplate ) + { + //if( DebugConsoleWindow.DeveloperMode ) + // Debug.LogWarning( "SetupInstancePropertiesBlock should not be used during template mode" ); + + return; + } + + OptimizeInstancedProperties(); + + if( m_dirtyInstancedProperties ) + { + m_instancedProperties = string.Format( IOUtils.InstancedPropertiesBeginTabs, blockName ) + m_instancedProperties + IOUtils.InstancedPropertiesEndTabs; + } + } + + public void AddToDotsProperties( WirePortDataType dataType, int nodeId, string value, int orderIndex, PrecisionType precision ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + string prop = string.Format( IOUtils.DotsInstancedPropertiesData, UIUtils.PrecisionWirePortToCgType( precision, dataType ), value ); + string define = string.Format( IOUtils.DotsInstancedDefinesData, UIUtils.PrecisionWirePortToCgType( precision, dataType ), value ); + + if( !m_dotsPropertiesDict.ContainsKey( value ) ) + { + PropertyDataCollector dataColl = new PropertyDataCollector( nodeId, prop, orderIndex ); + dataColl.DataType = dataType; + m_dotsPropertiesDict.Add( value, dataColl ); + m_dotsPropertiesList.Add( dataColl ); + + dataColl = new PropertyDataCollector( nodeId, define, orderIndex ); + m_dotsDefinesList.Add( dataColl ); + } + } + + public void AddToInstancedProperties( WirePortDataType dataType, int nodeId, string value, int orderIndex ) + { + if( string.IsNullOrEmpty( value ) ) + return; + string uniformValue = value.Contains( "uniform" ) ? value : "uniform " + value; + if( !m_instancedPropertiesDict.ContainsKey( value ) && + !m_uniformsDict.ContainsKey( value ) && + !m_uniformsDict.ContainsKey( uniformValue ) + ) + { + PropertyDataCollector dataColl = new PropertyDataCollector( nodeId, value, orderIndex ); + dataColl.DataType = dataType; + m_instancedPropertiesDict.Add( value, dataColl ); + m_instancedPropertiesList.Add( dataColl ); + m_instancedProperties += value; + m_dirtyInstancedProperties = true; + } + } + + public void CloseInstancedProperties() + { + if( m_dirtyInstancedProperties ) + { + m_instancedProperties += IOUtils.InstancedPropertiesEnd; + } + } + + // Properties + public void CopyPropertiesFromDataCollector( MasterNodeDataCollector dataCollector ) + { + if( dataCollector == null ) + return; + + int propertyCount = dataCollector.PropertiesList.Count; + for( int i = 0; i < propertyCount; i++ ) + { + AddToProperties( dataCollector.PropertiesList[ i ].NodeId, + dataCollector.PropertiesList[ i ].PropertyName, + dataCollector.PropertiesList[ i ].OrderIndex ); + } + + foreach( KeyValuePair<string, string> kvp in dataCollector.GrabPassDict ) + { + AddGrabPass( kvp.Value ); + } + + m_templateDataCollector.CopySRPPropertiesFromDataCollector( -1, dataCollector.TemplateDataCollectorInstance ); + } + + public void AddToProperties( int nodeId, string value, int orderIndex ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( !m_propertiesDict.ContainsKey( value ) ) + { + //Debug.Log( UIUtils ); + m_propertiesDict.Add( value, new PropertyDataCollector( nodeId, value, orderIndex ) ); + m_propertiesList.Add( m_propertiesDict[ value ] ); + m_properties += string.Format( IOUtils.PropertiesElement, value ); + m_dirtyProperties = true; + } + } + + public string BuildPropertiesString() + { + List<PropertyDataCollector> list = new List<PropertyDataCollector>( m_propertiesDict.Values ); + //for ( int i = 0; i < list.Count; i++ ) + //{ + // Debug.Log( list[ i ].OrderIndex + " " + list[ i ].PropertyName ); + //} + + list.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + CleanUpList( ref list ); + m_properties = IOUtils.PropertiesBegin; + for( int i = 0; i < list.Count; i++ ) + { + m_properties += string.Format( IOUtils.PropertiesElement, list[ i ].PropertyName ); + //Debug.Log() + } + m_properties += IOUtils.PropertiesEnd; + return m_properties; + } + + public bool ContainsProperty( string propertyName ) + { + // TODO: this needs to change, find the property should be dependant of have a "(" + List<PropertyDataCollector> list = new List<PropertyDataCollector>( m_propertiesDict.Values ); + return list.Find( x => x.PropertyName.Contains( propertyName+"(" ) ) != null; + } + + public string[] BuildUnformatedPropertiesStringArr() + { + List<PropertyDataCollector> list = new List<PropertyDataCollector>( m_propertiesDict.Values ); + list.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + CleanUpList( ref list ); + string[] arr = new string[ list.Count ]; + for( int i = 0; i < list.Count; i++ ) + { + arr[ i ] = list[ i ].PropertyName; + } + return arr; + } + //This clean up was set to remove Header attributes from shader functions which would be last on the property list + //Thus creating a label on the inspector with no properties below + public void CleanUpList( ref List<PropertyDataCollector> list ) + { + if( list.Count == 0 ) + return; + + if( list[ list.Count - 1 ].PropertyName.Contains( "[Header(" ) ) + { + //Check if this is a complete property or just a standalone header + Match match = Regex.Match( list[ list.Count - 1 ].PropertyName, TemplateHelperFunctions.PropertiesPatternG ); + if( !match.Success ) + { + list.RemoveAt( list.Count - 1 ); + CleanUpList( ref list ); + } + } + } + + public void CloseProperties() + { + if( m_dirtyProperties ) + { + m_properties += IOUtils.PropertiesEnd; + } + } + + public void AddUsePass( string value, bool above ) + { + if( m_usePassesDict.ContainsKey( value ) ) + return; + m_usePassesDict.Add( value, value ); + if( above ) + { + m_aboveUsePassesList.Add( new PropertyDataCollector( -1, value ) ); + } + else + { + m_belowUsePassesList.Add( new PropertyDataCollector( -1, value ) ); + } + } + + public void AddGrabPass( string value ) + { + if( m_grabPassDict.ContainsKey( value ) ) + return; + + m_grabPassDict.Add( value, value ); + + if( string.IsNullOrEmpty( value ) ) + { + if( !m_grabPassIsDirty ) + m_grabPass += IOUtils.GrabPassEmpty; + } + else + { + m_grabPass += IOUtils.GrabPassBegin + value + IOUtils.GrabPassEnd; + } + m_grabPassList.Add( new PropertyDataCollector( -1, m_grabPass.Replace( "\t", string.Empty ).Replace( "\n", string.Empty ) ) ); + m_grabPassIsDirty = true; + } + + // This is used by templates global variables to register already existing globals/properties + //public void SoftRegisterUniform( string dataName ) + //{ + // if( !m_uniformsDict.ContainsKey( dataName ) ) + // { + // m_uniformsDict.Add( dataName, new PropertyDataCollector( -1, dataName ) ); + // } + //} + + public string GenerateInstanced(PrecisionType precisionType, WirePortDataType dataType,string propertyName ) + { + if( IsSRP ) + { + return string.Format( IOUtils.LWSRPInstancedPropertiesElement, UIUtils.PrecisionWirePortToCgType( precisionType, dataType ), propertyName ); + } + else + { + return string.Format( IOUtils.InstancedPropertiesElement, UIUtils.PrecisionWirePortToCgType( precisionType, dataType ), propertyName ); + } + } + + public bool CheckIfSoftRegistered( string name ) + { + return m_softRegisteredUniformsDict.ContainsKey( name ); + } + + public void SoftRegisterUniform( TemplateShaderPropertyData data ) + { + bool excludeUniformKeyword = ( data.PropertyType == PropertyType.InstancedProperty ) || IsSRP; + + string uniformName = UIUtils.GenerateUniformName( excludeUniformKeyword, data.PropertyDataType, data.PropertyName ); + if( !m_uniformsDict.ContainsKey( uniformName ) ) + { + PropertyDataCollector newEntry = new PropertyDataCollector( -1, uniformName ); + m_uniformsDict.Add( uniformName, newEntry ); + m_softRegisteredUniformsDict.Add( uniformName, newEntry ); + } + + string instancedUniform = GenerateInstanced( PrecisionType.Float, data.PropertyDataType, data.PropertyName ); + if( !m_uniformsDict.ContainsKey( instancedUniform ) ) + { + PropertyDataCollector newEntry = new PropertyDataCollector( -1, instancedUniform ); + m_uniformsDict.Add( instancedUniform, newEntry ); + m_softRegisteredUniformsDict.Add( instancedUniform, newEntry ); + } + + instancedUniform = GenerateInstanced( PrecisionType.Half, data.PropertyDataType, data.PropertyName ); + if( !m_uniformsDict.ContainsKey( instancedUniform ) ) + { + PropertyDataCollector newEntry = new PropertyDataCollector( -1, instancedUniform ); + m_uniformsDict.Add( instancedUniform, newEntry ); + m_softRegisteredUniformsDict.Add( instancedUniform, newEntry ); + } + } + + public void AddToUniforms( int nodeId, string dataType, string dataName, bool checkSRPBatch = false, bool excludeUniform = false ) + { + if( string.IsNullOrEmpty( dataName ) || string.IsNullOrEmpty( dataType ) ) + return; + + string value = UIUtils.GenerateUniformName( IsSRP || excludeUniform, dataType, dataName ); + if( !m_uniformsDict.ContainsKey( value ) && !m_uniformsDict.ContainsKey( dataName ) ) + { + m_uniformsDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + if( IsSRP && checkSRPBatch ) + { + m_templateDataCollector.AddSRPBatcherProperty( nodeId, value ); + } + else + { + m_uniforms += "\t\t" + value + '\n'; + m_uniformsList.Add( m_uniformsDict[ value ] ); + } + m_dirtyUniforms = true; + } + } + + public void AddToUniforms( int nodeId, string value, bool checkSRPBatch = false ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( !m_uniformsDict.ContainsKey( value ) ) + { + m_uniformsDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + if( IsSRP && checkSRPBatch ) + { + m_templateDataCollector.AddSRPBatcherProperty( nodeId, value ); + } + else + { + m_uniforms += "\t\t" + value + '\n'; + m_uniformsList.Add( m_uniformsDict[ value ] ); + } + m_dirtyUniforms = true; + } + } + + public void AddToDirectives( string value, int orderIndex = -1 , AdditionalLineType type = AdditionalLineType.Custom ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + switch( type ) + { + case AdditionalLineType.Include:value = "#include " + value;break; + case AdditionalLineType.Define:value = "#define " + value; break; + case AdditionalLineType.Pragma:value = "#pragma " + value; break; + } + if( !m_additionalDirectivesDict.ContainsKey( value ) ) + { + PropertyDataCollector data = new PropertyDataCollector( -1, value, orderIndex ); + m_additionalDirectivesDict.Add( value, data ); + m_additionalDirectivesList.Add( data ); + m_dirtyAdditionalDirectives = true; + } + } + + public void AddToIncludes( int nodeId, string value ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( m_includesExclusionDict.ContainsKey( value ) ) + { + return; + } + + if( IsTemplate ) + { + if( m_templateDataCollector.HasDirective( AdditionalLineType.Include, value ) ) + return; + } + + if( !m_includesDict.ContainsKey( value ) ) + { + PropertyDataCollector data = new PropertyDataCollector( nodeId, "#include \"" + value + "\"" ); + m_includesDict.Add( value, data ); + m_includesList.Add( data ); + m_includes += "\t\t#include \"" + value + "\"\n"; + m_dirtyIncludes = true; + } + else + { + if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToIncludes:Attempting to add duplicate " + value, MessageSeverity.Warning ); + } + } + + + public void RemoveFromIncludes( string value ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( !m_includesExclusionDict.ContainsKey( value ) ) + { + m_includesExclusionDict.Add( value, value ); + } + + if( m_includesDict.ContainsKey( value ) ) + { + PropertyDataCollector data = m_includesDict[ value ]; + m_includesDict.Remove( value ); + m_includesList.Remove( data ); + m_dirtyIncludes = true; + string finalValueName = "\t\t#include \"" + value + "\"\n"; + m_includes = m_includes.Replace( finalValueName, string.Empty ); + } + } + + //public void AddToTags( int nodeId, string name, string value ) + //{ + // if( string.IsNullOrEmpty( name ) || string.IsNullOrEmpty( value ) ) + // return; + + // if( !m_tagsDict.ContainsKey( name ) ) + // { + // string finalResult = string.Format( "\"{0}\"=\"{1}\"", name, value ); + // m_tagsDict.Add( name, new PropertyDataCollector( nodeId, finalResult ) ); + // m_tagsList.Add( new PropertyDataCollector( nodeId, finalResult ) ); + // } + //} + + public void AddToPragmas( int nodeId, string value ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( IsTemplate ) + { + if( m_templateDataCollector.HasDirective( AdditionalLineType.Pragma, value ) ) + return; + } + + if( !m_pragmasDict.ContainsKey( value ) ) + { + m_pragmasDict.Add( value, new PropertyDataCollector( nodeId, "#pragma " + value ) ); + m_pragmasList.Add( m_pragmasDict[ value ] ); + m_pragmas += "\t\t#pragma " + value + "\n"; + m_dirtyPragmas = true; + } + else + { + if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToPragmas:Attempting to add duplicate " + value, MessageSeverity.Warning ); + } + } + + public void AddToDefines( int nodeId, string value, bool define = true ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( IsTemplate ) + { + if( m_templateDataCollector.HasDirective( AdditionalLineType.Define, value ) ) + return; + } + + if( !m_definesDict.ContainsKey( value ) ) + { + string defineValue = ( define ? "#define " : "#undef " ) + value; + m_definesDict.Add( value, new PropertyDataCollector( nodeId, defineValue ) ); + m_definesList.Add( m_definesDict[ value ] ); + m_defines += "\t\t" + defineValue + "\n"; + m_dirtyDefines = true; + } + else + { + if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToDefines:Attempting to add duplicate " + value, MessageSeverity.Warning ); + } + } + + public int GetVirtualCoordinatesId( int nodeId, string coord, string lodBias ) + { + if( !m_virtualCoordinatesDict.ContainsKey( coord ) ) + { + m_virtualCoordinatesDict.Add( coord, nodeId ); + AddLocalVariable( nodeId, "VirtualCoord " + Constants.VirtualCoordNameStr + nodeId + " = VTComputeVirtualCoord" + lodBias + "(" + coord + ");" ); + return nodeId; + } + else + { + int fetchedId = 0; + m_virtualCoordinatesDict.TryGetValue( coord, out fetchedId ); + return fetchedId; + } + } + + public bool AddToLocalVariables( MasterNodePortCategory category, int nodeId, PrecisionType precisionType, WirePortDataType type, string varName, string varValue ) + { + if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) ) + return false; + + string value = UIUtils.PrecisionWirePortToCgType( precisionType, type ) + " " + varName + " = " + varValue + ";"; + return AddToLocalVariables( category, nodeId, value ); + } + + public bool AddToLocalVariables( int nodeId, PrecisionType precisionType, WirePortDataType type, string varName, string varValue ) + { + if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) ) + return false; + + string value = UIUtils.PrecisionWirePortToCgType( precisionType, type ) + " " + varName + " = " + varValue + ";"; + return AddToLocalVariables( nodeId, value ); + } + + public bool AddToLocalVariables( MasterNodePortCategory category, int nodeId, string value, bool ignoreDuplicates = false ) + { + if( string.IsNullOrEmpty( value ) ) + return false; + + switch( category ) + { + case MasterNodePortCategory.Vertex: + case MasterNodePortCategory.Tessellation: + { + return AddToVertexLocalVariables( nodeId, value, ignoreDuplicates ); + } + case MasterNodePortCategory.Fragment: + case MasterNodePortCategory.Debug: + { + return AddToLocalVariables( nodeId, value, ignoreDuplicates ); + } + } + + return false; + } + + public bool AddLocalVariable( int nodeId, string customType, string varName, string varValue ) + { + if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) ) + return false; + + string value = customType + " " + varName + " = " + varValue + ";"; + return AddLocalVariable( nodeId, value ); + } + + public bool AddLocalVariable( int nodeId, PrecisionType precisionType, WirePortDataType type, string varName, string varValue ) + { + if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) ) + return false; + + string value = UIUtils.PrecisionWirePortToCgType( precisionType, type ) + " " + varName + " = " + varValue + ";"; + return AddLocalVariable( nodeId, value ); + } + + public bool AddLocalVariable( int nodeId, string name, string value, bool ignoreDuplicates = false , bool addSemiColon = false ) + { + string finalValue = addSemiColon ? name + " = " + value + ";" : name + " = " + value; + return AddLocalVariable( nodeId, finalValue, ignoreDuplicates ); + } + + public bool AddLocalVariable( int nodeId, string value, bool ignoreDuplicates = false ) + { + if( string.IsNullOrEmpty( value ) ) + return false; + + switch( m_portCategory ) + { + case MasterNodePortCategory.Vertex: + case MasterNodePortCategory.Tessellation: + { + return AddToVertexLocalVariables( nodeId, value, ignoreDuplicates ); + } + case MasterNodePortCategory.Fragment: + case MasterNodePortCategory.Debug: + { + return AddToLocalVariables( nodeId, value, ignoreDuplicates ); + } + } + + return false; + } + + public string AddVirtualLocalVariable( int nodeId, string variable, string value ) + { + if( string.IsNullOrEmpty( value ) ) + return string.Empty; + + string result = string.Empty; + + //switch ( m_portCategory ) + //{ + //case MasterNodePortCategory.Vertex: + //case MasterNodePortCategory.Tessellation: + //{ + //} + //break; + //case MasterNodePortCategory.Fragment: + //case MasterNodePortCategory.Debug: + //{ + if( !m_virtualVariablesDict.ContainsKey( value ) ) + { + m_virtualVariablesDict.Add( value, variable ); + result = variable; + } + else + { + m_virtualVariablesDict.TryGetValue( value, out result ); + } + //} + //break; + //} + + return result; + } + + public void AddCodeComments( bool forceForwardSlash, params string[] comments ) + { + if( m_portCategory == MasterNodePortCategory.Tessellation || m_portCategory == MasterNodePortCategory.Vertex ) + { + AddToVertexLocalVariables( 0, IOUtils.CreateCodeComments( forceForwardSlash, comments ) ); + } + else + { + AddToLocalVariables( 0, IOUtils.CreateCodeComments( forceForwardSlash, comments ) ); + } + } + + public bool HasLocalVariable( string value ) + { + switch( m_portCategory ) + { + case MasterNodePortCategory.Vertex: + case MasterNodePortCategory.Tessellation: + { + return m_vertexLocalVariablesDict.ContainsKey( value ); + } + case MasterNodePortCategory.Fragment: + case MasterNodePortCategory.Debug: + { + if( m_usingCustomOutput ) + { + return m_customOutputDict.ContainsKey( value ); + } + else + { + return m_localVariablesDict.ContainsKey( value ); + } + } + } + return false; + } + + public bool AddToLocalVariables( int nodeId, string value, bool ignoreDuplicates = false ) + { + if( string.IsNullOrEmpty( value ) ) + return false; + + if( m_usingCustomOutput ) + { + if( !m_customOutputDict.ContainsKey( value ) || ignoreDuplicates ) + { + if( !m_customOutputDict.ContainsKey( value ) ) + m_customOutputDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + + m_customOutputList.Add( m_customOutputDict[ value ] ); + m_customOutput += "\t\t\t" + value + '\n'; + return true; + } + else + { + if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning ); + } + } + else + { + if( !m_localVariablesDict.ContainsKey( value ) || ignoreDuplicates ) + { + if( !m_localVariablesDict.ContainsKey( value ) ) + m_localVariablesDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + + m_localVariablesList.Add( m_localVariablesDict[ value ] ); + AddToSpecialLocalVariables( nodeId, value, ignoreDuplicates ); + return true; + } + else + { + if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning ); + } + } + return false; + } + + public void AddToSpecialLocalVariables( int nodeId, string value, bool ignoreDuplicates = false ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + if( m_usingCustomOutput ) + { + if( !m_customOutputDict.ContainsKey( value ) || ignoreDuplicates ) + { + if( !m_customOutputDict.ContainsKey( value ) ) + m_customOutputDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + + m_customOutputList.Add( m_customOutputDict[ value ] ); + m_customOutput += "\t\t\t" + value + '\n'; + m_dirtySpecialLocalVariables = true; + } + else + { + if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToSpecialLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning ); + } + } + else + { + if( !m_specialLocalVariablesDict.ContainsKey( value ) || ignoreDuplicates ) + { + if( !m_specialLocalVariablesDict.ContainsKey( value ) ) + m_specialLocalVariablesDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + + m_specialLocalVariablesList.Add( m_specialLocalVariablesDict[ value ] ); + m_specialLocalVariables += "\t\t\t" + value + '\n'; + m_dirtySpecialLocalVariables = true; + } + else + { + if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToSpecialLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning ); + } + } + } + + public void ClearSpecialLocalVariables() + { + //m_specialLocalVariablesDict.Clear(); + m_specialLocalVariables = string.Empty; + m_dirtySpecialLocalVariables = false; + } + + public bool AddToVertexLocalVariables( int nodeId, string varName, string varValue ) + { + if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) ) + return false; + + string value = varName + " = " + varValue + ";"; + return AddToVertexLocalVariables( nodeId, value ); + } + + public bool AddToVertexLocalVariables( int nodeId, PrecisionType precisionType, WirePortDataType type, string varName, string varValue ) + { + if( string.IsNullOrEmpty( varName ) || string.IsNullOrEmpty( varValue ) ) + return false; + + string value = UIUtils.PrecisionWirePortToCgType( precisionType, type ) + " " + varName + " = " + varValue + ";"; + return AddToVertexLocalVariables( nodeId, value ); + } + + public bool AddToVertexLocalVariables( int nodeId, string value, bool ignoreDuplicates = false ) + { + if( string.IsNullOrEmpty( value ) ) + return false; + + if( !m_vertexLocalVariablesDict.ContainsKey( value ) || ignoreDuplicates ) + { + if( !m_vertexLocalVariablesDict.ContainsKey( value ) ) + m_vertexLocalVariablesDict.Add( value, new PropertyDataCollector( nodeId, value ) ); + + m_vertexLocalVariablesList.Add( m_vertexLocalVariablesDict[ value ] ); + m_vertexLocalVariables += "\t\t\t" + value + '\n'; + m_dirtyVertexLocalVariables = true; + return true; + } + else + { + if( m_showDebugMessages ) UIUtils.ShowMessage( "AddToVertexLocalVariables:Attempting to add duplicate " + value, MessageSeverity.Warning ); + } + + return false; + } + + public void ClearVertexLocalVariables() + { + //m_vertexLocalVariablesDict.Clear(); + m_vertexLocalVariables = string.Empty; + m_dirtyVertexLocalVariables = false; + } + + + public bool CheckFunction( string header ) + { + return m_localFunctions.ContainsKey( header ); + } + + public string AddFunctions( string header, string body, params object[] inParams ) + { + if( !m_localFunctions.ContainsKey( header ) ) + { + m_localFunctions.Add( header, body ); + m_functionsList.Add( new PropertyDataCollector( -1, body.Replace( "\t\t", string.Empty ) ) ); + m_functions += "\n" + body + "\n"; + m_dirtyFunctions = true; + } + + return String.Format( header, inParams ); + } + + public string AddFunctions( string header, string[] bodyLines, bool addNewLine, params object[] inParams ) + { + if( !m_localFunctions.ContainsKey( header ) ) + { + string body = string.Empty; + for( int i = 0; i < bodyLines.Length; i++ ) + { + body += ( m_masterNodeCategory == AvailableShaderTypes.Template ) ? bodyLines[ i ] : "\t\t" + bodyLines[ i ]; + if( addNewLine ) + body += '\n'; + } + + m_localFunctions.Add( header, body ); + m_functionsList.Add( new PropertyDataCollector( -1, body ) ); + m_functions += "\n" + body + "\n"; + m_dirtyFunctions = true; + } + + return String.Format( header, inParams ); + } + + public bool HasFunction( string functionId ) + { + return m_localFunctions.ContainsKey( functionId ); + } + + public void AddFunction( string functionId, string body ) + { + if( !m_localFunctions.ContainsKey( functionId ) ) + { + m_functionsList.Add( new PropertyDataCollector( -1, body ) ); + + m_localFunctions.Add( functionId, body ); + m_functions += "\n" + body + "\n"; + m_dirtyFunctions = true; + } + } + + public void AddFunction( string functionId, string[] bodyLines, bool addNewline ) + { + if( !m_localFunctions.ContainsKey( functionId ) ) + { + string body = string.Empty; + for( int i = 0; i < bodyLines.Length; i++ ) + { + body += ( m_masterNodeCategory == AvailableShaderTypes.Template ) ? bodyLines[ i ] : "\t\t" + bodyLines[ i ]; + if( addNewline ) + body += '\n'; + + } + m_functionsList.Add( new PropertyDataCollector( -1, body ) ); + + m_localFunctions.Add( functionId, body ); + m_functions += "\n" + body + "\n"; + m_dirtyFunctions = true; + } + } + + public void AddInstructions( string value, bool addTabs = false, bool addLineEnding = false ) + { + m_instructionsList.Add( new PropertyDataCollector( -1, value ) ); + m_instructions += addTabs ? "\t\t\t" + value : value; + if( addLineEnding ) + { + m_instructions += '\n'; + } + m_dirtyInstructions = true; + } + + + public void AddInstructions( bool addLineEnding, bool addTabs, params string[] values ) + { + for( int i = 0; i < values.Length; i++ ) + { + m_instructionsList.Add( new PropertyDataCollector( -1, values[ i ] ) ); + m_instructions += addTabs ? "\t\t\t" + values[ i ] : values[ i ]; + if( addLineEnding ) + { + m_instructions += '\n'; + } + } + m_dirtyInstructions = true; + } + + + + public void AddToStartInstructions( string value ) + { + if( string.IsNullOrEmpty( value ) ) + return; + + m_instructions = value + m_instructions; + m_dirtyInstructions = true; + } + + public void ResetInstructions() + { + m_instructionsList.Clear(); + m_instructions = string.Empty; + m_dirtyInstructions = false; + } + + + public void ResetVertexInstructions() + { + m_vertexDataList.Clear(); + m_vertexData = string.Empty; + m_dirtyPerVertexData = false; + } + + public void AddPropertyNode( PropertyNode node ) + { + if( !m_propertyNodes.ContainsKey( node.UniqueId ) ) + { + m_propertyNodes.Add( node.UniqueId, node ); + } + } + + public void UpdateMaterialOnPropertyNodes( Material material ) + { + m_masterNode.UpdateMaterial( material ); + foreach( KeyValuePair<int, PropertyNode> kvp in m_propertyNodes ) + { + kvp.Value.UpdateMaterial( material ); + } + } + + public void AddToVertexInput( string value ) + { + if( !m_vertexInputDict.ContainsKey( value ) ) + { + m_vertexInputDict.Add( value, value ); + m_vertexInputList.Add( value ); + } + } + + public void AddToInterpolators( string value ) + { + if( !m_interpolatorsDict.ContainsKey( value ) ) + { + m_interpolatorsDict.Add( value, value ); + m_interpolatorsList.Add( value ); + } + } + + public void AddToVertexInterpolatorsDecl( string value ) + { + if( !m_vertexInterpDeclDict.ContainsKey( value ) ) + { + m_vertexInterpDeclDict.Add( value, value ); + m_vertexInterpDeclList.Add( value ); + } + } + + public void UpdateShaderImporter( ref Shader shader ) + { + ShaderImporter importer = (ShaderImporter)ShaderImporter.GetAtPath( AssetDatabase.GetAssetPath( shader ) ); + if( m_propertyNodes.Count > 0 ) + { + try + { + bool hasContents = false; + TextureDefaultsDataColector defaultCol = new TextureDefaultsDataColector(); + foreach( KeyValuePair<int, PropertyNode> kvp in m_propertyNodes ) + { + hasContents = kvp.Value.UpdateShaderDefaults( ref shader, ref defaultCol ) || hasContents; + } + + if( hasContents ) + { + importer.SetDefaultTextures( defaultCol.NamesArr, defaultCol.ValuesArr ); + defaultCol.Destroy(); + defaultCol = null; + } + } + catch( Exception e ) + { + Debug.LogException( e ); + } + } + importer.SaveAndReimport(); + } + + public void AddCustomAppData( string value ) + { + if( m_customAppDataItemsDict.ContainsKey( value ) ) + return; + + m_customAppDataItemsDict.Add( value, value ); + m_customAppDataItems += "\t\t\t" + value + "\n"; + m_dirtyAppData = true; + } + public string CustomAppDataName { get { return m_dirtyAppData ? Constants.CustomAppDataFullName : Constants.AppDataFullName; } } + + public string CustomAppData + { + get + { + if( m_dirtyPerVertexData ) + return Constants.CustomAppDataFullBody + m_customAppDataItems + "\t\t};\n"; + + return string.Empty; + } + } + + public void Destroy() + { + m_masterNode = null; + + m_customAppDataItemsDict.Clear(); + m_customAppDataItemsDict = null; + + m_inputList.Clear(); + m_inputList = null; + + m_customInputList.Clear(); + m_customInputList = null; + + m_propertiesList.Clear(); + m_propertiesList = null; + + m_instancedPropertiesList.Clear(); + m_instancedPropertiesList = null; + + m_dotsPropertiesList.Clear(); + m_dotsPropertiesList = null; + + m_dotsDefinesList.Clear(); + m_dotsDefinesList = null; + + m_uniformsList.Clear(); + m_uniformsList = null; + + m_additionalDirectivesList.Clear(); + m_additionalDirectivesList = null; + + m_includesList.Clear(); + m_includesList = null; + + //m_tagsList.Clear(); + //m_tagsList = null; + + m_pragmasList.Clear(); + m_pragmasList = null; + + m_definesList.Clear(); + m_definesList = null; + + m_instructionsList.Clear(); + m_instructionsList = null; + + m_localVariablesList.Clear(); + m_localVariablesList = null; + + m_vertexLocalVariablesList.Clear(); + m_vertexLocalVariablesList = null; + + m_specialLocalVariablesList.Clear(); + m_specialLocalVariablesList = null; + + m_vertexDataList.Clear(); + m_vertexDataList = null; + + m_customOutputList.Clear(); + m_customOutputList = null; + + m_functionsList.Clear(); + m_functionsList = null; + + m_grabPassList.Clear(); + m_grabPassList = null; + + m_aboveUsePassesList.Clear(); + m_aboveUsePassesList = null; + + m_belowUsePassesList.Clear(); + m_belowUsePassesList = null; + + m_grabPassDict.Clear(); + m_grabPassDict = null; + + m_usePassesDict.Clear(); + m_usePassesDict = null; + + m_propertyNodes.Clear(); + m_propertyNodes = null; + + m_inputDict.Clear(); + m_inputDict = null; + + m_customInputDict.Clear(); + m_customInputDict = null; + + m_propertiesDict.Clear(); + m_propertiesDict = null; + + m_dotsPropertiesDict.Clear(); + m_dotsPropertiesDict = null; + + m_instancedPropertiesDict.Clear(); + m_instancedPropertiesDict = null; + + m_uniformsDict.Clear(); + m_uniformsDict = null; + + m_softRegisteredUniformsDict.Clear(); + m_softRegisteredUniformsDict = null; + + m_includesDict.Clear(); + m_includesDict = null; + + m_additionalDirectivesDict.Clear(); + m_additionalDirectivesDict = null; + + m_includesExclusionDict.Clear(); + m_includesExclusionDict = null; + //m_tagsDict.Clear(); + //m_tagsDict = null; + + m_pragmasDict.Clear(); + m_pragmasDict = null; + + m_definesDict.Clear(); + m_definesDict = null; + + m_virtualCoordinatesDict.Clear(); + m_virtualCoordinatesDict = null; + + m_virtualVariablesDict.Clear(); + m_virtualVariablesDict = null; + + m_localVariablesDict.Clear(); + m_localVariablesDict = null; + + m_specialLocalVariablesDict.Clear(); + m_specialLocalVariablesDict = null; + + m_vertexLocalVariablesDict.Clear(); + m_vertexLocalVariablesDict = null; + + m_localFunctions.Clear(); + m_localFunctions = null; + + m_vertexDataDict.Clear(); + m_vertexDataDict = null; + + m_customOutputDict.Clear(); + m_customOutputDict = null; + + //templates + m_vertexInputList.Clear(); + m_vertexInputList = null; + + m_vertexInputDict.Clear(); + m_vertexInputDict = null; + + m_interpolatorsList.Clear(); + m_interpolatorsList = null; + + m_interpolatorsDict.Clear(); + m_interpolatorsDict = null; + + m_vertexInterpDeclList.Clear(); + m_vertexInterpDeclList = null; + + m_vertexInterpDeclDict.Clear(); + m_vertexInterpDeclDict = null; + + m_templateDataCollector.Destroy(); + m_templateDataCollector = null; + + m_customShadowCoordsDict.Clear(); + m_customShadowCoordsDict = null; + + m_customShadowCoordsList.Clear(); + m_customShadowCoordsDict = null; + + m_packSlotsList.Clear(); + m_packSlotsList = null; + } + + public string Inputs { get { return m_input; } } + public string CustomInput { get { return m_customInput; } } + public string Properties { get { return m_properties; } } + public string InstanceBlockName { get { return m_instanceBlockName; } } + public string InstancedProperties { get { return m_instancedProperties; } } + public string Uniforms { get { return m_uniforms; } } + public string Instructions { get { return m_instructions; } } + public string Includes { get { return m_includes; } } + public string Pragmas { get { return m_pragmas; } } + public string Defines { get { return m_defines; } } + public string LocalVariables { get { return m_localVariables; } } + public string SpecialLocalVariables { get { return m_specialLocalVariables; } } + public string VertexLocalVariables { get { return m_vertexLocalVariables; } } + //public string VertexLocalVariablesFromList + //{ + // get + // { + // string result = string.Empty; + // int count = m_vertexLocalVariablesList.Count; + // for( int i = 0; i < count; i++ ) + // { + // result += m_vertexLocalVariablesList[ i ].PropertyName + "\n"; + // } + // return result; + // } + //} + public string VertexData { get { return m_vertexData; } } + public string CustomOutput { get { return m_customOutput; } } + public string Functions { get { return m_functions; } } + public string GrabPass { get { return m_grabPass; } } + public bool DirtyAppData { get { return m_dirtyAppData; } } + public bool DirtyInstructions { get { return m_dirtyInstructions; } } + public bool DirtyUniforms { get { return m_dirtyUniforms; } } + public bool DirtyProperties { get { return m_dirtyProperties; } } + public bool DirtyInstancedProperties { get { return m_dirtyInstancedProperties; } } + public bool DirtyInputs { get { return m_dirtyInputs; } } + public bool DirtyCustomInput { get { return m_dirtyCustomInputs; } } + public bool DirtyIncludes { get { return m_dirtyIncludes; } } + public bool DirtyPragmas { get { return m_dirtyPragmas; } } + public bool DirtyDefines { get { return m_dirtyDefines; } } + public bool DirtyAdditionalDirectives { get { return m_dirtyAdditionalDirectives; } } + public bool DirtyLocalVariables { get { return m_dirtyLocalVariables; } } + public bool DirtyVertexVariables { get { return m_dirtyVertexLocalVariables; } } + public bool DirtySpecialLocalVariables { get { return m_dirtySpecialLocalVariables; } } + public bool DirtyPerVertexData { get { return m_dirtyPerVertexData; } } + public bool DirtyFunctions { get { return m_dirtyFunctions; } } + public bool DirtyGrabPass { get { return m_grabPassIsDirty; } } + public int LocalVariablesAmount { get { return m_localVariablesDict.Count; } } + public int SpecialLocalVariablesAmount { get { return m_specialLocalVariablesDict.Count; } } + public int VertexLocalVariablesAmount { get { return m_vertexLocalVariablesDict.Count; } } + public bool TesselationActive { set { m_tesselationActive = value; } get { return m_tesselationActive; } } + + + public int AvailableVertexTempId { get { return m_availableVertexTempId++; } } + public int AvailableFragTempId { get { return m_availableFragTempId++; } } + + /// <summary> + /// Returns true if Normal output is being written by something else + /// </summary> + public bool DirtyNormal + { + get { return m_dirtyNormal; } + set { m_dirtyNormal = value; } + } + + public bool IsFragmentCategory + { + get { return m_portCategory == MasterNodePortCategory.Fragment || m_portCategory == MasterNodePortCategory.Debug; } + } + + public MasterNodePortCategory PortCategory + { + get { return m_portCategory; } + set { m_portCategory = value; } + } + + public PortGenType GenType + { + get { return m_genType; } + set { m_genType = value; } + } + + public bool IsTemplate { get { return m_masterNodeCategory == AvailableShaderTypes.Template; } } + + public bool IsSRP { get { return ( TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.Lightweight || TemplateDataCollectorInstance.CurrentSRPType == TemplateSRPType.HD ); } } + + public AvailableShaderTypes MasterNodeCategory + { + get { return m_masterNodeCategory; } + set { m_masterNodeCategory = value; } + } + + /// <summary> + /// Forces write to Normal output when the output is not connected + /// </summary> + public bool ForceNormal + { + get { return m_forceNormal; } + set + { + if( value ) + { + if( !m_forceNormalIsDirty ) + { + m_forceNormal = value; + m_forceNormalIsDirty = value; + } + } + else + { + m_forceNormal = value; + } + } + } + + public bool UsingVertexColor + { + get { return m_usingVertexColor; } + set { m_usingVertexColor = value; } + } + + public bool UsingInternalData + { + get { return m_usingInternalData; } + set { m_usingInternalData = value; } + } + + public bool UsingScreenPos + { + get { return m_usingScreenPos; } + set { m_usingScreenPos = value; } + } + + public bool UsingCustomScreenPos + { + get { return m_usingCustomScreenPos; } + set { m_usingCustomScreenPos = value; } + } + + public bool UsingWorldNormal + { + get { return m_usingWorldNormal; } + set { m_usingWorldNormal = value; } + } + + public bool UsingWorldReflection + { + get { return m_usingWorldReflection; } + set { m_usingWorldReflection = value; } + } + + public bool UsingWorldPosition + { + get { return m_usingWorldPosition; } + set { m_usingWorldPosition = value; } + } + + public bool UsingViewDirection + { + get { return m_usingViewDirection; } + set { m_usingViewDirection = value; } + } + + public bool IsOutlineDataCollector + { + get { return m_isOutlineDataCollector; } + set { m_isOutlineDataCollector = value; } + } + + public bool UsingCustomOutlineColor + { + get { return m_usingCustomOutlineColor; } + set { m_usingCustomOutlineColor = value; } + } + + public bool UsingCustomOutlineWidth + { + get { return m_usingCustomOutlineWidth; } + set { m_usingCustomOutlineWidth = value; } + } + + public bool UsingCustomOutlineAlpha + { + get { return m_usingCustomOutlineAlpha; } + set { m_usingCustomOutlineAlpha = value; } + } + + public int CustomOutlineSelectedAlpha + { + get { return m_customOutlineSelectedAlpha; } + set { m_customOutlineSelectedAlpha = value; } + } + + public bool UsingCustomOutput + { + get { return m_usingCustomOutput; } + set { m_usingCustomOutput = value; } + } + + public bool UsingHigherSizeTexcoords + { + get { return m_usingHigherSizeTexcoords; } + set { m_usingHigherSizeTexcoords = value; } + } + + public bool UsingLightAttenuation + { + get { return m_usingLightAttenuation; } + set { m_usingLightAttenuation = value; } + } + + public bool UsingArrayDerivatives + { + get { return m_usingArrayDerivatives; } + set + { + if( value ) + { + MasterNodeDataCollector instance = this; + GeneratorUtils.AddCustomArraySamplingMacros( ref instance ); + } + + m_usingArrayDerivatives = value; + } + } + + public bool SafeNormalizeLightDir + { + get { return m_safeNormalizeLightDir; } + set { m_safeNormalizeLightDir = value; } + } + + public bool SafeNormalizeViewDir + { + get { return m_safeNormalizeViewDir; } + set { m_safeNormalizeViewDir = value; } + } + + public string StandardAdditionalDirectives + { + get + { + string body = string.Empty; + int count = m_additionalDirectivesList.Count; + for( int i = 0; i < count; i++ ) + { + body += "\t\t" + m_additionalDirectivesList[ i ].PropertyName + "\n"; + } + return body; + } + } + + public List<PropertyDataCollector> InputList { get { return m_inputList; } } + public List<PropertyDataCollector> CustomInputList { get { return m_customInputList; } } + public List<PropertyDataCollector> PropertiesList { get { return m_propertiesList; } } + public List<PropertyDataCollector> InstancedPropertiesList { get { return m_instancedPropertiesList; } } + public List<PropertyDataCollector> DotsPropertiesList { get { return m_dotsPropertiesList; } } + public List<PropertyDataCollector> DotsDefinesList { get { return m_dotsDefinesList; } } + public List<PropertyDataCollector> UniformsList { get { return m_uniformsList; } } + public List<PropertyDataCollector> MiscList { get { return m_additionalDirectivesList; } } + public List<PropertyDataCollector> BeforeNativeDirectivesList { get { return m_additionalDirectivesList.FindAll( obj => obj.OrderIndex < 0 ); } } + public List<PropertyDataCollector> AfterNativeDirectivesList { get { return m_additionalDirectivesList.FindAll( obj => obj.OrderIndex > 0 ); } } + public List<PropertyDataCollector> IncludesList { get { return m_includesList; } } + //public List<PropertyDataCollector> TagsList { get { return m_tagsList; } } + public List<PropertyDataCollector> PragmasList { get { return m_pragmasList; } } + public List<PropertyDataCollector> DefinesList { get { return m_definesList; } } + public List<PropertyDataCollector> InstructionsList { get { return m_instructionsList; } } + public List<PropertyDataCollector> LocalVariablesList { get { return m_localVariablesList; } } + public List<PropertyDataCollector> VertexLocalVariablesList { get { return m_vertexLocalVariablesList; } } + public List<PropertyDataCollector> SpecialLocalVariablesList { get { return m_specialLocalVariablesList; } } + public List<PropertyDataCollector> VertexDataList { get { return m_vertexDataList; } } + public List<PropertyDataCollector> CustomOutputList { get { return m_customOutputList; } } + public List<PropertyDataCollector> FunctionsList { get { return m_functionsList; } } + public List<PropertyDataCollector> GrabPassList { get { return m_grabPassList; } } + public Dictionary<string, string> GrabPassDict { get { return m_grabPassDict; } } + public List<PropertyDataCollector> AboveUsePassesList { get { return m_aboveUsePassesList; } } + public List<PropertyDataCollector> BelowUsePassesList { get { return m_belowUsePassesList; } } + public Dictionary<string, string> AboveUsePassesDict { get { return m_usePassesDict; } } + public List<InputCoordsCollector> CustomShadowCoordsList { get { return m_customShadowCoordsList; } } + public List<int> PackSlotsList { get { return m_packSlotsList; } } + public Dictionary<string, string> LocalFunctions { get { return m_localFunctions; } } + //Templates + public List<string> VertexInputList { get { return m_vertexInputList; } } + public List<string> InterpolatorList { get { return m_interpolatorsList; } } + public List<string> VertexInterpDeclList { get { return m_vertexInterpDeclList; } } + public TemplateDataCollector TemplateDataCollectorInstance { get { return m_templateDataCollector; } } + public RenderPath CurrentRenderPath + { + get { return m_renderPath; } + set { m_renderPath = value; } + } + + public NodeAvailability CurrentCanvasMode { get { return m_currentCanvasMode; } set { m_currentCanvasMode = value; } } + public TemplateSRPType CurrentSRPType + { + get + { + if( IsTemplate ) + return m_templateDataCollector.CurrentSRPType; + + return TemplateSRPType.BuiltIn; + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNodeDataCollector.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNodeDataCollector.cs.meta new file mode 100644 index 00000000..2b16420a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNodeDataCollector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d026d775ff431f34789437db3fb4abbb +timeCreated: 1481126959 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutlineOpHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutlineOpHelper.cs new file mode 100644 index 00000000..38137434 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutlineOpHelper.cs @@ -0,0 +1,629 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +using UnityEngine; +using UnityEditor; +using System; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + public enum OutlineMode + { + VertexOffset, + VertexScale + } + + [Serializable] + public sealed class OutlineOpHelper + { + + private string[] ModeTags = + { + "Tags{ }", + "Tags{ \"RenderType\" = \"TransparentCutout\" \"Queue\" = \"AlphaTest+0\"}", + "Tags{ \"RenderType\" = \"Transparent\" \"Queue\" = \"Transparent+0\"}", + "Tags{ \"RenderType\" = \"Transparent\" \"Queue\" = \"Transparent+0\" }" + }; + + private string[] ModePragma = + { + string.Empty, + string.Empty, + "alpha:fade ", + "alpha:premul " + }; + + + private readonly string OutlineSurfaceConfig = "#pragma surface outlineSurf Outline {0} keepalpha noshadow noambient novertexlights nolightmap nodynlightmap nodirlightmap nometa noforwardadd vertex:outlineVertexDataFunc "; + + private readonly string OutlineBodyStructBegin = "struct Input {"; + private readonly string OutlineBodyStructDefault = "\thalf filler;"; + private readonly string OutlineBodyStructEnd = "};"; + + private readonly string OutlineDefaultUniformColor = "half4 _ASEOutlineColor;"; + private readonly string OutlineDefaultUniformWidth = "half _ASEOutlineWidth;"; + private readonly string OutlineDefaultUniformColorInstanced = "UNITY_DEFINE_INSTANCED_PROP( half4, _ASEOutlineColor )"; + private readonly string OutlineDefaultUniformWidthInstanced = "UNITY_DEFINE_INSTANCED_PROP( half, _ASEOutlineWidth )"; + + private readonly string OutlineDefaultVertexHeader = "void outlineVertexDataFunc( inout appdata_full v, out Input o )\n\t\t{"; + private readonly string OutlineTessVertexHeader = "void outlineVertexDataFunc( inout appdata_full v )\n\t\t{"; + + private readonly string OutlineDefaultVertexOutputDeclaration = "\tUNITY_INITIALIZE_OUTPUT( Input, o );"; + + private readonly string[] OutlineSurfBody = { + "\to.Emission = _ASEOutlineColor.rgb;", + "\to.Alpha = 1;" + }; + + private readonly string[] OutlineSurfBodyInstanced = { + "\to.Emission = UNITY_ACCESS_INSTANCED_PROP(_ASEOutlineColor).rgb;", + "\to.Alpha = 1;" + }; + + private readonly string[] OutlineBodyDefaultSurfBegin = { + "}", + "inline half4 LightingOutline( SurfaceOutput s, half3 lightDir, half atten ) { return half4 ( 0,0,0, s.Alpha); }", + "void outlineSurf( Input i, inout SurfaceOutput o )", + "{"}; + + private readonly string[] OutlineBodyDefaultSurfEnd = { + "}", + "ENDCG", + "\n"}; + + //private const string OutlineInstancedHeader = "#pragma multi_compile_instancing"; + + //private readonly string[] OutlineBodyInstancedBegin = { + // "UNITY_INSTANCING_CBUFFER_START({0})", + // "\tUNITY_DEFINE_INSTANCED_PROP( half4, _ASEOutlineColor )", + // "\tUNITY_DEFINE_INSTANCED_PROP(half, _ASEOutlineWidth)", + // "UNITY_INSTANCING_CBUFFER_END", + // "void outlineVertexDataFunc( inout appdata_full v, out Input o )", + // "{", + // "\tUNITY_INITIALIZE_OUTPUT( Input, o );"}; + + //private readonly string[] OutlineBodyInstancedEnd = { + // "}", + // "inline half4 LightingOutline( SurfaceOutput s, half3 lightDir, half atten ) { return half4 ( 0,0,0, s.Alpha); }", + // "void outlineSurf( Input i, inout SurfaceOutput o ) { o.Emission = UNITY_ACCESS_INSTANCED_PROP( _ASEOutlineColor ).rgb; o.Alpha = 1; }", + // "ENDCG", + // "\n"}; + + private const string WidthVariableAccessInstanced = "UNITY_ACCESS_INSTANCED_PROP( _ASEOutlineWidth )"; + + private const string OutlineVertexOffsetMode = "\tv.vertex.xyz += ( v.normal * {0} );"; + private const string OutlineVertexScaleMode = "\tv.vertex.xyz *= ( 1 + {0});"; + private const string OutlineVertexCustomMode = "\tv.vertex.xyz += {0};"; + + private const string OutlineColorLabel = "Color"; + private const string OutlineWidthLabel = "Width"; + + private const string ColorPropertyName = "_ASEOutlineColor"; + private const string WidthPropertyName = "_ASEOutlineWidth"; + + + private const string WidthPropertyNameInstanced = "UNITY_ACCESS_INSTANCED_PROP(_ASEOutlineWidth)"; + + + + private const string ColorPropertyDec = "_ASEOutlineColor( \"Outline Color\", Color ) = ({0})"; + private const string OutlinePropertyDec = "_ASEOutlineWidth( \"Outline Width\", Float ) = {0}"; + + private const string ModePropertyStr = "Mode"; + + private const string NoFogStr = "No Fog"; + + private const string BillboardInstructionFormat = "\t{0};"; + + [SerializeField] + private Color m_outlineColor; + + [SerializeField] + private float m_outlineWidth; + + [SerializeField] + private bool m_enabled; + + [SerializeField] + private OutlineMode m_mode = OutlineMode.VertexOffset; + + [SerializeField] + private bool m_noFog = true; + + private CullMode m_cullMode = CullMode.Front; + private int m_zTestMode = 0; + private int m_zWriteMode = 0; + private bool m_dirtyInput = false; + private string m_inputs = string.Empty; + private List<PropertyDataCollector> m_inputList = new List<PropertyDataCollector>(); + private string m_uniforms = string.Empty; + private List<PropertyDataCollector> m_uniformList = new List<PropertyDataCollector>(); + private List<PropertyDataCollector> m_instancedPropertiesList = new List<PropertyDataCollector>(); + private string m_instancedProperties = string.Empty; + private string m_instructions = string.Empty; + private string m_functions = string.Empty; + private string m_includes = string.Empty; + private string m_pragmas = string.Empty; + private string m_defines = string.Empty; + private string m_vertexData = string.Empty; + private string m_grabPasses = string.Empty; + private Dictionary<string, string> m_localFunctions; + + //private OutlineMode m_customMode = OutlineMode.VertexOffset; + private int m_offsetMode = 0; + private bool m_customNoFog = true; + + public void Draw( ParentNode owner, GUIStyle toolbarstyle, Material mat ) + { + Color cachedColor = GUI.color; + GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, 0.5f ); + EditorGUILayout.BeginHorizontal( toolbarstyle ); + GUI.color = cachedColor; + owner.ContainerGraph.ParentWindow.InnerWindowVariables.OutlineActiveMode = owner.GUILayoutToggle( owner.ContainerGraph.ParentWindow.InnerWindowVariables.OutlineActiveMode , EditorVariablesManager.OutlineActiveMode.LabelName, UIUtils.MenuItemToggleStyle, GUILayout.ExpandWidth( true ) ); + EditorGUI.BeginChangeCheck(); + m_enabled = owner.EditorGUILayoutToggle( string.Empty, m_enabled, UIUtils.MenuItemEnableStyle, GUILayout.Width( 16 ) ); + if( EditorGUI.EndChangeCheck() ) + { + if( m_enabled ) + UpdateToMaterial( mat ); + + UIUtils.RequestSave(); + } + EditorGUILayout.EndHorizontal(); + + if( owner.ContainerGraph.ParentWindow.InnerWindowVariables.OutlineActiveMode ) + { + cachedColor = GUI.color; + GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, ( EditorGUIUtility.isProSkin ? 0.5f : 0.25f ) ); + EditorGUILayout.BeginVertical( UIUtils.MenuItemBackgroundStyle ); + GUI.color = cachedColor; + + EditorGUILayout.Separator(); + EditorGUI.BeginDisabledGroup( !m_enabled ); + + EditorGUI.indentLevel += 1; + { + m_mode = (OutlineMode)owner.EditorGUILayoutEnumPopup( ModePropertyStr, m_mode ); + + EditorGUI.BeginChangeCheck(); + m_outlineColor = owner.EditorGUILayoutColorField( OutlineColorLabel, m_outlineColor ); + if( EditorGUI.EndChangeCheck() && mat != null ) + { + if( mat.HasProperty( ColorPropertyName ) ) + { + mat.SetColor( ColorPropertyName, m_outlineColor ); + } + } + + EditorGUI.BeginChangeCheck(); + m_outlineWidth = owner.EditorGUILayoutFloatField( OutlineWidthLabel, m_outlineWidth ); + if( EditorGUI.EndChangeCheck() && mat != null ) + { + if( mat.HasProperty( WidthPropertyName ) ) + { + mat.SetFloat( WidthPropertyName, m_outlineWidth ); + } + } + + m_noFog = owner.EditorGUILayoutToggle( NoFogStr, m_noFog ); + } + + EditorGUI.indentLevel -= 1; + EditorGUI.EndDisabledGroup(); + EditorGUILayout.Separator(); + EditorGUILayout.EndVertical(); + } + } + + public void UpdateToMaterial( Material mat ) + { + if( mat == null ) + return; + + if( mat.HasProperty( ColorPropertyName ) ) + { + mat.SetColor( ColorPropertyName, m_outlineColor ); + } + + if( mat.HasProperty( WidthPropertyName ) ) + { + mat.SetFloat( WidthPropertyName, m_outlineWidth ); + } + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + m_enabled = Convert.ToBoolean( nodeParams[ index++ ] ); + m_outlineWidth = Convert.ToSingle( nodeParams[ index++ ] ); + m_outlineColor = IOUtils.StringToColor( nodeParams[ index++ ] ); + if( UIUtils.CurrentShaderVersion() > 5004 ) + { + m_mode = (OutlineMode)Enum.Parse( typeof( OutlineMode ), nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 13902 ) + { + m_noFog = Convert.ToBoolean( nodeParams[ index++ ] ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_enabled ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_outlineWidth ); + IOUtils.AddFieldValueToString( ref nodeInfo, IOUtils.ColorToString( m_outlineColor ) ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_mode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_noFog ); + } + + public void AddToDataCollector( ref MasterNodeDataCollector dataCollector ) + { + if( !dataCollector.UsingCustomOutlineColor ) + dataCollector.AddToProperties( -1, string.Format( ColorPropertyDec, IOUtils.ColorToString( m_outlineColor ) ), -1 ); + if( !dataCollector.UsingCustomOutlineWidth ) + dataCollector.AddToProperties( -1, string.Format( OutlinePropertyDec, m_outlineWidth ), -1 ); + } + + public void UpdateFromMaterial( Material mat ) + { + if( mat.HasProperty( ColorPropertyName ) ) + { + m_outlineColor = mat.GetColor( ColorPropertyName ); + } + + if( mat.HasProperty( WidthPropertyName ) ) + { + m_outlineWidth = mat.GetFloat( WidthPropertyName ); + } + } + + void AddMultibodyString( string body , List<string> list ) + { + body = body.Replace( "\t\t", string.Empty ); + string[] strArr = body.Split( '\n' ); + for( int i = 0; i < strArr.Length; i++ ) + { + list.Add( strArr[ i ] ); + } + + } + public string[] OutlineFunctionBody( ref MasterNodeDataCollector dataCollector, bool instanced, bool isShadowCaster, string shaderName, string[] billboardInfo, ref TessellationOpHelper tessOpHelper, string target, PrecisionType precision ) + { + List<string> body = new List<string>(); + body.Add( ModeTags[ dataCollector.CustomOutlineSelectedAlpha ] ); + if( !string.IsNullOrEmpty( m_grabPasses )) + body.Add( m_grabPasses.Replace( "\t\t",string.Empty )); + + if( m_zWriteMode != 0 ) + body.Add( "ZWrite " + ZBufferOpHelper.ZWriteModeValues[ m_zWriteMode ] ); + if( m_zTestMode != 0 ) + body.Add( "ZTest " + ZBufferOpHelper.ZTestModeValues[ m_zTestMode ] ); + + body.Add( "Cull " + m_cullMode ); + body.Add( "CGPROGRAM" ); + if( tessOpHelper.EnableTesselation ) + { + body.Add( "#include \"" + TessellationOpHelper.TessInclude + "\"" ); + body.Add( "#pragma target " + target ); + } + else + { + body.Add( "#pragma target 3.0" ); + } + + bool customOutline = dataCollector.UsingCustomOutlineColor || dataCollector.UsingCustomOutlineWidth || dataCollector.UsingCustomOutlineAlpha; + int outlineMode = customOutline ? m_offsetMode : ( m_mode == OutlineMode.VertexOffset ? 0 : 1 ); + string extraOptions = ( customOutline ? m_customNoFog : m_noFog ) ? "nofog " : string.Empty; + if( dataCollector.CustomOutlineSelectedAlpha > 0 ) + { + extraOptions += ModePragma[ dataCollector.CustomOutlineSelectedAlpha ]; + } + + string surfConfig = string.Format( OutlineSurfaceConfig, extraOptions ); + + if( tessOpHelper.EnableTesselation ) + tessOpHelper.WriteToOptionalParams( ref surfConfig ); + + body.Add( surfConfig ); + if( !isShadowCaster ) + { + AddMultibodyString( m_defines, body ); + AddMultibodyString( m_includes, body ); + AddMultibodyString( m_pragmas, body ); + } + + //if( instanced ) + //{ + // body.Add( OutlineInstancedHeader ); + //} + + if( customOutline ) + { + if( isShadowCaster ) + { + + for( int i = 0; i < InputList.Count; i++ ) + { + dataCollector.AddToInput( InputList[ i ].NodeId, InputList[ i ].PropertyName, true ); + } + } + else + { + if( !string.IsNullOrEmpty( m_inputs ) ) + body.Add( m_inputs.Trim( '\t', '\n' ) ); + } + + if( !DirtyInput && !isShadowCaster ) + body.Add( OutlineBodyStructDefault ); + + if( !isShadowCaster ) + body.Add( OutlineBodyStructEnd ); + } + else if( !isShadowCaster ) + { + body.Add( OutlineBodyStructBegin ); + body.Add( OutlineBodyStructDefault ); + body.Add( OutlineBodyStructEnd ); + } + + if( instanced ) + { + //for( int i = 0; i < OutlineBodyInstancedBegin.Length; i++ ) + //{ + // body.Add( ( i == 0 ) ? string.Format( OutlineBodyInstancedBegin[ i ], shaderName ) : OutlineBodyInstancedBegin[ i ] ); + //} + + //if( (object)billboardInfo != null ) + //{ + // for( int j = 0; j < billboardInfo.Length; j++ ) + // { + // body.Add( string.Format( BillboardInstructionFormat, billboardInfo[ j ] ) ); + // } + //} + + //switch( outlineMode ) + //{ + // case 0: body.Add( string.Format( OutlineVertexOffsetMode, WidthVariableAccessInstanced ) ); break; + // case 1: body.Add( string.Format( OutlineVertexScaleMode, WidthVariableAccessInstanced ) ); break; + // case 2: body.Add( string.Format( OutlineVertexCustomMode, WidthVariableAccessInstanced ) ); break; + //} + //for( int i = 0; i < OutlineBodyInstancedEnd.Length; i++ ) + //{ + // body.Add( OutlineBodyInstancedEnd[ i ] ); + //} + bool openCBuffer = true; + if( customOutline ) + { + if( isShadowCaster ) + { + for( int i = 0; i < UniformList.Count; i++ ) + { + dataCollector.AddToUniforms( UniformList[ i ].NodeId, UniformList[ i ].PropertyName ); + } + + foreach( KeyValuePair<string, string> kvp in m_localFunctions ) + { + dataCollector.AddFunction( kvp.Key, kvp.Value ); + } + } + else + { + if( !string.IsNullOrEmpty( Uniforms ) ) + body.Add( Uniforms.Trim( '\t', '\n' ) ); + + openCBuffer = false; + body.Add( string.Format( IOUtils.InstancedPropertiesBegin, shaderName )); + if( !string.IsNullOrEmpty( InstancedProperties ) ) + body.Add( InstancedProperties.Trim( '\t', '\n' ) ); + } + } + + if( openCBuffer) + body.Add( string.Format( IOUtils.InstancedPropertiesBegin, shaderName ) ); + + if( !dataCollector.UsingCustomOutlineColor ) + body.Add( precision == PrecisionType.Float ? OutlineDefaultUniformColorInstanced.Replace( "half", "float" ) : OutlineDefaultUniformColorInstanced ); + + if( !dataCollector.UsingCustomOutlineWidth ) + body.Add( precision == PrecisionType.Float ? OutlineDefaultUniformWidthInstanced.Replace( "half", "float" ) : OutlineDefaultUniformWidthInstanced ); + + body.Add( IOUtils.InstancedPropertiesEnd ); + + //Functions + if( customOutline && !isShadowCaster ) + body.Add( Functions ); + + if( tessOpHelper.EnableTesselation && !isShadowCaster ) + { + body.Add( tessOpHelper.Uniforms().TrimStart( '\t' ) ); + body.Add( tessOpHelper.GetCurrentTessellationFunction.Trim( '\t', '\n' ) + "\n" ); + } + + if( tessOpHelper.EnableTesselation ) + { + body.Add( OutlineTessVertexHeader ); + } + else + { + body.Add( OutlineDefaultVertexHeader ); + body.Add( OutlineDefaultVertexOutputDeclaration ); + } + + if( customOutline ) + { + if( !string.IsNullOrEmpty( VertexData ) ) + body.Add( "\t" + VertexData.Trim( '\t', '\n' ) ); + } + + if( (object)billboardInfo != null ) + { + for( int j = 0; j < billboardInfo.Length; j++ ) + { + body.Add( string.Format( BillboardInstructionFormat, billboardInfo[ j ] ) ); + } + } + + switch( outlineMode ) + { + case 0: body.Add( string.Format( OutlineVertexOffsetMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyNameInstanced ) ); break; + case 1: body.Add( string.Format( OutlineVertexScaleMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyNameInstanced ) ); break; + case 2: body.Add( string.Format( OutlineVertexCustomMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyNameInstanced ) ); break; + } + + for( int i = 0; i < OutlineBodyDefaultSurfBegin.Length; i++ ) + { + body.Add( OutlineBodyDefaultSurfBegin[ i ] ); + } + if( dataCollector.UsingCustomOutlineColor || dataCollector.CustomOutlineSelectedAlpha > 0 ) + { + body.Add( "\t" + Instructions.Trim( '\t', '\n' ) ); + } + else + { + for( int i = 0; i < OutlineSurfBodyInstanced.Length; i++ ) + { + body.Add( OutlineSurfBodyInstanced[ i ] ); + } + } + + for( int i = 0; i < OutlineBodyDefaultSurfEnd.Length; i++ ) + { + body.Add( OutlineBodyDefaultSurfEnd[ i ] ); + } + } + else + { + if( customOutline ) + { + if( isShadowCaster ) + { + for( int i = 0; i < UniformList.Count; i++ ) + { + dataCollector.AddToUniforms( UniformList[ i ].NodeId, UniformList[ i ].PropertyName ); + } + + foreach( KeyValuePair<string, string> kvp in m_localFunctions ) + { + dataCollector.AddFunction( kvp.Key, kvp.Value ); + } + } + else + { + if( !string.IsNullOrEmpty( Uniforms ) ) + body.Add( Uniforms.Trim( '\t', '\n' ) ); + } + } + + if( !dataCollector.UsingCustomOutlineColor ) + body.Add( precision == PrecisionType.Float ? OutlineDefaultUniformColor.Replace( "half", "float" ) : OutlineDefaultUniformColor ); + + if( !dataCollector.UsingCustomOutlineWidth ) + body.Add( precision == PrecisionType.Float ? OutlineDefaultUniformWidth.Replace( "half", "float" ) : OutlineDefaultUniformWidth ); + + //Functions + if( customOutline && !isShadowCaster ) + body.Add( Functions ); + + if( tessOpHelper.EnableTesselation && !isShadowCaster ) + { + body.Add( tessOpHelper.Uniforms().TrimStart( '\t' ) ); + body.Add( tessOpHelper.GetCurrentTessellationFunction.Trim( '\t', '\n' ) + "\n" ); + } + + if( tessOpHelper.EnableTesselation ) + { + body.Add( OutlineTessVertexHeader ); + } + else + { + body.Add( OutlineDefaultVertexHeader ); + body.Add( OutlineDefaultVertexOutputDeclaration ); + } + + if( customOutline ) + { + if( !string.IsNullOrEmpty( VertexData ) ) + body.Add( "\t" + VertexData.Trim( '\t', '\n' ) ); + } + + if( (object)billboardInfo != null ) + { + for( int j = 0; j < billboardInfo.Length; j++ ) + { + body.Add( string.Format( BillboardInstructionFormat, billboardInfo[ j ] ) ); + } + } + + switch( outlineMode ) + { + case 0: body.Add( string.Format( OutlineVertexOffsetMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyName ) ); break; + case 1: body.Add( string.Format( OutlineVertexScaleMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyName ) ); break; + case 2: body.Add( string.Format( OutlineVertexCustomMode, dataCollector.UsingCustomOutlineWidth ? "outlineVar" : WidthPropertyName ) ); break; + } + for( int i = 0; i < OutlineBodyDefaultSurfBegin.Length; i++ ) + { + body.Add( OutlineBodyDefaultSurfBegin[ i ] ); + } + if( dataCollector.UsingCustomOutlineColor || dataCollector.CustomOutlineSelectedAlpha > 0 ) + { + body.Add( "\t" + Instructions.Trim( '\t', '\n' ) ); + } + else + { + for( int i = 0; i < OutlineSurfBody.Length; i++ ) + { + body.Add( OutlineSurfBody[ i ] ); + } + } + + for( int i = 0; i < OutlineBodyDefaultSurfEnd.Length; i++ ) + { + body.Add( OutlineBodyDefaultSurfEnd[ i ] ); + } + } + + string[] bodyArr = body.ToArray(); + body.Clear(); + body = null; + return bodyArr; + } + + + public void Destroy() + { + m_inputList = null; + m_uniformList = null; + m_instancedPropertiesList = null; + m_localFunctions = null; + } + + public bool EnableOutline { get { return m_enabled; } } + + public bool UsingCullMode { get { return m_cullMode != CullMode.Front; } } + public bool UsingZWrite { get { return m_zWriteMode != 0; } } + public bool UsingZTest { get { return m_zTestMode != 0; } } + public int ZWriteMode { get { return m_zWriteMode; } set { m_zWriteMode = value; } } + public int ZTestMode { get { return m_zTestMode; } set { m_zTestMode = value; } } + public CullMode OutlineCullMode { get { return m_cullMode; } set { m_cullMode = value; } } + public string Inputs { get { return m_inputs; } set { m_inputs = value; } } + public string Uniforms { get { return m_uniforms; } set { m_uniforms = value; } } + public string InstancedProperties { get { return m_instancedProperties; } set { m_instancedProperties = value; } } + public string Instructions { get { return m_instructions; } set { m_instructions = value; } } + public string Functions { get { return m_functions; } set { m_functions = value; } } + public string Includes { get { return m_includes; } set { m_includes = value; } } + public string Pragmas { get { return m_pragmas; } set { m_pragmas = value; } } + public string Defines { get { return m_defines; } set { m_defines = value; } } + public string VertexData { get { return m_vertexData; } set { m_vertexData = value; } } + public string GrabPasses { get { return m_grabPasses; } set { m_grabPasses = value; } } + public List<PropertyDataCollector> InputList { get { return m_inputList; } set { m_inputList = value; } } + public List<PropertyDataCollector> UniformList { get { return m_uniformList; } set { m_uniformList = value; } } + public List<PropertyDataCollector> InstancedPropertiesList { get { return m_instancedPropertiesList; } set { m_instancedPropertiesList = value; } } + + public Dictionary<string, string> LocalFunctions { get { return m_localFunctions; } set { m_localFunctions = value; } } + public bool DirtyInput { get { return m_dirtyInput; } set { m_dirtyInput = value; } } + + //public OutlineMode CustomMode { get { return m_customMode; } set { m_customMode = value; } } + public int OffsetMode { get { return m_offsetMode; } set { m_offsetMode = value; } } + public bool CustomNoFog { get { return m_customNoFog; } set { m_customNoFog = value; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutlineOpHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutlineOpHelper.cs.meta new file mode 100644 index 00000000..bb79b681 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutlineOpHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d0900a4b7d1563e49b6184d7579dcbec +timeCreated: 1487331466 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutputNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutputNode.cs new file mode 100644 index 00000000..1fffc290 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutputNode.cs @@ -0,0 +1,90 @@ +using System; +using UnityEngine; + +namespace AmplifyShaderEditor +{ + public class OutputNode : SignalGeneratorNode + { + public static int LOD_SUBSHADER_VERSION = 17200; + [SerializeField] + protected bool m_isMainOutputNode = false; + + [SerializeField] + protected int m_lodIndex = -1; + + public OutputNode() : base() { } + public OutputNode( int uniqueId, float x, float y, float width, float height ) : base( uniqueId, x, y, width, height ) { } + + public override void ResetNodeData() + { + base.ResetNodeData(); + m_graphDepth = -1; + } + + public virtual void SetupNodeCategories() + { + ContainerGraph.ResetNodesData(); + //int count = m_inputPorts.Count; + //for( int i = 0; i < count; i++ ) + //{ + // if( m_inputPorts[ i ].IsConnected ) + // { + // NodeData nodeData = new NodeData( m_inputPorts[ i ].Category ); + // ParentNode node = m_inputPorts[ i ].GetOutputNode(); + // node.PropagateNodeData( nodeData, ref collector ); + // } + //} + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_isMainOutputNode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_lodIndex ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_isMainOutputNode = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > LOD_SUBSHADER_VERSION ) + { + m_lodIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + if( IsLODMainMasterNode && !ContainerGraph.IsDuplicating ) + { + ContainerGraph.AssignMasterNode( this, true ); + } + } + + public override void AfterDuplication() + { + base.AfterDuplication(); + m_isMainOutputNode = false; + } + + public bool IsMainOutputNode + { + get { return m_isMainOutputNode; } + set + { + if( value != m_isMainOutputNode ) + { + m_isMainOutputNode = value; + if( m_isMainOutputNode ) + { + GenerateSignalPropagation(); + } + else + { + GenerateSignalInibitor(); + } + } + } + } + + public int LODIndex { get { return m_lodIndex; } set { m_lodIndex = value; } } + public bool IsLODMainMasterNode { get { return m_isMainOutputNode && m_lodIndex == -1; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutputNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutputNode.cs.meta new file mode 100644 index 00000000..79cae85e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutputNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ed0ee3a73f11f344495d16b54bb3af29 +timeCreated: 1491918470 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingOptionsOpHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingOptionsOpHelper.cs new file mode 100644 index 00000000..34c8e548 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingOptionsOpHelper.cs @@ -0,0 +1,227 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + public enum DisableBatchingTagValues + { + True, + False, + LODFading + } + + [Serializable] + public class RenderingOptionsOpHelper + { + private const string RenderingOptionsStr = " Rendering Options"; + private readonly static GUIContent EmissionGIFlags = new GUIContent( "Emission GI Flag", "Modifies Emission GI flags" ); + private readonly static GUIContent LODCrossfadeContent = new GUIContent( " LOD Group Cross Fade", "Applies a dither crossfade to be used with LOD groups for smoother transitions. Uses one interpolator\nDefault: OFF" ); + private readonly static GUIContent DisableBatchingContent = new GUIContent( "Disable Batching", "\nDisables objects to be batched and used with DrawCallBatching Default: False" ); + private readonly static GUIContent IgnoreProjectorContent = new GUIContent( " Ignore Projector", "\nIf True then an object that uses this shader will not be affected by Projectors Default: False" ); + private readonly static GUIContent UseDefaultCasterContent = new GUIContent( " Use Default Shadow Caster", "\nIf True always use surface default shadow caster Default: False" ); + private readonly static GUIContent ForceNoShadowCastingContent = new GUIContent( " Force No Shadow Casting", "\nIf True then an object that is rendered using this subshader will never cast shadows Default: False" ); + private readonly static GUIContent ForceEnableInstancingContent = new GUIContent( " Force Enable Instancing", "\nIf True forces instancing on shader independent of having instanced properties" ); +#if UNITY_5_6_OR_NEWER + private readonly static GUIContent ForceDisableInstancingContent = new GUIContent( " Force Disable Instancing", "\nIf True forces disable instancing on shader independent of having instanced properties" ); +#endif + private readonly static GUIContent SpecularHightlightsContent = new GUIContent( " Fwd Specular Highlights Toggle", "\nIf True creates a material toggle to set Unity's internal specular highlight rendering keyword" ); + private readonly static GUIContent ReflectionsContent = new GUIContent( " Fwd Reflections Toggle", "\nIf True creates a material toggle to set Unity's internal reflections rendering keyword" ); + + [SerializeField] + private bool m_forceEnableInstancing = false; + + [SerializeField] + private bool m_forceDisableInstancing = false; + + [SerializeField] + private bool m_specularHighlightToggle = false; + + [SerializeField] + private bool m_reflectionsToggle = false; + + [SerializeField] + private bool m_lodCrossfade = false; + + [SerializeField] + private DisableBatchingTagValues m_disableBatching = DisableBatchingTagValues.False; + + [SerializeField] + private bool m_ignoreProjector = false; + + [SerializeField] + private bool m_useDefaultShadowCaster = false; + + [SerializeField] + private bool m_forceNoShadowCasting = false; + + [SerializeField] + private List<CodeGenerationData> m_codeGenerationDataList; + + public RenderingOptionsOpHelper() + { + m_codeGenerationDataList = new List<CodeGenerationData>(); + m_codeGenerationDataList.Add( new CodeGenerationData( " Exclude Deferred", "exclude_path:deferred" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Exclude Forward", "exclude_path:forward" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Exclude Legacy Deferred", "exclude_path:prepass" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Shadows", "noshadow" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Ambient Light", "noambient" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Per Vertex Light", "novertexlights" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Lightmaps", "nolightmap " ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Dynamic Global GI", "nodynlightmap" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Directional lightmaps", "nodirlightmap" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Built-in Fog", "nofog" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Meta Pass", "nometa" ) ); + m_codeGenerationDataList.Add( new CodeGenerationData( " Add Pass", "noforwardadd" ) ); + } + + public bool IsOptionActive( string option ) + { + return !m_codeGenerationDataList.Find( x => x.Name.Equals( option ) ).IsActive; + } + + public void Draw( StandardSurfaceOutputNode owner ) + { + bool value = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedRenderingOptions; + NodeUtils.DrawPropertyGroup( ref value, RenderingOptionsStr, () => + { + int codeGenCount = m_codeGenerationDataList.Count; + // Starting from index 4 because other options are already contemplated with m_renderPath and add/receive shadows + for( int i = 4; i < codeGenCount; i++ ) + { + m_codeGenerationDataList[ i ].IsActive = !owner.EditorGUILayoutToggleLeft( m_codeGenerationDataList[ i ].Name, !m_codeGenerationDataList[ i ].IsActive ); + } + m_lodCrossfade = owner.EditorGUILayoutToggleLeft( LODCrossfadeContent, m_lodCrossfade ); + m_ignoreProjector = owner.EditorGUILayoutToggleLeft( IgnoreProjectorContent, m_ignoreProjector ); + EditorGUI.BeginDisabledGroup( !owner.CastShadows ); + m_useDefaultShadowCaster = owner.EditorGUILayoutToggleLeft( UseDefaultCasterContent, m_useDefaultShadowCaster ); + EditorGUI.EndDisabledGroup(); + m_forceNoShadowCasting = owner.EditorGUILayoutToggleLeft( ForceNoShadowCastingContent, m_forceNoShadowCasting ); + if( owner.ContainerGraph.IsInstancedShader ) + { + GUI.enabled = false; + owner.EditorGUILayoutToggleLeft( ForceEnableInstancingContent, true ); + GUI.enabled = true; + } + else + { + m_forceEnableInstancing = owner.EditorGUILayoutToggleLeft( ForceEnableInstancingContent, m_forceEnableInstancing ); + } + +#if UNITY_5_6_OR_NEWER + m_forceDisableInstancing = owner.EditorGUILayoutToggleLeft( ForceDisableInstancingContent, m_forceDisableInstancing ); +#endif + m_specularHighlightToggle = owner.EditorGUILayoutToggleLeft( SpecularHightlightsContent, m_specularHighlightToggle ); + m_reflectionsToggle = owner.EditorGUILayoutToggleLeft( ReflectionsContent, m_reflectionsToggle ); + m_disableBatching = (DisableBatchingTagValues)owner.EditorGUILayoutEnumPopup( DisableBatchingContent, m_disableBatching ); + Material mat = owner.ContainerGraph.CurrentMaterial; + if( mat != null ) + { + mat.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)owner.EditorGUILayoutEnumPopup( EmissionGIFlags, mat.globalIlluminationFlags ); + } + } ); + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedRenderingOptions = value; + } + + public void Build( ref string OptionalParameters ) + { + int codeGenCount = m_codeGenerationDataList.Count; + + for( int i = 0; i < codeGenCount; i++ ) + { + if( m_codeGenerationDataList[ i ].IsActive ) + { + OptionalParameters += m_codeGenerationDataList[ i ].Value + Constants.OptionalParametersSep; + } + } + +#if UNITY_2017_1_OR_NEWER + if( m_lodCrossfade ) + { + OptionalParameters += Constants.LodCrossFadeOption2017 + Constants.OptionalParametersSep; + } +#endif + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + for( int i = 0; i < m_codeGenerationDataList.Count; i++ ) + { + m_codeGenerationDataList[ i ].IsActive = Convert.ToBoolean( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 10005 ) + { + m_lodCrossfade = Convert.ToBoolean( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 10007 ) + { + m_disableBatching = (DisableBatchingTagValues)Enum.Parse( typeof( DisableBatchingTagValues ), nodeParams[ index++ ] ); + m_ignoreProjector = Convert.ToBoolean( nodeParams[ index++ ] ); + m_forceNoShadowCasting = Convert.ToBoolean( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 11002 ) + { + m_forceEnableInstancing = Convert.ToBoolean( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 15205 ) + { + m_forceDisableInstancing = Convert.ToBoolean( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 14403 ) + { + m_specularHighlightToggle = Convert.ToBoolean( nodeParams[ index++ ] ); + m_reflectionsToggle = Convert.ToBoolean( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 16307 ) + { + m_useDefaultShadowCaster = Convert.ToBoolean( nodeParams[ index++ ] ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + for( int i = 0; i < m_codeGenerationDataList.Count; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_codeGenerationDataList[ i ].IsActive ); + } + + IOUtils.AddFieldValueToString( ref nodeInfo, m_lodCrossfade ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_disableBatching ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_ignoreProjector ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_forceNoShadowCasting ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_forceEnableInstancing ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_forceDisableInstancing ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_specularHighlightToggle ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_reflectionsToggle ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_useDefaultShadowCaster ); + } + + public void Destroy() + { + m_codeGenerationDataList.Clear(); + m_codeGenerationDataList = null; + } + public bool UseDefaultShadowCaster { get { return m_useDefaultShadowCaster; } } + public bool ForceEnableInstancing { get { return m_forceEnableInstancing; } } + public bool ForceDisableInstancing { get { return m_forceDisableInstancing; } } + + public bool LodCrossfade { get { return m_lodCrossfade; } } + public bool IgnoreProjectorValue { get { return m_ignoreProjector; } set { m_ignoreProjector = value; } } + public bool SpecularHighlightToggle { get { return m_specularHighlightToggle; } set { m_specularHighlightToggle = value; } } + public bool ReflectionsToggle { get { return m_reflectionsToggle; } set { m_reflectionsToggle = value; } } + + public string DisableBatchingTag { get { return ( m_disableBatching != DisableBatchingTagValues.False ) ? string.Format( Constants.TagFormat, "DisableBatching", m_disableBatching ) : string.Empty; } } + public string IgnoreProjectorTag { get { return ( m_ignoreProjector ) ? string.Format( Constants.TagFormat, "IgnoreProjector", "True" ) : string.Empty; } } + public string ForceNoShadowCastingTag { get { return ( m_forceNoShadowCasting ) ? string.Format( Constants.TagFormat, "ForceNoShadowCasting", "True" ) : string.Empty; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingOptionsOpHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingOptionsOpHelper.cs.meta new file mode 100644 index 00000000..e94a1528 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingOptionsOpHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 26d840af03d4f7b418e9c7bece143648 +timeCreated: 1488906067 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingPlatformsOpHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingPlatformsOpHelper.cs new file mode 100644 index 00000000..c049d6d7 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingPlatformsOpHelper.cs @@ -0,0 +1,238 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using UnityEditor; +using UnityEngine; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class RenderPlatformInfo + { + public string Label; + public RenderPlatforms Value; + } + + [Serializable] + public class RenderingPlatformOpHelper + { + private const string RenderingPlatformsStr = " Rendering Platforms"; + private readonly RenderPlatformInfo[] RenderingPlatformsInfo = + { + new RenderPlatformInfo(){Label = " Direct3D 9", Value = RenderPlatforms.d3d9}, + new RenderPlatformInfo(){Label = " Direct3D 11 9.x", Value = RenderPlatforms.d3d11_9x}, + new RenderPlatformInfo(){Label = " Direct3D 11/12", Value = RenderPlatforms.d3d11}, + new RenderPlatformInfo(){Label = " OpenGL 3.x/4.x", Value = RenderPlatforms.glcore}, + new RenderPlatformInfo(){Label = " OpenGL ES 2.0", Value = RenderPlatforms.gles}, + new RenderPlatformInfo(){Label = " OpenGL ES 3.x", Value = RenderPlatforms.gles3}, + new RenderPlatformInfo(){Label = " iOS/Mac Metal", Value = RenderPlatforms.metal}, + new RenderPlatformInfo(){Label = " Vulkan", Value = RenderPlatforms.vulkan}, + new RenderPlatformInfo(){Label = " Xbox 360", Value = RenderPlatforms.xbox360}, + new RenderPlatformInfo(){Label = " Xbox One", Value = RenderPlatforms.xboxone}, + new RenderPlatformInfo(){Label = " PlayStation 4", Value = RenderPlatforms.ps4}, + new RenderPlatformInfo(){Label = " PlayStation Vita", Value = RenderPlatforms.psp2}, + new RenderPlatformInfo(){Label = " Nintendo 3DS", Value = RenderPlatforms.n3ds}, + new RenderPlatformInfo(){Label = " Nintendo Wii U", Value = RenderPlatforms.wiiu} + }; + + // Values from this dictionary must be the indices corresponding from the list above + private readonly Dictionary<RenderPlatforms, int> PlatformToIndex = new Dictionary<RenderPlatforms, int>() + { + {RenderPlatforms.d3d9, 0}, + {RenderPlatforms.d3d11_9x, 1}, + {RenderPlatforms.d3d11, 2}, + {RenderPlatforms.glcore, 3}, + {RenderPlatforms.gles, 4}, + {RenderPlatforms.gles3, 5}, + {RenderPlatforms.metal, 6}, + {RenderPlatforms.vulkan, 7}, + {RenderPlatforms.xbox360, 8}, + {RenderPlatforms.xboxone, 9}, + {RenderPlatforms.ps4, 10}, + {RenderPlatforms.psp2, 11}, + {RenderPlatforms.n3ds, 12}, + {RenderPlatforms.wiiu, 13} + }; + + + private readonly List<RenderPlatforms> LegacyIndexToPlatform = new List<RenderPlatforms>() + { + RenderPlatforms.d3d9, + RenderPlatforms.d3d11, + RenderPlatforms.glcore, + RenderPlatforms.gles, + RenderPlatforms.gles3, + RenderPlatforms.metal, + RenderPlatforms.d3d11_9x, + RenderPlatforms.xbox360, + RenderPlatforms.xboxone, + RenderPlatforms.ps4, + RenderPlatforms.psp2, + RenderPlatforms.n3ds, + RenderPlatforms.wiiu + }; + + [SerializeField] + private bool[] m_renderingPlatformValues; + + public RenderingPlatformOpHelper() + { + m_renderingPlatformValues = new bool[ RenderingPlatformsInfo.Length ]; + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + m_renderingPlatformValues[ i ] = true; + } + } + + + public void Draw( ParentNode owner ) + { + bool value = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedRenderingPlatforms; + NodeUtils.DrawPropertyGroup( ref value, RenderingPlatformsStr, () => + { + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + m_renderingPlatformValues[ i ] = owner.EditorGUILayoutToggleLeft( RenderingPlatformsInfo[ i ].Label, m_renderingPlatformValues[ i ] ); + } + } ); + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedRenderingPlatforms = value; + } + + public void SetRenderingPlatforms( ref string ShaderBody ) + { + int checkedPlatforms = 0; + int uncheckedPlatforms = 0; + + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + if( m_renderingPlatformValues[ i ] ) + { + checkedPlatforms += 1; + } + else + { + uncheckedPlatforms += 1; + } + } + + if( checkedPlatforms > 0 && checkedPlatforms < m_renderingPlatformValues.Length ) + { + string result = string.Empty; + if( checkedPlatforms < uncheckedPlatforms ) + { + result = "only_renderers "; + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + if( m_renderingPlatformValues[ i ] ) + { + result += (RenderPlatforms)RenderingPlatformsInfo[i].Value + " "; + } + } + } + else + { + result = "exclude_renderers "; + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + if( !m_renderingPlatformValues[ i ] ) + { + result += (RenderPlatforms)RenderingPlatformsInfo[ i ].Value + " "; + } + } + } + MasterNode.AddShaderPragma( ref ShaderBody, result ); + } + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + if( UIUtils.CurrentShaderVersion() < 17006 ) + { + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + m_renderingPlatformValues[ i ] = false; + } + + int count = LegacyIndexToPlatform.Count; + int activeCount = 0; + for( int i = 0; i < count; i++ ) + { + RenderPlatforms platform = LegacyIndexToPlatform[ i ]; + int newIndex = PlatformToIndex[ platform ]; + bool value = Convert.ToBoolean( nodeParams[ index++ ] ); + if( value ) + { + m_renderingPlatformValues[ newIndex ] = true; + activeCount += 1; + } + else + { + m_renderingPlatformValues[ newIndex ] = false; + } + } + + if( activeCount == count ) + { + m_renderingPlatformValues[ PlatformToIndex[ RenderPlatforms.vulkan ] ] = true; + } + } + else + { + int count = Convert.ToInt32( nodeParams[ index++ ] ); + if( count > 0 ) + { + RenderPlatforms firstPlatform = (RenderPlatforms)Enum.Parse( typeof(RenderPlatforms), nodeParams[ index++ ] ); + if( firstPlatform == RenderPlatforms.all ) + { + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + m_renderingPlatformValues[ i ] = true; + } + } + else + { + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + m_renderingPlatformValues[ i ] = false; + } + + m_renderingPlatformValues[ PlatformToIndex[ firstPlatform ]] = true; + for( int i = 1; i < count; i++ ) + { + RenderPlatforms currPlatform = (RenderPlatforms)Enum.Parse( typeof( RenderPlatforms ), nodeParams[ index++ ] ); + m_renderingPlatformValues[ PlatformToIndex[ currPlatform ] ] = true; + } + } + } + } + } + + public void WriteToString( ref string nodeInfo ) + { + int active = 0; + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + if( m_renderingPlatformValues[ i ] ) + active += 1; + } + IOUtils.AddFieldValueToString( ref nodeInfo, active ); + if( active == m_renderingPlatformValues.Length ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, RenderPlatforms.all ); + } + else + { + for( int i = 0; i < m_renderingPlatformValues.Length; i++ ) + { + if( m_renderingPlatformValues[ i ] ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, RenderingPlatformsInfo[i].Value ); + } + } + } + + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingPlatformsOpHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingPlatformsOpHelper.cs.meta new file mode 100644 index 00000000..96f19245 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingPlatformsOpHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 50a1f03b042823f469cef7d97c73fdc3 +timeCreated: 1488907373 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StandardSurface.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StandardSurface.cs new file mode 100644 index 00000000..9fd57e8a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StandardSurface.cs @@ -0,0 +1,3302 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditorInternal; + +namespace AmplifyShaderEditor +{ + public enum VertexMode + { + Relative, + Absolute + } + + public enum RenderPath + { + All, + ForwardOnly, + DeferredOnly + } + + public enum StandardShaderLightModel + { + Standard, + StandardSpecular, + Lambert, + BlinnPhong, + Unlit, + CustomLighting + } + + public enum CullMode + { + Back, + Front, + Off + } + + public enum AlphaMode + { + Opaque = 0, + Masked = 1, + Transparent = 2, // Transparent (alpha:fade) + Translucent = 3, + Premultiply = 4, // Alpha Premul (alpha:premul) + Custom = 5, + } + + public enum RenderType + { + Opaque, + Transparent, + TransparentCutout, + Background, + Overlay, + TreeOpaque, + TreeTransparentCutout, + TreeBillboard, + Grass, + GrassBillboard, + Custom + } + + public enum RenderQueue + { + Background, + Geometry, + AlphaTest, + Transparent, + Overlay + } + + public enum RenderPlatforms + { + d3d9, + d3d11, + glcore, + gles, + gles3, + metal, + d3d11_9x, + xbox360, + xboxone, + ps4, + psp2, + n3ds, + wiiu, + vulkan, + all + } + + [Serializable] + public class NodeCache + { + public int TargetNodeId = -1; + public int TargetPortId = -1; + + public NodeCache( int targetNodeId, int targetPortId ) + { + SetData( targetNodeId, targetPortId ); + } + + public void SetData( int targetNodeId, int targetPortId ) + { + TargetNodeId = targetNodeId; + TargetPortId = targetPortId; + } + + public void Invalidate() + { + TargetNodeId = -1; + TargetPortId = -1; + } + + public bool IsValid + { + get { return ( TargetNodeId >= 0 ); } + } + + public override string ToString() + { + return "TargetNodeId " + TargetNodeId + " TargetPortId " + TargetPortId; + } + } + + [Serializable] + public class CacheNodeConnections + { + public Dictionary<string, List<NodeCache>> NodeCacheArray; + + public CacheNodeConnections() + { + NodeCacheArray = new Dictionary<string, List<NodeCache>>(); + } + + public void Add( string key, NodeCache value ) + { + if( NodeCacheArray.ContainsKey( key ) ) + { + NodeCacheArray[ key ].Add( value ); + } + else + { + NodeCacheArray.Add( key, new List<NodeCache>() ); + NodeCacheArray[ key ].Add( value ); + } + } + + public NodeCache Get( string key, int idx = 0 ) + { + if( NodeCacheArray.ContainsKey( key ) ) + { + if( idx < NodeCacheArray[ key ].Count ) + return NodeCacheArray[ key ][ idx ]; + } + return null; + } + + public List<NodeCache> GetList( string key ) + { + if( NodeCacheArray.ContainsKey( key ) ) + { + return NodeCacheArray[ key ]; + } + return null; + } + + public void Clear() + { + foreach( KeyValuePair<string, List<NodeCache>> kvp in NodeCacheArray ) + { + kvp.Value.Clear(); + } + NodeCacheArray.Clear(); + } + } + + [Serializable] + [NodeAttributes( "Standard Surface Output", "Master", "Surface shader generator output", null, KeyCode.None, false )] + public sealed class StandardSurfaceOutputNode : MasterNode, ISerializationCallbackReceiver + { + private readonly static string[] VertexLitFunc = { "\t\tinline half4 LightingUnlit( SurfaceOutput s, half3 lightDir, half atten )", + "\t\t{", + "\t\t\treturn half4 ( 0, 0, 0, s.Alpha );", + "\t\t}\n"}; + + private readonly static string[] FadeModeOptions = { "Opaque", "Masked", "Transparent", "Translucent", "Alpha Premultipled", "Custom" }; + private const string VertexModeStr = "Vertex Output"; + private readonly static GUIContent RenderPathContent = new GUIContent( "Render Path", "Selects and generates passes for the supported rendering paths\nDefault: All" ); + private const string ShaderModelStr = "Shader Model"; + private readonly static GUIContent LightModelContent = new GUIContent( "Light Model", "Surface shader lighting model defines how the surface reflects light\nDefault: Standard" ); + private readonly static GUIContent ShaderLODContent = new GUIContent( "Shader LOD", "Shader LOD" ); + private readonly static GUIContent CullModeContent = new GUIContent( "Cull Mode", "Polygon culling mode prevents rendering of either back-facing or front-facing polygons to save performance, turn it off if you want to render both sides\nDefault: Back" ); + + private const string ChromaticAberrationStr = "Chromatic Aberration"; + private const string DiscardStr = "Opacity Mask"; + private const string VertexDisplacementStr = "Local Vertex Offset"; + private const string VertexPositionStr = "Local Vertex Position"; + private const string VertexDataStr = "VertexData"; + private const string VertexNormalStr = "Local Vertex Normal"; + private const string CustomLightingStr = "Custom Lighting"; + private const string AlbedoStr = "Albedo"; + private const string NormalStr = "Normal"; + private const string EmissionStr = "Emission"; + private const string MetallicStr = "Metallic"; + private const string SmoothnessStr = "Smoothness"; + private const string OcclusionDataStr = "Occlusion"; + private const string OcclusionLabelStr = "Ambient Occlusion"; + private const string TransmissionStr = "Transmission"; + private const string TranslucencyStr = "Translucency"; + private const string RefractionStr = "Refraction"; + private const string AlphaStr = "Opacity"; + private const string AlphaDataStr = "Alpha"; + private const string DebugStr = "Debug"; + private const string SpecularStr = "Specular"; + private const string GlossStr = "Gloss"; + private const string CustomRenderTypeStr = "Custom Type"; + private readonly static GUIContent AlphaModeContent = new GUIContent( " Blend Mode", "Defines how the surface blends with the background\nDefault: Opaque" ); + private const string OpacityMaskClipValueStr = "Mask Clip Value"; + private readonly static GUIContent OpacityMaskClipValueContent = new GUIContent( "Mask Clip Value", "Default clip value to be compared with opacity alpha ( 0 = fully Opaque, 1 = fully Masked )\nDefault: 0.5" ); + private readonly static GUIContent CastShadowsContent = new GUIContent( "Cast Shadows", "Generates a shadow caster pass for vertex modifications and point lights in forward rendering\nDefault: ON" ); + private readonly static GUIContent ReceiveShadowsContent = new GUIContent( "Receive Shadows", "Untick it to disable shadow receiving, this includes self-shadowing (only for forward rendering) \nDefault: ON" ); + private readonly static GUIContent QueueIndexContent = new GUIContent( "Queue Index", "Value to offset the render queue, accepts both positive values to render later and negative values to render sooner\nDefault: 0" ); + private readonly static GUIContent RefractionLayerStr = new GUIContent( "Refraction Layer", "Use it to group or ungroup different refraction shaders into the same or different grabpass (only for forward rendering) \nDefault: 0" ); + private readonly static GUIContent AlphaToCoverageStr = new GUIContent( "Alpha To Coverage", "" ); + private readonly static GUIContent RenderQueueContent = new GUIContent( "Render Queue", "Base rendering queue index\n(Background = 1000, Geometry = 2000, AlphaTest = 2450, Transparent = 3000, Overlay = 4000)\nDefault: Geometry" ); + private readonly static GUIContent RenderTypeContent = new GUIContent( "Render Type", "Categorizes shaders into several predefined groups, usually to be used with screen shader effects\nDefault: Opaque" ); + + private const string ShaderInputOrderStr = "Shader Input Order"; + + + [SerializeField] + private BlendOpsHelper m_blendOpsHelper = new BlendOpsHelper(); + + [SerializeField] + private StencilBufferOpHelper m_stencilBufferHelper = new StencilBufferOpHelper(); + + [SerializeField] + private ZBufferOpHelper m_zBufferHelper = new ZBufferOpHelper(); + + [SerializeField] + private OutlineOpHelper m_outlineHelper = new OutlineOpHelper(); + + [SerializeField] + private TessellationOpHelper m_tessOpHelper = new TessellationOpHelper(); + + [SerializeField] + private ColorMaskHelper m_colorMaskHelper = new ColorMaskHelper(); + + [SerializeField] + private RenderingPlatformOpHelper m_renderingPlatformOpHelper = new RenderingPlatformOpHelper(); + + [SerializeField] + private RenderingOptionsOpHelper m_renderingOptionsOpHelper = new RenderingOptionsOpHelper(); + + [SerializeField] + private BillboardOpHelper m_billboardOpHelper = new BillboardOpHelper(); + + [SerializeField] + private FallbackPickerHelper m_fallbackHelper = null; + + [SerializeField] + private TerrainDrawInstancedHelper m_drawInstancedHelper = new TerrainDrawInstancedHelper(); + + //legacy + [SerializeField] + private AdditionalIncludesHelper m_additionalIncludes = new AdditionalIncludesHelper(); + //legacy + [SerializeField] + private AdditionalPragmasHelper m_additionalPragmas = new AdditionalPragmasHelper(); + //legacy + [SerializeField] + private AdditionalDefinesHelper m_additionalDefines = new AdditionalDefinesHelper(); + + [SerializeField] + private TemplateAdditionalDirectivesHelper m_additionalDirectives = new TemplateAdditionalDirectivesHelper( " Additional Directives" ); + + [SerializeField] + private AdditionalSurfaceOptionsHelper m_additionalSurfaceOptions = new AdditionalSurfaceOptionsHelper(); + + [SerializeField] + private UsePassHelper m_usePass; + + [SerializeField] + private CustomTagsHelper m_customTagsHelper = new CustomTagsHelper(); + + [SerializeField] + private DependenciesHelper m_dependenciesHelper = new DependenciesHelper(); + + [SerializeField] + private StandardShaderLightModel m_currentLightModel; + + [SerializeField] + private StandardShaderLightModel m_lastLightModel; + + [SerializeField] + private CullMode m_cullMode = CullMode.Back; + + [SerializeField] + private InlineProperty m_inlineCullMode = new InlineProperty(); + + [SerializeField] + private InlineProperty m_inlineChromaticAberration = new InlineProperty(0.1f); + + [SerializeField] + private AlphaMode m_alphaMode = AlphaMode.Opaque; + + [SerializeField] + private RenderType m_renderType = RenderType.Opaque; + + [SerializeField] + private string m_customRenderType = string.Empty; + + [SerializeField] + private RenderQueue m_renderQueue = RenderQueue.Geometry; + + [SerializeField] + private RenderPath m_renderPath = RenderPath.All; + + [SerializeField] + private VertexMode m_vertexMode = VertexMode.Relative; + + [SerializeField] + private bool m_customBlendMode = false; + + [SerializeField] + private float m_opacityMaskClipValue = 0.5f; + + [SerializeField] + private InlineProperty m_inlineOpacityMaskClipValue = new InlineProperty(); + + [SerializeField] + private InlineProperty m_inlineAlphaToCoverage = new InlineProperty(); + + [SerializeField] + private int m_customLightingPortId = -1; + + [SerializeField] + private int m_emissionPortId = -1; + + [SerializeField] + private int m_discardPortId = -1; + + [SerializeField] + private int m_opacityPortId = -1; + + [SerializeField] + private int m_vertexPortId = -1; + + [SerializeField] + private bool m_keepAlpha = true; + + [SerializeField] + private bool m_castShadows = true; + + //[SerializeField] + private bool m_customShadowCaster = false; + + [SerializeField] + private bool m_receiveShadows = true; + + [SerializeField] + private int m_queueOrder = 0; + + [SerializeField] + private int m_grabOrder = 0; + + [SerializeField] + private bool m_alphaToCoverage = false; + + private InputPort m_transmissionPort; + private InputPort m_translucencyPort; + private InputPort m_tessellationPort; + private bool m_previousTranslucencyOn = false; + private bool m_previousRefractionOn = false; + + [SerializeField] + private CacheNodeConnections m_cacheNodeConnections = new CacheNodeConnections(); + + + private bool m_usingProSkin = false; + private GUIStyle m_inspectorFoldoutStyle; + private GUIStyle m_inspectorToolbarStyle; + private GUIStyle m_inspectorTooldropdownStyle; + + + private bool m_customBlendAvailable = false; + + private Color m_cachedColor = Color.white; + private float m_titleOpacity = 0.5f; + private float m_boxOpacity = 0.5f; + + private InputPort m_refractionPort; + private InputPort m_normalPort; + + + private GUIStyle m_inspectorDefaultStyle; + + [SerializeField] + private ReordenatorNode m_specColorReorder = null; + + [SerializeField] + private int m_specColorOrderIndex = -1; + + [SerializeField] + private ReordenatorNode m_maskClipReorder = null; + + [SerializeField] + private int m_maskClipOrderIndex = -1; + + [SerializeField] + private ReordenatorNode m_translucencyReorder = null; + + [SerializeField] + private int m_translucencyOrderIndex = -1; + + [SerializeField] + private ReordenatorNode m_refractionReorder = null; + + [SerializeField] + private int m_refractionOrderIndex = -1; + + [SerializeField] + private ReordenatorNode m_tessellationReorder = null; + + [SerializeField] + private int m_tessellationOrderIndex = -1; + + private bool m_previousTessellationOn = false; + private bool m_initialize = true; + private bool m_checkChanges = true; + private bool m_lightModelChanged = true; + + private PropertyNode m_dummyProperty = null; + + protected override void CommonInit( int uniqueId ) + { + m_currentLightModel = m_lastLightModel = StandardShaderLightModel.Standard; + m_textLabelWidth = 120; + m_autoDrawInternalPortData = false; + base.CommonInit( uniqueId ); + m_zBufferHelper.ParentSurface = this; + m_tessOpHelper.ParentSurface = this; + m_customPrecision = true; + } + + public override void OnEnable() + { + base.OnEnable(); + 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(); + } + } + + public override void AddMasterPorts() + { + int vertexCorrection = 2; + int index = vertexCorrection + 2; + base.AddMasterPorts(); + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + { + AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 ); + AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 ); + m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 ); + AddInputPort( WirePortDataType.FLOAT, false, MetallicStr, index++, MasterNodePortCategory.Fragment, 3 ); + AddInputPort( WirePortDataType.FLOAT, false, SmoothnessStr, index++, MasterNodePortCategory.Fragment, 4 ); + AddInputPort( WirePortDataType.FLOAT, false, OcclusionLabelStr, OcclusionDataStr, index++, MasterNodePortCategory.Fragment, 5 ); + } + break; + case StandardShaderLightModel.StandardSpecular: + { + AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 ); + AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 ); + m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 ); + AddInputPort( WirePortDataType.FLOAT3, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 ); + AddInputPort( WirePortDataType.FLOAT, false, SmoothnessStr, index++, MasterNodePortCategory.Fragment, 4 ); + AddInputPort( WirePortDataType.FLOAT, false, OcclusionLabelStr, OcclusionDataStr, index++, MasterNodePortCategory.Fragment, 5 ); + } + break; + case StandardShaderLightModel.CustomLighting: + { + AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 ); + AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 ); + m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true; + AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 ); + AddInputPort( WirePortDataType.FLOAT, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 ); + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true; + AddInputPort( WirePortDataType.FLOAT, false, GlossStr, index++, MasterNodePortCategory.Fragment, 4 ); + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true; + } + break; + case StandardShaderLightModel.Unlit: + { + AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 ); + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true; + AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 ); + m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true; + AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 ); + AddInputPort( WirePortDataType.FLOAT, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 ); + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true; + AddInputPort( WirePortDataType.FLOAT, false, GlossStr, index++, MasterNodePortCategory.Fragment, 4 ); + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true; + } + break; + case StandardShaderLightModel.Lambert: + { + AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 ); + AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 ); + m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 ); + AddInputPort( WirePortDataType.FLOAT, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 ); + AddInputPort( WirePortDataType.FLOAT, false, GlossStr, index++, MasterNodePortCategory.Fragment, 4 ); + } + break; + case StandardShaderLightModel.BlinnPhong: + { + AddInputPort( WirePortDataType.FLOAT3, false, AlbedoStr, vertexCorrection + 1, MasterNodePortCategory.Fragment, 0 ); + AddInputPort( WirePortDataType.FLOAT3, false, NormalStr, vertexCorrection + 0, MasterNodePortCategory.Fragment, 1 ); + m_normalPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + AddInputPort( WirePortDataType.FLOAT3, false, EmissionStr, index++, MasterNodePortCategory.Fragment, 2 ); + AddInputPort( WirePortDataType.FLOAT, false, SpecularStr, index++, MasterNodePortCategory.Fragment, 3 ); + AddInputPort( WirePortDataType.FLOAT, false, GlossStr, index++, MasterNodePortCategory.Fragment, 4 ); + } + break; + } + + // instead of setting in the switch emission port is always at position 2; + m_emissionPortId = 2; + + AddInputPort( WirePortDataType.FLOAT3, false, TransmissionStr, index++, MasterNodePortCategory.Fragment, 6 ); + m_transmissionPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_currentLightModel == StandardShaderLightModel.Standard ) || ( m_currentLightModel == StandardShaderLightModel.StandardSpecular ) ? false : true; + + AddInputPort( WirePortDataType.FLOAT3, false, TranslucencyStr, index++, MasterNodePortCategory.Fragment, 7 ); + m_translucencyPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_currentLightModel == StandardShaderLightModel.Standard ) || ( m_currentLightModel == StandardShaderLightModel.StandardSpecular ) ? false : true; + + AddInputPort( WirePortDataType.FLOAT, false, RefractionStr, index + 2, MasterNodePortCategory.Fragment, 8 ); + m_refractionPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_alphaMode == AlphaMode.Opaque || m_alphaMode == AlphaMode.Masked || m_currentLightModel == StandardShaderLightModel.Unlit || m_currentLightModel == StandardShaderLightModel.CustomLighting ); + + AddInputPort( WirePortDataType.FLOAT, false, AlphaStr, index++, MasterNodePortCategory.Fragment, 9 ); + m_inputPorts[ m_inputPorts.Count - 1 ].DataName = AlphaDataStr; + m_opacityPortId = m_inputPorts.Count - 1; + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_alphaMode == AlphaMode.Opaque || m_alphaMode == AlphaMode.Masked ); + + AddInputPort( WirePortDataType.FLOAT, false, DiscardStr, index++, MasterNodePortCategory.Fragment, 10 ); + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_alphaMode != AlphaMode.Masked && m_alphaMode != AlphaMode.Custom ); + m_discardPortId = m_inputPorts.Count - 1; + + // This is done to take the index + 2 from refraction port into account and not overlap indexes + index++; + + AddInputPort( WirePortDataType.FLOAT3, false, CustomLightingStr, index++, MasterNodePortCategory.Fragment, 13 ); + m_inputPorts[ m_inputPorts.Count - 1 ].Locked = ( m_currentLightModel != StandardShaderLightModel.CustomLighting ); + m_inputPorts[ m_inputPorts.Count - 1 ].GenType = PortGenType.CustomLighting; + m_customLightingPortId = m_inputPorts.Count - 1; + + //////////////////////////////////////////////////////////////////////////////////////////////// + // Vertex functions - Adding ordex index in order to force these to be the last ones + // Well now they have been moved to be the first ones so operations on vertex are to be taken into account + // by dither, screen position and similar nodes + //////////////////////////////////////////////////////////////////////////////////////////////// + m_vertexPortId = m_inputPorts.Count; + m_tessOpHelper.VertexOffsetIndexPort = m_vertexPortId; + AddInputPort( WirePortDataType.FLOAT3, false, ( m_vertexMode == VertexMode.Relative ? VertexDisplacementStr : VertexPositionStr ), VertexDataStr, 0/*index++*/, MasterNodePortCategory.Vertex, 11 ); + AddInputPort( WirePortDataType.FLOAT3, false, VertexNormalStr, 1/*index++*/, MasterNodePortCategory.Vertex, 12 ); + + //AddInputPort( WirePortDataType.FLOAT3, false, CustomLightModelStr, index++, MasterNodePortCategory.Fragment, 13 ); + //m_inputPorts[ m_inputPorts.Count - 1 ].Locked = true;// !(m_currentLightModel == StandardShaderLightModel.CustomLighting); + + AddInputPort( WirePortDataType.FLOAT4, false, TessellationOpHelper.TessellationPortStr, index++, MasterNodePortCategory.Tessellation, 14 ); + m_tessellationPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_tessOpHelper.MasterNodeIndexPort = m_tessellationPort.PortId; + + //////////////////////////////////////////////////////////////////////////////////// + AddInputPort( WirePortDataType.FLOAT3, false, DebugStr, index++, MasterNodePortCategory.Debug, 15 ); + + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + m_inputPorts[ i ].CustomColor = Color.white; + } + m_sizeIsDirty = true; + } + + public override void ForcePortType() + { + int portId = 0; + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + { + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + } + break; + case StandardShaderLightModel.StandardSpecular: + { + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + } + break; + case StandardShaderLightModel.CustomLighting: + { + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + } + break; + case StandardShaderLightModel.Unlit: + case StandardShaderLightModel.Lambert: + { + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + } + break; + case StandardShaderLightModel.BlinnPhong: + { + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + } + break; + } + + //Transmission + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + //Translucency + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + //Refraction + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + //Alpha + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + //Discard + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT, false ); + //Custom Lighting + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + //Vertex Offset + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + //Vertex Normal + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + //Tessellation + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT4, false ); + //Debug + m_inputPorts[ portId++ ].ChangeType( WirePortDataType.FLOAT3, false ); + } + + public override void SetName( string name ) + { + ShaderName = name; + } + + public void DrawInspectorProperty() + { + if( m_inspectorDefaultStyle == null ) + { + m_inspectorDefaultStyle = UIUtils.GetCustomStyle( CustomStyle.ResetToDefaultInspectorButton ); + } + + DrawCustomInspector( false ); + } + + private void RecursiveLog() + { + List<PropertyNode> nodes = UIUtils.PropertyNodesList(); + nodes.Sort( ( x, y ) => { return x.OrderIndex.CompareTo( y.OrderIndex ); } ); + for( int i = 0; i < nodes.Count; i++ ) + { + if( ( nodes[ i ] is ReordenatorNode ) ) + ( nodes[ i ] as ReordenatorNode ).RecursiveLog(); + else + Debug.Log( nodes[ i ].OrderIndex + " " + nodes[ i ].PropertyName ); + } + } + + public void DrawGeneralOptions() + { + DrawShaderName(); + DrawCurrentShaderType(); + + EditorGUI.BeginChangeCheck(); + m_currentLightModel = (StandardShaderLightModel)EditorGUILayoutEnumPopup( LightModelContent, m_currentLightModel ); + if( EditorGUI.EndChangeCheck() ) + { + ContainerGraph.ChangedLightingModel = true; + if( m_currentLightModel == StandardShaderLightModel.CustomLighting ) + { + ContainerGraph.ParentWindow.CurrentNodeAvailability = NodeAvailability.CustomLighting; + //ContainerGraph.CurrentCanvasMode = NodeAvailability.CustomLighting; + } + else + { + ContainerGraph.ParentWindow.CurrentNodeAvailability = NodeAvailability.SurfaceShader; + //ContainerGraph.CurrentCanvasMode = NodeAvailability.SurfaceShader; + } + } + + m_shaderModelIdx = EditorGUILayoutPopup( ShaderModelStr, m_shaderModelIdx, ShaderModelTypeArr ); + + EditorGUI.BeginChangeCheck(); + DrawPrecisionProperty( false ); + if( EditorGUI.EndChangeCheck() ) + ContainerGraph.CurrentPrecision = m_currentPrecisionType; + //m_cullMode = (CullMode)EditorGUILayoutEnumPopup( CullModeContent, m_cullMode ); + UndoParentNode inst = this; + m_inlineCullMode.CustomDrawer( ref inst, ( x ) => { m_cullMode = (CullMode)EditorGUILayoutEnumPopup( CullModeContent, m_cullMode ); }, CullModeContent.text ); + //m_inlineCullMode.Value = (int)m_cullMode; + //m_inlineCullMode.EnumTypePopup( ref inst, CullModeContent.text, Enum.GetNames( typeof( CullMode ) ) ); + //m_cullMode = (CullMode) m_inlineCullMode.Value; + + m_renderPath = (RenderPath)EditorGUILayoutEnumPopup( RenderPathContent, m_renderPath ); + + m_castShadows = EditorGUILayoutToggle( CastShadowsContent, m_castShadows ); + + m_receiveShadows = EditorGUILayoutToggle( ReceiveShadowsContent, m_receiveShadows ); + + m_drawInstancedHelper.Draw( this ); + + m_queueOrder = EditorGUILayoutIntField( QueueIndexContent, m_queueOrder ); + EditorGUI.BeginChangeCheck(); + m_vertexMode = (VertexMode)EditorGUILayoutEnumPopup( VertexModeStr, m_vertexMode ); + if( EditorGUI.EndChangeCheck() ) + { + m_inputPorts[ m_vertexPortId ].Name = m_vertexMode == VertexMode.Relative ? VertexDisplacementStr : VertexPositionStr; + m_sizeIsDirty = true; + } + + ShaderLOD = Mathf.Clamp( EditorGUILayoutIntField( ShaderLODContent, ShaderLOD ), 0, Shader.globalMaximumLOD ); + ////m_lodCrossfade = EditorGUILayoutToggle( LODCrossfadeContent, m_lodCrossfade ); + m_fallbackHelper.Draw( this ); + DrawInspectorProperty(); + + } + + public void ShowOpacityMaskValueUI() + { + EditorGUI.BeginChangeCheck(); + UndoParentNode inst = this; + m_inlineOpacityMaskClipValue.CustomDrawer( ref inst, ( x ) => { m_opacityMaskClipValue = EditorGUILayoutFloatField( OpacityMaskClipValueContent, m_opacityMaskClipValue ); }, OpacityMaskClipValueContent.text ); + if( EditorGUI.EndChangeCheck() ) + { + m_checkChanges = true; + if( m_currentMaterial != null && m_currentMaterial.HasProperty( IOUtils.MaskClipValueName ) ) + { + m_currentMaterial.SetFloat( IOUtils.MaskClipValueName, m_opacityMaskClipValue ); + } + } + } + + public override void DrawProperties() + { + if( m_inspectorFoldoutStyle == null || EditorGUIUtility.isProSkin != m_usingProSkin ) + m_inspectorFoldoutStyle = new GUIStyle( GUI.skin.GetStyle( "foldout" ) ); + + if( m_inspectorToolbarStyle == null || EditorGUIUtility.isProSkin != m_usingProSkin ) + { + m_inspectorToolbarStyle = new GUIStyle( GUI.skin.GetStyle( "toolbarbutton" ) ) + { + fixedHeight = 20 + }; + } + + if( m_inspectorTooldropdownStyle == null || EditorGUIUtility.isProSkin != m_usingProSkin ) + { + m_inspectorTooldropdownStyle = new GUIStyle( GUI.skin.GetStyle( "toolbardropdown" ) ) + { + fixedHeight = 20 + }; + m_inspectorTooldropdownStyle.margin.bottom = 2; + } + + if( EditorGUIUtility.isProSkin != m_usingProSkin ) + m_usingProSkin = EditorGUIUtility.isProSkin; + + base.DrawProperties(); + + EditorGUILayout.BeginVertical(); + { + EditorGUILayout.Separator(); + + m_titleOpacity = 0.5f; + m_boxOpacity = ( EditorGUIUtility.isProSkin ? 0.5f : 0.25f ); + m_cachedColor = GUI.color; + + // General + bool generalIsVisible = ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedGeneralShaderOptions; + NodeUtils.DrawPropertyGroup( ref generalIsVisible, GeneralFoldoutStr, DrawGeneralOptions ); + ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedGeneralShaderOptions = generalIsVisible; + + //Blend Mode + GUI.color = new Color( m_cachedColor.r, m_cachedColor.g, m_cachedColor.b, m_titleOpacity ); + EditorGUILayout.BeginHorizontal( m_inspectorToolbarStyle ); + GUI.color = m_cachedColor; + + bool blendOptionsVisible = GUILayout.Toggle( ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedBlendOptions, AlphaModeContent, UIUtils.MenuItemToggleStyle, GUILayout.ExpandWidth( true ) ); + if( Event.current.button == Constants.FoldoutMouseId ) + { + ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedBlendOptions = blendOptionsVisible; + } + + + if( !EditorGUIUtility.isProSkin ) + GUI.color = new Color( 0.25f, 0.25f, 0.25f, 1f ); + + float boxSize = 60; + switch( m_alphaMode ) + { + case AlphaMode.Transparent: + boxSize = 85; + break; + case AlphaMode.Translucent: + boxSize = 80; + break; + case AlphaMode.Premultiply: + boxSize = 120; + break; + } + EditorGUI.BeginChangeCheck(); + m_alphaMode = (AlphaMode)EditorGUILayoutPopup( string.Empty, (int)m_alphaMode, FadeModeOptions, UIUtils.InspectorPopdropdownStyle, GUILayout.Width( boxSize ), GUILayout.Height( 19 ) ); + if( EditorGUI.EndChangeCheck() ) + { + UpdateFromBlendMode(); + } + + GUI.color = m_cachedColor; + EditorGUILayout.EndHorizontal(); + + m_customBlendAvailable = ( m_alphaMode == AlphaMode.Custom || m_alphaMode == AlphaMode.Opaque ); + + if( ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedBlendOptions ) + { + GUI.color = new Color( m_cachedColor.r, m_cachedColor.g, m_cachedColor.b, m_boxOpacity ); + EditorGUILayout.BeginVertical( UIUtils.MenuItemBackgroundStyle ); + GUI.color = m_cachedColor; + EditorGUI.indentLevel++; + EditorGUILayout.Separator(); + EditorGUI.BeginChangeCheck(); + + + m_renderType = (RenderType)EditorGUILayoutEnumPopup( RenderTypeContent, m_renderType ); + if( m_renderType == RenderType.Custom ) + { + EditorGUI.BeginChangeCheck(); + m_customRenderType = EditorGUILayoutTextField( CustomRenderTypeStr, m_customRenderType ); + if( EditorGUI.EndChangeCheck() ) + { + m_customRenderType = UIUtils.RemoveInvalidCharacters( m_customRenderType ); + } + } + + m_renderQueue = (RenderQueue)EditorGUILayoutEnumPopup( RenderQueueContent, m_renderQueue ); + + if( EditorGUI.EndChangeCheck() ) + { + if( m_renderType == RenderType.Opaque && m_renderQueue == RenderQueue.Geometry ) + m_alphaMode = AlphaMode.Opaque; + else if( m_renderType == RenderType.TransparentCutout && m_renderQueue == RenderQueue.AlphaTest ) + m_alphaMode = AlphaMode.Masked; + else if( m_renderType == RenderType.Transparent && m_renderQueue == RenderQueue.Transparent ) + m_alphaMode = AlphaMode.Transparent; + else if( m_renderType == RenderType.Opaque && m_renderQueue == RenderQueue.Transparent ) + m_alphaMode = AlphaMode.Translucent; + else + m_alphaMode = AlphaMode.Custom; + + + UpdateFromBlendMode(); + } + + bool bufferedEnabled = GUI.enabled; + + GUI.enabled = ( m_alphaMode == AlphaMode.Masked || m_alphaMode == AlphaMode.Custom ); + m_inputPorts[ m_discardPortId ].Locked = !GUI.enabled; + ShowOpacityMaskValueUI(); + + GUI.enabled = bufferedEnabled; + + EditorGUI.BeginDisabledGroup( !( m_alphaMode == AlphaMode.Transparent || m_alphaMode == AlphaMode.Premultiply || m_alphaMode == AlphaMode.Translucent || m_alphaMode == AlphaMode.Custom ) ); + m_grabOrder = EditorGUILayoutIntField( RefractionLayerStr, m_grabOrder ); + float cachedLabelWidth = EditorGUIUtility.labelWidth; + UndoParentNode inst = this; + if( m_refractionPort.IsConnected ) + { + EditorGUIUtility.labelWidth = 145; + EditorGUI.BeginChangeCheck(); + m_inlineChromaticAberration.RangedFloatField( ref inst, ChromaticAberrationStr, 0.0f,0.3f ); + if( EditorGUI.EndChangeCheck() ) + { + if( m_currentMaterial != null && m_currentMaterial.HasProperty( IOUtils.ChromaticAberrationProperty ) ) + { + m_currentMaterial.SetFloat( IOUtils.ChromaticAberrationProperty, m_inlineChromaticAberration.FloatValue ); + } + } + } + + EditorGUIUtility.labelWidth = 130; + m_inlineAlphaToCoverage.CustomDrawer( ref inst, ( x ) => { m_alphaToCoverage = EditorGUILayoutToggle( AlphaToCoverageStr, m_alphaToCoverage ); }, AlphaToCoverageStr.text ); + EditorGUIUtility.labelWidth = cachedLabelWidth; + EditorGUI.EndDisabledGroup(); + + EditorGUILayout.Separator(); + + if( !m_customBlendAvailable ) + { + EditorGUILayout.HelpBox( "Advanced options are only available for Custom blend modes", MessageType.Warning ); + } + + EditorGUI.BeginDisabledGroup( !m_customBlendAvailable ); + m_blendOpsHelper.Draw( this, m_customBlendAvailable ); + m_colorMaskHelper.Draw( this ); + + EditorGUI.EndDisabledGroup(); + EditorGUILayout.Separator(); + EditorGUI.indentLevel--; + EditorGUILayout.EndVertical(); + } + + m_stencilBufferHelper.Draw( this ); + m_tessOpHelper.Draw( this, m_inspectorToolbarStyle, m_currentMaterial, m_tessellationPort.IsConnected ); + m_outlineHelper.Draw( this, m_inspectorToolbarStyle, m_currentMaterial ); + m_billboardOpHelper.Draw( this ); + m_zBufferHelper.Draw( this, m_inspectorToolbarStyle, m_customBlendAvailable ); + m_renderingOptionsOpHelper.Draw( this ); + m_renderingPlatformOpHelper.Draw( this ); + //m_additionalDefines.Draw( this ); + //m_additionalIncludes.Draw( this ); + //m_additionalPragmas.Draw( this ); + m_additionalSurfaceOptions.Draw( this ); + m_usePass.Draw( this ); + m_additionalDirectives.Draw( this ); + m_customTagsHelper.Draw( this ); + m_dependenciesHelper.Draw( this ); + DrawMaterialInputs( m_inspectorToolbarStyle ); + } + + EditorGUILayout.EndVertical(); + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + + if( m_initialize ) + { + m_initialize = false; + + if( m_dummyProperty == null ) + { + m_dummyProperty = ScriptableObject.CreateInstance<PropertyNode>(); + m_dummyProperty.ContainerGraph = ContainerGraph; + } + } + + if( m_currentLightModel != m_lastLightModel ) + m_lightModelChanged = true; + + if( m_lightModelChanged ) + { + m_lightModelChanged = false; + if( m_currentLightModel == StandardShaderLightModel.BlinnPhong ) + { + if( m_specColorReorder == null ) + { + m_specColorReorder = ScriptableObject.CreateInstance<ReordenatorNode>(); + m_specColorReorder.ContainerGraph = ContainerGraph; + m_specColorReorder.OrderIndex = m_specColorOrderIndex; + m_specColorReorder.Init( "_SpecColor", "Specular Color", null ); + } + + UIUtils.RegisterPropertyNode( m_specColorReorder ); + } + else + { + if( m_specColorReorder != null ) + UIUtils.UnregisterPropertyNode( m_specColorReorder ); + } + + if( m_currentLightModel == StandardShaderLightModel.CustomLighting && m_masterNodeCategory == 0 ) + ContainerGraph.CurrentCanvasMode = NodeAvailability.CustomLighting; + else if( m_masterNodeCategory == 0 ) + ContainerGraph.CurrentCanvasMode = NodeAvailability.SurfaceShader; + CacheCurrentSettings(); + m_lastLightModel = m_currentLightModel; + DeleteAllInputConnections( true, true ); + AddMasterPorts(); + ConnectFromCache(); + } + + if( drawInfo.CurrentEventType != EventType.Layout ) + return; + + if( m_transmissionPort != null && m_transmissionPort.IsConnected && m_renderPath != RenderPath.ForwardOnly ) + { + m_renderPath = RenderPath.ForwardOnly; + UIUtils.ShowMessage( "Render Path changed to Forward Only since transmission only works in forward rendering" ); + } + + if( m_translucencyPort != null && m_translucencyPort.IsConnected && m_renderPath != RenderPath.ForwardOnly ) + { + m_renderPath = RenderPath.ForwardOnly; + UIUtils.ShowMessage( "Render Path changed to Forward Only since translucency only works in forward rendering" ); + } + + if( m_translucencyPort.IsConnected != m_previousTranslucencyOn ) + m_checkChanges = true; + + if( m_refractionPort.IsConnected != m_previousRefractionOn ) + m_checkChanges = true; + + if( ( m_tessOpHelper.EnableTesselation && !m_tessellationPort.IsConnected ) != m_previousTessellationOn ) + m_checkChanges = true; + + m_previousTranslucencyOn = m_translucencyPort.IsConnected; + + m_previousRefractionOn = m_refractionPort.IsConnected; + + m_previousTessellationOn = ( m_tessOpHelper.EnableTesselation && !m_tessellationPort.IsConnected ); + + if( m_checkChanges ) + { + if( m_translucencyPort.IsConnected ) + { + if( m_translucencyReorder == null ) + { + List<PropertyNode> translucencyList = new List<PropertyNode>(); + for( int i = 0; i < 7; i++ ) + { + translucencyList.Add( m_dummyProperty ); + } + + m_translucencyReorder = ScriptableObject.CreateInstance<ReordenatorNode>(); + m_translucencyReorder.ContainerGraph = ContainerGraph; + m_translucencyReorder.OrderIndex = m_translucencyOrderIndex; + m_translucencyReorder.Init( "_TranslucencyGroup", "Translucency", translucencyList ); + } + + UIUtils.RegisterPropertyNode( m_translucencyReorder ); + } + else + { + if( m_translucencyReorder != null ) + UIUtils.UnregisterPropertyNode( m_translucencyReorder ); + } + + if( m_refractionPort.IsConnected ) + { + if( m_refractionReorder == null ) + { + List<PropertyNode> refractionList = new List<PropertyNode>(); + for( int i = 0; i < 2; i++ ) + { + refractionList.Add( m_dummyProperty ); + } + + m_refractionReorder = ScriptableObject.CreateInstance<ReordenatorNode>(); + m_refractionReorder.ContainerGraph = ContainerGraph; + m_refractionReorder.OrderIndex = m_refractionOrderIndex; + m_refractionReorder.Init( "_RefractionGroup", "Refraction", refractionList ); + } + + UIUtils.RegisterPropertyNode( m_refractionReorder ); + } + else + { + if( m_refractionReorder != null ) + UIUtils.UnregisterPropertyNode( m_refractionReorder ); + } + + if( m_tessOpHelper.EnableTesselation && !m_tessellationPort.IsConnected ) + { + if( m_tessellationReorder == null ) + { + List<PropertyNode> tessellationList = new List<PropertyNode>(); + for( int i = 0; i < 4; i++ ) + { + tessellationList.Add( m_dummyProperty ); + } + + m_tessellationReorder = ScriptableObject.CreateInstance<ReordenatorNode>(); + m_tessellationReorder.ContainerGraph = ContainerGraph; + m_tessellationReorder.OrderIndex = m_tessellationOrderIndex; + m_tessellationReorder.Init( "_TessellationGroup", "Tessellation", tessellationList ); + m_tessellationReorder.HeaderTitle = "Tesselation"; + } + + UIUtils.RegisterPropertyNode( m_tessellationReorder ); + } + else + { + if( m_tessellationReorder != null ) + UIUtils.UnregisterPropertyNode( m_tessellationReorder ); + } + + if( m_inputPorts[ m_discardPortId ].Available && !m_inlineOpacityMaskClipValue.IsValid ) + { + if( m_maskClipReorder == null ) + { + // Create dragable clip material property + m_maskClipReorder = ScriptableObject.CreateInstance<ReordenatorNode>(); + m_maskClipReorder.ContainerGraph = ContainerGraph; + m_maskClipReorder.OrderIndex = m_maskClipOrderIndex; + m_maskClipReorder.Init( "_Cutoff", "Mask Clip Value", null ); + } + + UIUtils.RegisterPropertyNode( m_maskClipReorder ); + } + else + { + if( m_maskClipReorder != null ) + UIUtils.UnregisterPropertyNode( m_maskClipReorder ); + } + + m_checkChanges = false; + } + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if( m_containerGraph.IsInstancedShader || m_renderingOptionsOpHelper.ForceEnableInstancing ) + { + DrawInstancedIcon( drawInfo ); + } + } + + private void CacheCurrentSettings() + { + m_cacheNodeConnections.Clear(); + for( int portId = 0; portId < m_inputPorts.Count; portId++ ) + { + if( m_inputPorts[ portId ].IsConnected ) + { + WireReference connection = m_inputPorts[ portId ].GetConnection(); + m_cacheNodeConnections.Add( m_inputPorts[ portId ].Name, new NodeCache( connection.NodeId, connection.PortId ) ); + } + } + } + + private void ConnectFromCache() + { + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + NodeCache cache = m_cacheNodeConnections.Get( m_inputPorts[ i ].Name ); + if( cache != null ) + { + UIUtils.SetConnection( UniqueId, m_inputPorts[ i ].PortId, cache.TargetNodeId, cache.TargetPortId ); + } + } + } + + public override void UpdateMaterial( Material mat ) + { + base.UpdateMaterial( mat ); + if( m_alphaMode == AlphaMode.Masked || m_alphaMode == AlphaMode.Custom ) + { + if( mat.HasProperty( IOUtils.MaskClipValueName ) ) + mat.SetFloat( IOUtils.MaskClipValueName, m_opacityMaskClipValue ); + } + + if( m_refractionPort.IsConnected && !m_inlineChromaticAberration.Active ) + { + if( mat.HasProperty( IOUtils.ChromaticAberrationProperty ) ) + mat.SetFloat( IOUtils.ChromaticAberrationProperty, m_inlineChromaticAberration.FloatValue ); + } + } + + public override void SetMaterialMode( Material mat, bool fetchMaterialValues ) + { + base.SetMaterialMode( mat, fetchMaterialValues ); + if( m_alphaMode == AlphaMode.Masked || m_alphaMode == AlphaMode.Custom ) + { + if( fetchMaterialValues && m_materialMode && mat.HasProperty( IOUtils.MaskClipValueName ) ) + { + m_opacityMaskClipValue = mat.GetFloat( IOUtils.MaskClipValueName ); + } + } + + if( m_refractionPort.IsConnected && !m_inlineChromaticAberration.Active ) + { + if( fetchMaterialValues && m_materialMode && mat.HasProperty( IOUtils.ChromaticAberrationProperty ) ) + m_inlineChromaticAberration.FloatValue = mat.GetFloat( IOUtils.ChromaticAberrationProperty); + } + } + + public override void ForceUpdateFromMaterial( Material material ) + { + m_tessOpHelper.UpdateFromMaterial( material ); + m_outlineHelper.UpdateFromMaterial( material ); + + if( m_alphaMode == AlphaMode.Masked || m_alphaMode == AlphaMode.Custom ) + { + if( material.HasProperty( IOUtils.MaskClipValueName ) ) + m_opacityMaskClipValue = material.GetFloat( IOUtils.MaskClipValueName ); + } + + if( m_refractionPort.IsConnected && !m_inlineChromaticAberration.Active ) + { + if( material.HasProperty( IOUtils.ChromaticAberrationProperty ) ) + m_inlineChromaticAberration.FloatValue = material.GetFloat( IOUtils.ChromaticAberrationProperty ); + } + } + + public override void UpdateMasterNodeMaterial( Material material ) + { + m_currentMaterial = material; + UpdateMaterialEditor(); + } + + void UpdateMaterialEditor() + { + FireMaterialChangedEvt(); + } + + public string CreateInstructionsForVertexPort( InputPort port ) + { + //Vertex displacement and per vertex custom data + WireReference connection = port.GetConnection(); + ParentNode node = UIUtils.GetNode( connection.NodeId ); + + string vertexInstructions = node.GetValueFromOutputStr( connection.PortId, port.DataType, ref m_currentDataCollector, false ); + + if( m_currentDataCollector.DirtySpecialLocalVariables ) + { + m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.SpecialLocalVariables, UniqueId, false ); + m_currentDataCollector.ClearSpecialLocalVariables(); + } + + if( m_currentDataCollector.DirtyVertexVariables ) + { + m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, UniqueId, false ); + m_currentDataCollector.ClearVertexLocalVariables(); + } + + return vertexInstructions; + } + + public void CreateInstructionsForPort( InputPort port, string portName, bool addCustomDelimiters = false, string customDelimiterIn = null, string customDelimiterOut = null, bool ignoreLocalVar = false, bool normalIsConnected = false , bool isDebugPort = false ) + { + WireReference connection = port.GetConnection(); + ParentNode node = UIUtils.GetNode( connection.NodeId ); + + string newInstruction = node.GetValueFromOutputStr( connection.PortId, port.DataType, ref m_currentDataCollector, ignoreLocalVar ); + + if( m_currentDataCollector.DirtySpecialLocalVariables ) + { + m_currentDataCollector.AddInstructions( m_currentDataCollector.SpecialLocalVariables ); + m_currentDataCollector.ClearSpecialLocalVariables(); + } + + if( m_currentDataCollector.DirtyVertexVariables ) + { + m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, port.NodeId, false ); + m_currentDataCollector.ClearVertexLocalVariables(); + } + + if( m_currentDataCollector.ForceNormal && !normalIsConnected ) + { + m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" ); + m_currentDataCollector.DirtyNormal = true; + m_currentDataCollector.ForceNormal = false; + } + + m_currentDataCollector.AddInstructions( addCustomDelimiters ? customDelimiterIn : ( "\t\t\t" + portName + " = " ) ); + m_currentDataCollector.AddInstructions( newInstruction ); + m_currentDataCollector.AddInstructions( addCustomDelimiters ? customDelimiterOut :((isDebugPort)?" + 1E-5;\n":";\n") ); + } + + public string CreateInstructionStringForPort( InputPort port, bool ignoreLocalVar = false ) + { + WireReference connection = port.GetConnection(); + ParentNode node = UIUtils.GetNode( connection.NodeId ); + + string newInstruction = node.GetValueFromOutputStr( connection.PortId, port.DataType, ref m_currentDataCollector, ignoreLocalVar ); + + if( m_currentDataCollector.DirtySpecialLocalVariables ) + { + m_currentDataCollector.AddInstructions( m_currentDataCollector.SpecialLocalVariables ); + m_currentDataCollector.ClearSpecialLocalVariables(); + } + + if( m_currentDataCollector.DirtyVertexVariables ) + { + m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, port.NodeId, false ); + m_currentDataCollector.ClearVertexLocalVariables(); + } + + if( m_currentDataCollector.ForceNormal ) + { + m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" ); + m_currentDataCollector.DirtyNormal = true; + m_currentDataCollector.ForceNormal = false; + } + + return newInstruction; + } + + public override Shader Execute( string pathname, bool isFullPath ) + { + ForcePortType(); + ForceReordering(); + UpdateFromBlendMode(); + base.Execute( pathname, isFullPath ); + RegisterStandaloneFuntions(); + + bool isInstancedShader = m_renderingOptionsOpHelper.ForceEnableInstancing || UIUtils.IsInstancedShader(); + bool hasVirtualTexture = UIUtils.HasVirtualTexture(); + bool hasTranslucency = false; + bool hasTransmission = false; + bool hasEmission = false; + bool hasOpacity = false; + bool hasOpacityMask = false; + bool hasRefraction = false; + //bool hasVertexOffset = false; + //bool hasCustomLightingAlpha = false; + bool hasCustomLightingMask = false; + + string customLightingCode = string.Empty; + string customLightingAlphaCode = string.Empty; + string customLightingMaskCode = string.Empty; + string customLightingInstructions = string.Empty; + + string refractionCode = string.Empty; + string refractionInstructions = string.Empty; + string refractionFix = string.Empty; + + string aboveUsePasses = string.Empty; + string bellowUsePasses = string.Empty; + + + m_currentDataCollector.TesselationActive = m_tessOpHelper.EnableTesselation; + m_currentDataCollector.CurrentRenderPath = m_renderPath; + + StandardShaderLightModel cachedLightModel = m_currentLightModel; + NodeAvailability cachedAvailability = ContainerGraph.CurrentCanvasMode; + + bool debugIsUsingCustomLighting = false; + bool usingDebugPort = false; + if( m_inputPorts[ m_inputPorts.Count - 1 ].IsConnected ) + { + usingDebugPort = true; + debugIsUsingCustomLighting = m_currentLightModel == StandardShaderLightModel.CustomLighting; + + m_currentDataCollector.GenType = PortGenType.CustomLighting; + m_currentLightModel = StandardShaderLightModel.CustomLighting; + ContainerGraph.CurrentCanvasMode = NodeAvailability.CustomLighting; + } + + if( isInstancedShader ) + { + m_currentDataCollector.AddToPragmas( UniqueId, IOUtils.InstancedPropertiesHeader ); + } + + if( m_renderingOptionsOpHelper.SpecularHighlightToggle || m_renderingOptionsOpHelper.ReflectionsToggle ) + m_currentDataCollector.AddToProperties( UniqueId, "[Header(Forward Rendering Options)]", 10001 ); + if( m_renderingOptionsOpHelper.SpecularHighlightToggle ) + { + m_currentDataCollector.AddToProperties( UniqueId, "[ToggleOff] _SpecularHighlights(\"Specular Highlights\", Float) = 1.0", 10002 ); + m_currentDataCollector.AddToPragmas( UniqueId, "shader_feature _SPECULARHIGHLIGHTS_OFF" ); + } + if( m_renderingOptionsOpHelper.ReflectionsToggle ) + { + m_currentDataCollector.AddToProperties( UniqueId, "[ToggleOff] _GlossyReflections(\"Reflections\", Float) = 1.0", 10003 ); + m_currentDataCollector.AddToPragmas( UniqueId, "shader_feature _GLOSSYREFLECTIONS_OFF" ); + } + + + // See if each node is being used on frag and/or vert ports + SetupNodeCategories(); + m_containerGraph.CheckPropertiesAutoRegister( ref m_currentDataCollector ); + + if( m_refractionPort.IsConnected || m_inputPorts[ m_inputPorts.Count - 1 ].IsConnected ) + { + m_currentDataCollector.DirtyNormal = true; + m_currentDataCollector.ForceNormal = true; + } + //this.PropagateNodeData( nodeData ); + + string tags = "\"RenderType\" = \"{0}\" \"Queue\" = \"{1}\""; + string finalRenderType = ( m_renderType == RenderType.Custom && m_customRenderType.Length > 0 ) ? m_customRenderType : m_renderType.ToString(); + tags = string.Format( tags, finalRenderType, ( m_renderQueue + ( ( m_queueOrder >= 0 ) ? "+" : string.Empty ) + m_queueOrder ) ); + //if ( !m_customBlendMode ) + { + if( m_alphaMode == AlphaMode.Transparent || m_alphaMode == AlphaMode.Premultiply ) + { + //tags += " \"IgnoreProjector\" = \"True\""; + if( !m_renderingOptionsOpHelper.IgnoreProjectorValue ) + { + Debug.Log( string.Format( "Setting Ignore Projector to True since it's requires by Blend Mode {0}.", m_alphaMode ) ); + m_renderingOptionsOpHelper.IgnoreProjectorValue = true; + } + } + } + + tags += m_renderingOptionsOpHelper.IgnoreProjectorTag; + tags += m_renderingOptionsOpHelper.ForceNoShadowCastingTag; + tags += m_renderingOptionsOpHelper.DisableBatchingTag; + + //add virtual texture support + if( hasVirtualTexture ) + { + tags += " \"Amplify\" = \"True\" "; + } + + //tags = "Tags{ " + tags + " }"; + + string outputStruct = ""; + switch( m_currentLightModel ) + { + case StandardShaderLightModel.CustomLighting: outputStruct = "SurfaceOutputCustomLightingCustom"; break; + case StandardShaderLightModel.Standard: outputStruct = "SurfaceOutputStandard"; break; + case StandardShaderLightModel.StandardSpecular: outputStruct = "SurfaceOutputStandardSpecular"; break; + case StandardShaderLightModel.Unlit: + case StandardShaderLightModel.Lambert: + case StandardShaderLightModel.BlinnPhong: outputStruct = "SurfaceOutput"; break; + } + + if( m_currentLightModel == StandardShaderLightModel.CustomLighting ) + { + m_currentDataCollector.AddToIncludes( UniqueId, Constants.UnityPBSLightingLib ); + + m_currentDataCollector.ChangeCustomInputHeader( m_currentLightModel.ToString() + Constants.CustomLightStructStr ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Albedo", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Normal", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Emission", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half Metallic", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half Smoothness", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half Occlusion", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half Alpha", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "Input SurfInput", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "UnityGIInput GIData", true ); + } + + //Terrain Draw Instanced + if( m_drawInstancedHelper.Enabled ) + { + if( !m_currentDataCollector.DirtyPerVertexData ) + { + m_currentDataCollector.OpenPerVertexHeader( !m_tessOpHelper.EnableTesselation ); + } + m_drawInstancedHelper.UpdateDataCollectorForStandard( ref m_currentDataCollector ); + } + + // Need to sort before creating local vars so they can inspect the normal port correctly + SortedList<int, InputPort> sortedPorts = new SortedList<int, InputPort>(); + for( int i = 0; i < m_inputPorts.Count; i++ ) + { + sortedPorts.Add( m_inputPorts[ i ].OrderId, m_inputPorts[ i ] ); + } + + bool normalIsConnected = m_normalPort.IsConnected; + m_tessOpHelper.Reset(); + if( m_inputPorts[ m_inputPorts.Count - 1 ].IsConnected ) + { + //Debug Port active + InputPort debugPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_currentDataCollector.PortCategory = debugPort.Category; + if( debugIsUsingCustomLighting ) + { + m_currentDataCollector.UsingCustomOutput = true; + WireReference connection = m_inputPorts[ m_inputPorts.Count - 1 ].GetConnection(); + ParentNode node = UIUtils.GetNode( connection.NodeId ); + customLightingCode = node.GetValueFromOutputStr( connection.PortId, WirePortDataType.FLOAT3, ref m_currentDataCollector, false ); + customLightingInstructions = m_currentDataCollector.CustomOutput; + + if( m_currentDataCollector.ForceNormal ) + { + m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" ); + m_currentDataCollector.DirtyNormal = true; + m_currentDataCollector.ForceNormal = false; + } + + if( m_currentDataCollector.DirtyVertexVariables ) + { + m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, UniqueId, false ); + m_currentDataCollector.ClearVertexLocalVariables(); + } + m_currentDataCollector.UsingCustomOutput = false; + } + else + { + CreateInstructionsForPort( debugPort, Constants.OutputVarStr + ".Emission", false, null, null, false, false,true ); + } + } + else + { + MasterNodePortCategory currentCategory = sortedPorts[ 0 ].Category; + //Collect data from standard nodes + for( int i = 0; i < sortedPorts.Count; i++ ) + { + // prepare ports for custom lighting + m_currentDataCollector.GenType = sortedPorts[ i ].GenType; + if( m_currentLightModel == StandardShaderLightModel.CustomLighting && sortedPorts[ i ].Name.Equals( AlphaStr ) ) + ContainerGraph.ResetNodesLocalVariablesIfNot( MasterNodePortCategory.Vertex ); + + if( sortedPorts[ i ].IsConnected ) + { + m_currentDataCollector.PortCategory = sortedPorts[ i ].Category; + + if( sortedPorts[ i ].Name.Equals( NormalStr ) )// Normal Map is Connected + { + m_currentDataCollector.DirtyNormal = true; + } + if( sortedPorts[ i ].Name.Equals( TranslucencyStr ) ) + { + hasTranslucency = true; + } + if( sortedPorts[ i ].Name.Equals( TransmissionStr ) ) + { + hasTransmission = true; + } + if( sortedPorts[ i ].Name.Equals( EmissionStr ) ) + { + hasEmission = true; + } + + if( sortedPorts[ i ].Name.Equals( RefractionStr ) ) + { + hasRefraction = true; + } + + if( sortedPorts[ i ].Name.Equals( AlphaStr ) ) + { + hasOpacity = true; + } + + if( sortedPorts[ i ].Name.Equals( DiscardStr ) ) + { + hasOpacityMask = true; + } + + if( hasRefraction ) + { + m_currentDataCollector.AddToInput( UniqueId, SurfaceInputs.SCREEN_POS ); + m_currentDataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_POS ); + + //not necessary, just being safe + m_currentDataCollector.DirtyNormal = true; + m_currentDataCollector.ForceNormal = true; + + if( m_grabOrder != 0 ) + { + m_currentDataCollector.AddGrabPass( "RefractionGrab" + m_grabOrder ); + m_currentDataCollector.AddToUniforms( UniqueId, "uniform sampler2D RefractionGrab" + m_grabOrder + ";" ); + } + else + { + m_currentDataCollector.AddGrabPass( "" ); + m_currentDataCollector.AddToUniforms( UniqueId, "uniform sampler2D _GrabTexture;" ); + } + + if( !m_inlineChromaticAberration.Active ) + { + m_currentDataCollector.AddToUniforms( UniqueId, "uniform float _ChromaticAberration;" ); + + m_currentDataCollector.AddToProperties( UniqueId, "[Header(Refraction)]", m_refractionReorder.OrderIndex ); + m_currentDataCollector.AddToProperties( UniqueId, "_ChromaticAberration(\"Chromatic Aberration\", Range( 0 , 0.3)) = 0.1", m_refractionReorder.OrderIndex + 1 ); + } + + m_currentDataCollector.AddToPragmas( UniqueId, "multi_compile _ALPHAPREMULTIPLY_ON" ); + } + + if( hasTranslucency || hasTransmission ) + { + //Translucency and Transmission Generation + + //Add properties and uniforms + m_currentDataCollector.AddToIncludes( UniqueId, Constants.UnityPBSLightingLib ); + + if( hasTranslucency ) + { + m_currentDataCollector.AddToProperties( UniqueId, "[Header(Translucency)]", m_translucencyReorder.OrderIndex ); + m_currentDataCollector.AddToProperties( UniqueId, "_Translucency(\"Strength\", Range( 0 , 50)) = 1", m_translucencyReorder.OrderIndex + 1 ); + m_currentDataCollector.AddToProperties( UniqueId, "_TransNormalDistortion(\"Normal Distortion\", Range( 0 , 1)) = 0.1", m_translucencyReorder.OrderIndex + 2 ); + m_currentDataCollector.AddToProperties( UniqueId, "_TransScattering(\"Scaterring Falloff\", Range( 1 , 50)) = 2", m_translucencyReorder.OrderIndex + 3 ); + m_currentDataCollector.AddToProperties( UniqueId, "_TransDirect(\"Direct\", Range( 0 , 1)) = 1", m_translucencyReorder.OrderIndex + 4 ); + m_currentDataCollector.AddToProperties( UniqueId, "_TransAmbient(\"Ambient\", Range( 0 , 1)) = 0.2", m_translucencyReorder.OrderIndex + 5 ); + m_currentDataCollector.AddToProperties( UniqueId, "_TransShadow(\"Shadow\", Range( 0 , 1)) = 0.9", m_translucencyReorder.OrderIndex + 6 ); + + m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _Translucency;" ); + m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransNormalDistortion;" ); + m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransScattering;" ); + m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransDirect;" ); + m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransAmbient;" ); + m_currentDataCollector.AddToUniforms( UniqueId, "uniform half _TransShadow;" ); + } + + //Add custom struct + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + case StandardShaderLightModel.StandardSpecular: + outputStruct = "SurfaceOutput" + m_currentLightModel.ToString() + Constants.CustomLightStructStr; break; + } + + m_currentDataCollector.ChangeCustomInputHeader( m_currentLightModel.ToString() + Constants.CustomLightStructStr ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Albedo", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Normal", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Emission", true ); + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + m_currentDataCollector.AddToCustomInput( UniqueId, "half Metallic", true ); + break; + case StandardShaderLightModel.StandardSpecular: + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Specular", true ); + break; + } + m_currentDataCollector.AddToCustomInput( UniqueId, "half Smoothness", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half Occlusion", true ); + m_currentDataCollector.AddToCustomInput( UniqueId, "half Alpha", true ); + if( hasTranslucency ) + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Translucency", true ); + + if( hasTransmission ) + m_currentDataCollector.AddToCustomInput( UniqueId, "half3 Transmission", true ); + } + + if( sortedPorts[ i ].Name.Equals( DiscardStr ) ) + { + //Discard Op Node + if( m_currentLightModel == StandardShaderLightModel.CustomLighting ) + { + hasCustomLightingMask = true; + m_currentDataCollector.UsingCustomOutput = true; + m_currentDataCollector.GenType = PortGenType.CustomLighting; + WireReference connection = sortedPorts[ i ].GetConnection(); + ParentNode node = UIUtils.GetNode( connection.NodeId ); + + customLightingMaskCode = node.GetValueFromOutputStr( connection.PortId, WirePortDataType.FLOAT, ref m_currentDataCollector, false ); + customLightingMaskCode = "clip( " + customLightingMaskCode + " - " + m_inlineOpacityMaskClipValue.GetValueOrProperty( IOUtils.MaskClipValueName, false ) + " )"; + customLightingInstructions = m_currentDataCollector.CustomOutput; + + m_currentDataCollector.GenType = PortGenType.NonCustomLighting; + m_currentDataCollector.UsingCustomOutput = false; + continue; + } + else + { + string clipIn = "\t\t\tclip( "; + string clipOut = " - " + m_inlineOpacityMaskClipValue.GetValueOrProperty( IOUtils.MaskClipValueName, false ) + " );\n"; + //if( ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) && m_castShadows ) + //{ + // clipIn = "\t\t\t#if UNITY_PASS_SHADOWCASTER\n" + clipIn; + // clipOut = clipOut + "\t\t\t#endif\n"; + //} + CreateInstructionsForPort( sortedPorts[ i ], Constants.OutputVarStr + "." + sortedPorts[ i ].DataName, true, clipIn, clipOut, false, normalIsConnected ); + } + } + else if( sortedPorts[ i ].DataName.Equals( VertexDataStr ) ) + { + string vertexInstructions = CreateInstructionsForVertexPort( sortedPorts[ i ] ); + m_currentDataCollector.AddToVertexDisplacement( vertexInstructions, m_vertexMode ); + } + else if( sortedPorts[ i ].DataName.Equals( VertexNormalStr ) ) + { + string vertexInstructions = CreateInstructionsForVertexPort( sortedPorts[ i ] ); + m_currentDataCollector.AddToVertexNormal( vertexInstructions ); + } + else if( m_tessOpHelper.IsTessellationPort( sortedPorts[ i ].PortId ) && sortedPorts[ i ].IsConnected /* && m_tessOpHelper.EnableTesselation*/) + { + //Vertex displacement and per vertex custom data + WireReference connection = sortedPorts[ i ].GetConnection(); + ParentNode node = UIUtils.GetNode( connection.NodeId ); + + string vertexInstructions = node.GetValueFromOutputStr( connection.PortId, sortedPorts[ i ].DataType, ref m_currentDataCollector, false ); + + if( m_currentDataCollector.DirtySpecialLocalVariables ) + { + m_tessOpHelper.AddAdditionalData( m_currentDataCollector.SpecialLocalVariables ); + m_currentDataCollector.ClearSpecialLocalVariables(); + } + + if( m_currentDataCollector.DirtyVertexVariables ) + { + m_tessOpHelper.AddAdditionalData( m_currentDataCollector.VertexLocalVariables ); + m_currentDataCollector.ClearVertexLocalVariables(); + } + + m_tessOpHelper.AddCustomFunction( vertexInstructions ); + } + else if( sortedPorts[ i ].Name.Equals( RefractionStr ) ) + { + ContainerGraph.ResetNodesLocalVariables(); + m_currentDataCollector.UsingCustomOutput = true; + + refractionFix = " + 0.00001 * i.screenPos * i.worldPos"; + m_currentDataCollector.AddInstructions( "\t\t\to.Normal = o.Normal" + refractionFix + ";\n" ); + refractionCode = CreateInstructionStringForPort( sortedPorts[ i ], false ); + refractionInstructions = m_currentDataCollector.CustomOutput; + + m_currentDataCollector.UsingCustomOutput = false; + } + else if( sortedPorts[ i ].Name.Equals( CustomLightingStr ) ) + { + m_currentDataCollector.UsingCustomOutput = true; + WireReference connection = sortedPorts[ i ].GetConnection(); + ParentNode node = UIUtils.GetNode( connection.NodeId ); + + customLightingCode = node.GetValueFromOutputStr( connection.PortId, WirePortDataType.FLOAT3, ref m_currentDataCollector, false ); + customLightingInstructions = m_currentDataCollector.CustomOutput; + + if( m_currentDataCollector.ForceNormal ) + { + m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" ); + m_currentDataCollector.DirtyNormal = true; + m_currentDataCollector.ForceNormal = false; + } + + if( m_currentDataCollector.DirtyVertexVariables ) + { + m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, UniqueId, false ); + m_currentDataCollector.ClearVertexLocalVariables(); + } + + m_currentDataCollector.UsingCustomOutput = false; + + } + else if( sortedPorts[ i ].Name.Equals( AlphaStr ) && m_currentLightModel == StandardShaderLightModel.CustomLighting ) + { + m_currentDataCollector.UsingCustomOutput = true; + m_currentDataCollector.GenType = PortGenType.CustomLighting; + + WireReference connection = sortedPorts[ i ].GetConnection(); + ParentNode node = UIUtils.GetNode( connection.NodeId ); + + customLightingAlphaCode = node.GetValueFromOutputStr( connection.PortId, WirePortDataType.FLOAT, ref m_currentDataCollector, false ); + customLightingInstructions = m_currentDataCollector.CustomOutput; + + if( m_currentDataCollector.ForceNormal ) + { + m_currentDataCollector.AddToStartInstructions( "\t\t\t" + Constants.OutputVarStr + ".Normal = float3(0,0,1);\n" ); + m_currentDataCollector.DirtyNormal = true; + m_currentDataCollector.ForceNormal = false; + } + + if( m_currentDataCollector.DirtyVertexVariables ) + { + m_currentDataCollector.AddVertexInstruction( m_currentDataCollector.VertexLocalVariables, UniqueId, false ); + m_currentDataCollector.ClearVertexLocalVariables(); + } + + m_currentDataCollector.GenType = PortGenType.NonCustomLighting; + m_currentDataCollector.UsingCustomOutput = false; + } + else + { + // Surface shader instruccions + // if working on normals and have normal dependent node then ignore local var generation + CreateInstructionsForPort( sortedPorts[ i ], Constants.OutputVarStr + "." + sortedPorts[ i ].DataName, false, null, null, false, normalIsConnected ); + } + } + else if( sortedPorts[ i ].Name.Equals( AlphaStr ) ) + { + if( m_currentLightModel != StandardShaderLightModel.CustomLighting ) + { + m_currentDataCollector.AddInstructions( string.Format( "\t\t\t{0}.{1} = 1;\n", Constants.OutputVarStr, sortedPorts[ i ].DataName ) ); + } + } + } + + m_billboardOpHelper.FillDataCollectorWithInternalData( ref m_currentDataCollector ); + } + + + if( !m_renderingOptionsOpHelper.UseDefaultShadowCaster && + ( ( m_castShadows && ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) ) || + ( m_castShadows && hasOpacity ) || + ( m_castShadows && ( m_currentDataCollector.UsingWorldNormal || m_currentDataCollector.UsingWorldReflection || m_currentDataCollector.UsingViewDirection ) ) || + ( m_castShadows && m_inputPorts[ m_discardPortId ].Available && m_inputPorts[ m_discardPortId ].IsConnected && m_currentLightModel == StandardShaderLightModel.CustomLighting ) )) + m_customShadowCaster = true; + else + m_customShadowCaster = false; + + //m_customShadowCaster = true; + + for( int i = 0; i < 4; i++ ) + { + if( m_currentDataCollector.GetChannelUsage( i ) == TextureChannelUsage.Required ) + { + string channelName = UIUtils.GetChannelName( i ); + m_currentDataCollector.AddToProperties( -1, UIUtils.GetTex2DProperty( channelName, TexturePropertyValues.white ), -1 ); + } + } + + m_currentDataCollector.AddToProperties( -1, IOUtils.DefaultASEDirtyCheckProperty, 10000 ); + if( m_inputPorts[ m_discardPortId ].Available && m_inputPorts[ m_discardPortId ].IsConnected ) + { + if( m_inlineOpacityMaskClipValue.IsValid ) + { + RangedFloatNode fnode = UIUtils.GetNode( m_inlineOpacityMaskClipValue.NodeId ) as RangedFloatNode; + if( fnode != null ) + { + m_currentDataCollector.AddToProperties( fnode.UniqueId, fnode.GetPropertyValue(), fnode.OrderIndex ); + m_currentDataCollector.AddToUniforms( fnode.UniqueId, fnode.GetUniformValue() ); + } + else + { + IntNode inode = UIUtils.GetNode( m_inlineOpacityMaskClipValue.NodeId ) as IntNode; + m_currentDataCollector.AddToProperties( inode.UniqueId, inode.GetPropertyValue(), inode.OrderIndex ); + m_currentDataCollector.AddToUniforms( inode.UniqueId, inode.GetUniformValue() ); + } + } + else + { + m_currentDataCollector.AddToProperties( -1, string.Format( IOUtils.MaskClipValueProperty, OpacityMaskClipValueStr, m_opacityMaskClipValue ), ( m_maskClipReorder != null ) ? m_maskClipReorder.OrderIndex : -1 ); + m_currentDataCollector.AddToUniforms( -1, string.Format( IOUtils.MaskClipValueUniform, m_opacityMaskClipValue ) ); + } + } + + if( !m_currentDataCollector.DirtyInputs ) + m_currentDataCollector.AddToInput( UniqueId, "half filler", true ); + + if( m_currentLightModel == StandardShaderLightModel.BlinnPhong ) + m_currentDataCollector.AddToProperties( -1, "_SpecColor(\"Specular Color\",Color)=(1,1,1,1)", m_specColorReorder.OrderIndex ); + + //Tesselation + if( m_tessOpHelper.EnableTesselation ) + { + m_tessOpHelper.AddToDataCollector( ref m_currentDataCollector, m_tessellationReorder != null ? m_tessellationReorder.OrderIndex : -1 ); + if( !m_currentDataCollector.DirtyPerVertexData ) + { + m_currentDataCollector.OpenPerVertexHeader( false ); + } + } + + + if( m_outlineHelper.EnableOutline || ( m_currentDataCollector.UsingCustomOutlineColor || m_currentDataCollector.CustomOutlineSelectedAlpha > 0 || m_currentDataCollector.UsingCustomOutlineWidth ) ) + { + m_outlineHelper.AddToDataCollector( ref m_currentDataCollector ); + } + +#if !UNITY_2017_1_OR_NEWER + if( m_renderingOptionsOpHelper.LodCrossfade ) + { + m_currentDataCollector.AddToPragmas( UniqueId, "multi_compile _ LOD_FADE_CROSSFADE" ); + m_currentDataCollector.AddToStartInstructions( "\t\t\tUNITY_APPLY_DITHER_CROSSFADE(i);\n" ); + m_currentDataCollector.AddToInput( UniqueId, "UNITY_DITHER_CROSSFADE_COORDS", false ); + m_currentDataCollector.AddVertexInstruction( "UNITY_TRANSFER_DITHER_CROSSFADE( " + Constants.VertexShaderOutputStr + ", " + Constants.VertexShaderInputStr + ".vertex )", UniqueId, true ); + } +#endif + //m_additionalIncludes.AddToDataCollector( ref m_currentDataCollector ); + //m_additionalPragmas.AddToDataCollector( ref m_currentDataCollector ); + //m_additionalDefines.AddToDataCollector( ref m_currentDataCollector ); + m_additionalDirectives.AddAllToDataCollector( ref m_currentDataCollector ); + + //m_currentDataCollector.CloseInputs(); + m_currentDataCollector.CloseCustomInputs(); + m_currentDataCollector.CloseProperties(); + m_currentDataCollector.ClosePerVertexHeader(); + + //build Shader Body + string ShaderBody = string.Empty; + OpenShaderBody( ref ShaderBody, m_shaderName ); + { + //set properties + if( m_currentDataCollector.DirtyProperties ) + { + ShaderBody += m_currentDataCollector.BuildPropertiesString(); + } + //set subshader + OpenSubShaderBody( ref ShaderBody ); + { + + // Add extra depth pass + m_zBufferHelper.DrawExtraDepthPass( ref ShaderBody ); + + // Add optionalPasses + if( m_outlineHelper.EnableOutline || ( m_currentDataCollector.UsingCustomOutlineColor || m_currentDataCollector.CustomOutlineSelectedAlpha > 0 || m_currentDataCollector.UsingCustomOutlineWidth ) ) + { + if( !usingDebugPort ) + AddMultilineBody( ref ShaderBody, m_outlineHelper.OutlineFunctionBody( ref m_currentDataCollector, isInstancedShader, m_customShadowCaster, UIUtils.RemoveInvalidCharacters( ShaderName ), ( m_billboardOpHelper.IsBillboard && !usingDebugPort ? m_billboardOpHelper.GetInternalMultilineInstructions() : null ), ref m_tessOpHelper, ShaderModelTypeArr[ m_shaderModelIdx ], CurrentPrecisionType ) ); + } + + //Add SubShader tags + if( hasEmission ) + { + tags += " \"IsEmissive\" = \"true\" "; + } + + tags += m_customTagsHelper.GenerateCustomTags(); + + tags = "Tags{ " + tags + " }"; + m_usePass.BuildUsePassInfo( m_currentDataCollector, ref aboveUsePasses, ref bellowUsePasses, "\t\t" ); + if( !string.IsNullOrEmpty( aboveUsePasses ) ) + { + ShaderBody += aboveUsePasses; + } + + AddRenderTags( ref ShaderBody, tags ); + AddShaderLOD( ref ShaderBody, ShaderLOD ); + AddRenderState( ref ShaderBody, "Cull", m_inlineCullMode.GetValueOrProperty( m_cullMode.ToString() ) ); + m_customBlendAvailable = ( m_alphaMode == AlphaMode.Custom || m_alphaMode == AlphaMode.Opaque ); + if( ( m_zBufferHelper.IsActive && m_customBlendAvailable ) || m_outlineHelper.UsingZWrite || m_outlineHelper.UsingZTest ) + { + ShaderBody += m_zBufferHelper.CreateDepthInfo( m_outlineHelper.UsingZWrite, m_outlineHelper.UsingZTest ); + } + if( m_stencilBufferHelper.Active ) + { + ShaderBody += m_stencilBufferHelper.CreateStencilOp( this ); + } + + if( m_blendOpsHelper.Active ) + { + ShaderBody += m_blendOpsHelper.CreateBlendOps(); + } + + if( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) + { + ShaderBody += "\t\tAlphaToMask "+ m_inlineAlphaToCoverage.GetValueOrProperty( "On" )+"\n"; + } + + // Build Color Mask + m_colorMaskHelper.BuildColorMask( ref ShaderBody, m_customBlendAvailable ); + + //ShaderBody += "\t\tZWrite " + _zWriteMode + '\n'; + //ShaderBody += "\t\tZTest " + _zTestMode + '\n'; + + //Add GrabPass + if( m_currentDataCollector.DirtyGrabPass ) + { + ShaderBody += m_currentDataCollector.GrabPass; + } + + // build optional parameters + string OptionalParameters = string.Empty; + + // addword standard to custom lighting to accepts standard lighting models + string standardCustomLighting = string.Empty; + if( m_currentLightModel == StandardShaderLightModel.CustomLighting ) + standardCustomLighting = "Standard"; + + //add cg program + if( m_customShadowCaster ) + OpenCGInclude( ref ShaderBody ); + else + OpenCGProgram( ref ShaderBody ); + { + //Add Defines + if( m_currentDataCollector.DirtyDefines ) + ShaderBody += m_currentDataCollector.Defines; + + //Add Includes + if( m_customShadowCaster ) + { + m_currentDataCollector.AddToIncludes( UniqueId, Constants.UnityPBSLightingLib ); + m_currentDataCollector.AddToIncludes( UniqueId, "Lighting.cginc" ); + } + if( m_currentDataCollector.DirtyIncludes ) + ShaderBody += m_currentDataCollector.Includes; + + //define as surface shader and specify lighting model + if( UIUtils.GetTextureArrayNodeAmount() > 0 && m_shaderModelIdx < 3 ) + { + UIUtils.ShowMessage( "Automatically changing Shader Model to 3.5 since\nit's the minimum required by texture arrays." ); + m_shaderModelIdx = 3; + } + + // if tessellation is active then we need be at least using shader model 4.6 + if( m_tessOpHelper.EnableTesselation && m_shaderModelIdx < 6 ) + { + UIUtils.ShowMessage( "Automatically changing Shader Model to 4.6 since\nit's the minimum required by tessellation." ); + m_shaderModelIdx = 6; + } + + // if translucency is ON change render path + if( hasTranslucency && m_renderPath != RenderPath.ForwardOnly ) + { + UIUtils.ShowMessage( "Automatically changing Render Path to Forward Only since\ntranslucency only works in forward rendering." ); + m_renderPath = RenderPath.ForwardOnly; + } + + // if outline is ON change render path + if( m_outlineHelper.EnableOutline && m_renderPath != RenderPath.ForwardOnly ) + { + UIUtils.ShowMessage( "Automatically changing Render Path to Forward Only since\noutline only works in forward rendering." ); + m_renderPath = RenderPath.ForwardOnly; + } + + // if transmission is ON change render path + if( hasTransmission && m_renderPath != RenderPath.ForwardOnly ) + { + UIUtils.ShowMessage( "Automatically changing Render Path to Forward Only since\ntransmission only works in forward rendering." ); + m_renderPath = RenderPath.ForwardOnly; + } + + // if refraction is ON change render path + if( hasRefraction && m_renderPath != RenderPath.ForwardOnly ) + { + UIUtils.ShowMessage( "Automatically changing Render Path to Forward Only since\nrefraction only works in forward rendering." ); + m_renderPath = RenderPath.ForwardOnly; + } + + ShaderBody += string.Format( IOUtils.PragmaTargetHeader, ShaderModelTypeArr[ m_shaderModelIdx ] ); + + + //Add pragmas (needs check to see if all pragmas work with custom shadow caster) + if( m_currentDataCollector.DirtyPragmas/* && !m_customShadowCaster */) + ShaderBody += m_currentDataCollector.Pragmas; + + if( m_currentDataCollector.DirtyAdditionalDirectives ) + ShaderBody += m_currentDataCollector.StandardAdditionalDirectives; + + //if ( !m_customBlendMode ) + { + switch( m_alphaMode ) + { + case AlphaMode.Opaque: + case AlphaMode.Masked: break; + case AlphaMode.Transparent: + { + OptionalParameters += "alpha:fade" + Constants.OptionalParametersSep; + } + break; + case AlphaMode.Premultiply: + { + OptionalParameters += "alpha:premul" + Constants.OptionalParametersSep; + } + break; + } + } + + if( m_keepAlpha ) + { + OptionalParameters += "keepalpha" + Constants.OptionalParametersSep; + } + + if( hasRefraction ) + { + OptionalParameters += "finalcolor:RefractionF" + Constants.OptionalParametersSep; + } + + if( !m_customShadowCaster && m_castShadows ) + { + OptionalParameters += "addshadow" + Constants.OptionalParametersSep; + } + + if( m_castShadows ) + { + OptionalParameters += "fullforwardshadows" + Constants.OptionalParametersSep; + } + + if( !m_receiveShadows ) + { + OptionalParameters += "noshadow" + Constants.OptionalParametersSep; + } + + if( m_renderingOptionsOpHelper.IsOptionActive( " Add Pass" ) && usingDebugPort ) + { + OptionalParameters += "noforwardadd" + Constants.OptionalParametersSep; + } + + if( m_renderingOptionsOpHelper.ForceDisableInstancing ) + { + OptionalParameters += "noinstancing" + Constants.OptionalParametersSep; + } + + switch( m_renderPath ) + { + case RenderPath.All: break; + case RenderPath.DeferredOnly: OptionalParameters += "exclude_path:forward" + Constants.OptionalParametersSep; break; + case RenderPath.ForwardOnly: OptionalParameters += "exclude_path:deferred" + Constants.OptionalParametersSep; break; + } + + //Add code generation options + m_renderingOptionsOpHelper.Build( ref OptionalParameters ); + + if( !m_customShadowCaster ) + { + string customLightSurface = string.Empty; + if( hasTranslucency || hasTransmission ) + customLightSurface = "Custom"; + m_renderingPlatformOpHelper.SetRenderingPlatforms( ref ShaderBody ); + + //Check if Custom Vertex is being used and add tag + if( m_currentDataCollector.DirtyPerVertexData ) + OptionalParameters += "vertex:" + Constants.VertexDataFunc + Constants.OptionalParametersSep; + + if( m_tessOpHelper.EnableTesselation && !usingDebugPort ) + { + m_tessOpHelper.WriteToOptionalParams( ref OptionalParameters ); + } + + m_additionalSurfaceOptions.WriteToOptionalSurfaceOptions( ref OptionalParameters ); + + AddShaderPragma( ref ShaderBody, "surface surf " + standardCustomLighting + m_currentLightModel.ToString() + customLightSurface + Constants.OptionalParametersSep + OptionalParameters ); + } + else + { + if( /*m_currentDataCollector.UsingWorldNormal ||*/ m_currentDataCollector.UsingInternalData ) + { + ShaderBody += "\t\t#ifdef UNITY_PASS_SHADOWCASTER\n"; + ShaderBody += "\t\t\t#undef INTERNAL_DATA\n"; + ShaderBody += "\t\t\t#undef WorldReflectionVector\n"; + ShaderBody += "\t\t\t#undef WorldNormalVector\n"; + ShaderBody += "\t\t\t#define INTERNAL_DATA half3 internalSurfaceTtoW0; half3 internalSurfaceTtoW1; half3 internalSurfaceTtoW2;\n"; + ShaderBody += "\t\t\t#define WorldReflectionVector(data,normal) reflect (data.worldRefl, half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal)))\n"; + ShaderBody += "\t\t\t#define WorldNormalVector(data,normal) half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal))\n"; + ShaderBody += "\t\t#endif\n"; + } + } + + if( m_currentDataCollector.UsingHigherSizeTexcoords ) + { + ShaderBody += "\t\t#undef TRANSFORM_TEX\n"; + ShaderBody += "\t\t#define TRANSFORM_TEX(tex,name) float4(tex.xy * name##_ST.xy + name##_ST.zw, tex.z, tex.w)\n"; + } + + if( m_currentDataCollector.DirtyAppData ) + ShaderBody += m_currentDataCollector.CustomAppData; + + // Add Input struct + if( m_currentDataCollector.DirtyInputs ) + ShaderBody += "\t\t" + m_currentDataCollector.Inputs + "\t\t};" + "\n\n"; + + // Add Custom Lighting struct + if( m_currentDataCollector.DirtyCustomInput ) + ShaderBody += m_currentDataCollector.CustomInput + "\n\n"; + + //Add Uniforms + if( m_currentDataCollector.DirtyUniforms ) + ShaderBody += m_currentDataCollector.Uniforms + "\n"; + + // Add Array Derivatives Macros + //if( m_currentDataCollector.UsingArrayDerivatives ) + //{ + // ShaderBody += "\t\t#if defined(UNITY_COMPILER_HLSL2GLSL) || defined(SHADER_TARGET_SURFACE_ANALYSIS)\n"; + // ShaderBody += "\t\t\t#define ASE_SAMPLE_TEX2DARRAY_GRAD(tex,coord,dx,dy) UNITY_SAMPLE_TEX2DARRAY (tex,coord)\n"; + // ShaderBody += "\t\t#else\n"; + // ShaderBody += "\t\t\t#define ASE_SAMPLE_TEX2DARRAY_GRAD(tex,coord,dx,dy) tex.SampleGrad (sampler##tex,coord,dx,dy)\n"; + // ShaderBody += "\t\t#endif\n\n"; + //} + + //Add Instanced Properties + if( isInstancedShader && m_currentDataCollector.DirtyInstancedProperties ) + { + m_currentDataCollector.SetupInstancePropertiesBlock( UIUtils.RemoveInvalidCharacters( ShaderName ) ); + ShaderBody += m_currentDataCollector.InstancedProperties + "\n"; + } + + if( m_currentDataCollector.DirtyFunctions ) + ShaderBody += m_currentDataCollector.Functions + "\n"; + + + //Tesselation + if( m_tessOpHelper.EnableTesselation && !usingDebugPort ) + { + ShaderBody += m_tessOpHelper.GetCurrentTessellationFunction + "\n"; + } + + //Add Custom Vertex Data + if( m_currentDataCollector.DirtyPerVertexData ) + { + ShaderBody += m_currentDataCollector.VertexData; + } + + if( m_currentLightModel == StandardShaderLightModel.Unlit ) + { + for( int i = 0; i < VertexLitFunc.Length; i++ ) + { + ShaderBody += VertexLitFunc[ i ] + "\n"; + } + } + + //Add custom lighting + if( m_currentLightModel == StandardShaderLightModel.CustomLighting ) + { + ShaderBody += "\t\tinline half4 LightingStandard" + m_currentLightModel.ToString() + "( inout " + outputStruct + " " + Constants.CustomLightOutputVarStr + ", half3 viewDir, UnityGI gi )\n\t\t{\n"; + ShaderBody += "\t\t\tUnityGIInput data = s.GIData;\n"; + ShaderBody += "\t\t\tInput i = s.SurfInput;\n"; + ShaderBody += "\t\t\thalf4 c = 0;\n"; + if( m_currentDataCollector.UsingLightAttenuation ) + { + ShaderBody += "\t\t\t#ifdef UNITY_PASS_FORWARDBASE\n"; + ShaderBody += "\t\t\tfloat ase_lightAtten = data.atten;\n"; + ShaderBody += "\t\t\tif( _LightColor0.a == 0)\n"; + ShaderBody += "\t\t\tase_lightAtten = 0;\n"; + ShaderBody += "\t\t\t#else\n"; + ShaderBody += "\t\t\tfloat3 ase_lightAttenRGB = gi.light.color / ( ( _LightColor0.rgb ) + 0.000001 );\n"; + ShaderBody += "\t\t\tfloat ase_lightAtten = max( max( ase_lightAttenRGB.r, ase_lightAttenRGB.g ), ase_lightAttenRGB.b );\n"; + ShaderBody += "\t\t\t#endif\n"; + + ShaderBody += "\t\t\t#if defined(HANDLE_SHADOWS_BLENDING_IN_GI)\n"; + ShaderBody += "\t\t\thalf bakedAtten = UnitySampleBakedOcclusion(data.lightmapUV.xy, data.worldPos);\n"; + ShaderBody += "\t\t\tfloat zDist = dot(_WorldSpaceCameraPos - data.worldPos, UNITY_MATRIX_V[2].xyz);\n"; + ShaderBody += "\t\t\tfloat fadeDist = UnityComputeShadowFadeDistance(data.worldPos, zDist);\n"; + ShaderBody += "\t\t\tase_lightAtten = UnityMixRealtimeAndBakedShadows(data.atten, bakedAtten, UnityComputeShadowFade(fadeDist));\n"; + ShaderBody += "\t\t\t#endif\n"; + } + + //if( m_currentDataCollector.dirtyc ) + ShaderBody += customLightingInstructions; + ShaderBody += "\t\t\tc.rgb = " + ( !string.IsNullOrEmpty( customLightingCode ) ? customLightingCode : "0" ) + ";\n"; + ShaderBody += "\t\t\tc.a = " + ( !string.IsNullOrEmpty( customLightingAlphaCode ) ? customLightingAlphaCode : "1" ) + ";\n"; + if( m_alphaMode == AlphaMode.Premultiply || ( ( m_alphaMode == AlphaMode.Custom || m_alphaMode == AlphaMode.Opaque ) && m_blendOpsHelper.CurrentBlendRGB.IndexOf( "Premultiplied" ) > -1 ) ) + ShaderBody += "\t\t\tc.rgb *= c.a;\n"; + if( hasCustomLightingMask ) + ShaderBody += "\t\t\t" + customLightingMaskCode + ";\n"; + ShaderBody += "\t\t\treturn c;\n"; + ShaderBody += "\t\t}\n\n"; + + //Add GI function + ShaderBody += "\t\tinline void LightingStandard" + m_currentLightModel.ToString() + "_GI( inout " + outputStruct + " " + Constants.CustomLightOutputVarStr + ", UnityGIInput data, inout UnityGI gi )\n\t\t{\n"; + ShaderBody += "\t\t\ts.GIData = data;\n"; + //ShaderBody += "\t\t\tUNITY_GI(gi, " + Constants.CustomLightOutputVarStr + ", data);\n"; + ShaderBody += "\t\t}\n\n"; + } + + //Add custom lighting function + if( hasTranslucency || hasTransmission ) + { + ShaderBody += "\t\tinline half4 Lighting" + m_currentLightModel.ToString() + Constants.CustomLightStructStr + "(" + outputStruct + " " + Constants.CustomLightOutputVarStr + ", half3 viewDir, UnityGI gi )\n\t\t{\n"; + if( hasTranslucency ) + { + ShaderBody += "\t\t\t#if !DIRECTIONAL\n"; + ShaderBody += "\t\t\tfloat3 lightAtten = gi.light.color;\n"; + ShaderBody += "\t\t\t#else\n"; + ShaderBody += "\t\t\tfloat3 lightAtten = lerp( _LightColor0.rgb, gi.light.color, _TransShadow );\n"; + ShaderBody += "\t\t\t#endif\n"; + ShaderBody += "\t\t\thalf3 lightDir = gi.light.dir + " + Constants.CustomLightOutputVarStr + ".Normal * _TransNormalDistortion;\n"; + ShaderBody += "\t\t\thalf transVdotL = pow( saturate( dot( viewDir, -lightDir ) ), _TransScattering );\n"; + ShaderBody += "\t\t\thalf3 translucency = lightAtten * (transVdotL * _TransDirect + gi.indirect.diffuse * _TransAmbient) * " + Constants.CustomLightOutputVarStr + ".Translucency;\n"; + ShaderBody += "\t\t\thalf4 c = half4( " + Constants.CustomLightOutputVarStr + ".Albedo * translucency * _Translucency, 0 );\n\n"; + } + + if( hasTransmission ) + { + ShaderBody += "\t\t\thalf3 transmission = max(0 , -dot(" + Constants.CustomLightOutputVarStr + ".Normal, gi.light.dir)) * gi.light.color * " + Constants.CustomLightOutputVarStr + ".Transmission;\n"; + ShaderBody += "\t\t\thalf4 d = half4(" + Constants.CustomLightOutputVarStr + ".Albedo * transmission , 0);\n\n"; + } + + ShaderBody += "\t\t\tSurfaceOutput" + m_currentLightModel.ToString() + " r;\n"; + ShaderBody += "\t\t\tr.Albedo = " + Constants.CustomLightOutputVarStr + ".Albedo;\n"; + ShaderBody += "\t\t\tr.Normal = " + Constants.CustomLightOutputVarStr + ".Normal;\n"; + ShaderBody += "\t\t\tr.Emission = " + Constants.CustomLightOutputVarStr + ".Emission;\n"; + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + ShaderBody += "\t\t\tr.Metallic = " + Constants.CustomLightOutputVarStr + ".Metallic;\n"; + break; + case StandardShaderLightModel.StandardSpecular: + ShaderBody += "\t\t\tr.Specular = " + Constants.CustomLightOutputVarStr + ".Specular;\n"; + break; + } + ShaderBody += "\t\t\tr.Smoothness = " + Constants.CustomLightOutputVarStr + ".Smoothness;\n"; + ShaderBody += "\t\t\tr.Occlusion = " + Constants.CustomLightOutputVarStr + ".Occlusion;\n"; + ShaderBody += "\t\t\tr.Alpha = " + Constants.CustomLightOutputVarStr + ".Alpha;\n"; + ShaderBody += "\t\t\treturn Lighting" + m_currentLightModel.ToString() + " (r, viewDir, gi)" + ( hasTranslucency ? " + c" : "" ) + ( hasTransmission ? " + d" : "" ) + ";\n"; + ShaderBody += "\t\t}\n\n"; + + //Add GI function + ShaderBody += "\t\tinline void Lighting" + m_currentLightModel.ToString() + Constants.CustomLightStructStr + "_GI(" + outputStruct + " " + Constants.CustomLightOutputVarStr + ", UnityGIInput data, inout UnityGI gi )\n\t\t{\n"; + + ShaderBody += "\t\t\t#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS\n"; + ShaderBody += "\t\t\t\tgi = UnityGlobalIllumination(data, " + Constants.CustomLightOutputVarStr + ".Occlusion, " + Constants.CustomLightOutputVarStr + ".Normal);\n"; + ShaderBody += "\t\t\t#else\n"; + ShaderBody += "\t\t\t\tUNITY_GLOSSY_ENV_FROM_SURFACE( g, " + Constants.CustomLightOutputVarStr + ", data );\n"; + ShaderBody += "\t\t\t\tgi = UnityGlobalIllumination( data, " + Constants.CustomLightOutputVarStr + ".Occlusion, " + Constants.CustomLightOutputVarStr + ".Normal, g );\n"; + ShaderBody += "\t\t\t#endif\n"; + + //ShaderBody += "\t\t\tUNITY_GI(gi, " + Constants.CustomLightOutputVarStr + ", data);\n"; + ShaderBody += "\t\t}\n\n"; + } + + if( hasRefraction ) + { + ShaderBody += "\t\tinline float4 Refraction( Input " + Constants.InputVarStr + ", " + outputStruct + " " + Constants.OutputVarStr + ", float indexOfRefraction, float chomaticAberration ) {\n"; + ShaderBody += "\t\t\tfloat3 worldNormal = " + Constants.OutputVarStr + ".Normal;\n"; + ShaderBody += "\t\t\tfloat4 screenPos = " + Constants.InputVarStr + ".screenPos;\n"; + ShaderBody += "\t\t\t#if UNITY_UV_STARTS_AT_TOP\n"; + ShaderBody += "\t\t\t\tfloat scale = -1.0;\n"; + ShaderBody += "\t\t\t#else\n"; + ShaderBody += "\t\t\t\tfloat scale = 1.0;\n"; + ShaderBody += "\t\t\t#endif\n"; + ShaderBody += "\t\t\tfloat halfPosW = screenPos.w * 0.5;\n"; + ShaderBody += "\t\t\tscreenPos.y = ( screenPos.y - halfPosW ) * _ProjectionParams.x * scale + halfPosW;\n"; + ShaderBody += "\t\t\t#if SHADER_API_D3D9 || SHADER_API_D3D11\n"; + ShaderBody += "\t\t\t\tscreenPos.w += 0.00000000001;\n"; + ShaderBody += "\t\t\t#endif\n"; + ShaderBody += "\t\t\tfloat2 projScreenPos = ( screenPos / screenPos.w ).xy;\n"; + ShaderBody += "\t\t\tfloat3 worldViewDir = normalize( UnityWorldSpaceViewDir( " + Constants.InputVarStr + ".worldPos ) );\n"; + ShaderBody += "\t\t\tfloat3 refractionOffset = ( indexOfRefraction - 1.0 ) * mul( UNITY_MATRIX_V, float4( worldNormal, 0.0 ) ) * ( 1.0 - dot( worldNormal, worldViewDir ) );\n"; + ShaderBody += "\t\t\tfloat2 cameraRefraction = float2( refractionOffset.x, refractionOffset.y );\n"; + + string grabpass = "_GrabTexture"; + if( m_grabOrder != 0 ) + grabpass = "RefractionGrab" + m_grabOrder; + ShaderBody += "\t\t\tfloat4 redAlpha = tex2D( " + grabpass + ", ( projScreenPos + cameraRefraction ) );\n"; + ShaderBody += "\t\t\tfloat green = tex2D( " + grabpass + ", ( projScreenPos + ( cameraRefraction * ( 1.0 - chomaticAberration ) ) ) ).g;\n"; + ShaderBody += "\t\t\tfloat blue = tex2D( " + grabpass + ", ( projScreenPos + ( cameraRefraction * ( 1.0 + chomaticAberration ) ) ) ).b;\n"; + ShaderBody += "\t\t\treturn float4( redAlpha.r, green, blue, redAlpha.a );\n"; + ShaderBody += "\t\t}\n\n"; + + ShaderBody += "\t\tvoid RefractionF( Input " + Constants.InputVarStr + ", " + outputStruct + " " + Constants.OutputVarStr + ", inout half4 color )\n"; + ShaderBody += "\t\t{\n"; + ShaderBody += "\t\t\t#ifdef UNITY_PASS_FORWARDBASE\n"; + ShaderBody += refractionInstructions; + if( m_inlineChromaticAberration.Active ) + { + ShaderBody += "\t\t\tcolor.rgb = color.rgb + Refraction( " + Constants.InputVarStr + ", " + Constants.OutputVarStr + ", " + refractionCode + ", " + m_inlineChromaticAberration.GetValueOrProperty(false) + " ) * ( 1 - color.a );\n"; + } + else + { + ShaderBody += "\t\t\tcolor.rgb = color.rgb + Refraction( " + Constants.InputVarStr + ", " + Constants.OutputVarStr + ", " + refractionCode + ", _ChromaticAberration ) * ( 1 - color.a );\n"; + } + ShaderBody += "\t\t\tcolor.a = 1;\n"; + ShaderBody += "\t\t\t#endif\n"; + ShaderBody += "\t\t}\n\n"; + } + + //Add Surface Shader body + ShaderBody += "\t\tvoid surf( Input " + Constants.InputVarStr + " , inout " + outputStruct + " " + Constants.OutputVarStr + " )\n\t\t{\n"; + { + // Pass input information to custom lighting function + if( m_currentLightModel == StandardShaderLightModel.CustomLighting ) + ShaderBody += "\t\t\t" + Constants.OutputVarStr + ".SurfInput = " + Constants.InputVarStr + ";\n"; + + //add local vars + if( m_currentDataCollector.DirtyLocalVariables ) + ShaderBody += m_currentDataCollector.LocalVariables; + + //add nodes ops + if( m_currentDataCollector.DirtyInstructions ) + ShaderBody += m_currentDataCollector.Instructions; + } + ShaderBody += "\t\t}\n"; + } + CloseCGProgram( ref ShaderBody ); + + + //Add custom Shadow Caster + if( m_customShadowCaster ) + { + OpenCGProgram( ref ShaderBody ); + string customLightSurface = hasTranslucency || hasTransmission ? "Custom" : ""; + m_renderingPlatformOpHelper.SetRenderingPlatforms( ref ShaderBody ); + + //Check if Custom Vertex is being used and add tag + if( m_currentDataCollector.DirtyPerVertexData ) + OptionalParameters += "vertex:" + Constants.VertexDataFunc + Constants.OptionalParametersSep; + + if( m_tessOpHelper.EnableTesselation && !usingDebugPort ) + { + m_tessOpHelper.WriteToOptionalParams( ref OptionalParameters ); + } + //if ( hasRefraction ) + // ShaderBody += "\t\t#pragma multi_compile _ALPHAPREMULTIPLY_ON\n"; + + m_additionalSurfaceOptions.WriteToOptionalSurfaceOptions( ref OptionalParameters ); + + AddShaderPragma( ref ShaderBody, "surface surf " + standardCustomLighting + m_currentLightModel.ToString() + customLightSurface + Constants.OptionalParametersSep + OptionalParameters ); + CloseCGProgram( ref ShaderBody ); + + ShaderBody += "\t\tPass\n"; + ShaderBody += "\t\t{\n"; + ShaderBody += "\t\t\tName \"ShadowCaster\"\n"; + ShaderBody += "\t\t\tTags{ \"LightMode\" = \"ShadowCaster\" }\n"; + ShaderBody += "\t\t\tZWrite On\n"; + if( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) + ShaderBody += "\t\t\tAlphaToMask Off\n"; + ShaderBody += "\t\t\tCGPROGRAM\n"; + ShaderBody += "\t\t\t#pragma vertex vert\n"; + ShaderBody += "\t\t\t#pragma fragment frag\n"; + ShaderBody += "\t\t\t#pragma target " + ShaderModelTypeArr[ m_shaderModelIdx ] + "\n"; + //ShaderBody += "\t\t\t#pragma multi_compile_instancing\n"; + ShaderBody += "\t\t\t#pragma multi_compile_shadowcaster\n"; + ShaderBody += "\t\t\t#pragma multi_compile UNITY_PASS_SHADOWCASTER\n"; + ShaderBody += "\t\t\t#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2\n"; + ShaderBody += "\t\t\t#include \"HLSLSupport.cginc\"\n"; +#if UNITY_2018_3_OR_NEWER + //Preventing WebGL to throw error Duplicate system value semantic definition: input semantic 'SV_POSITION' and input semantic 'VPOS' + ShaderBody += "\t\t\t#if ( SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN )\n"; +#else + ShaderBody += "\t\t\t#if ( SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN )\n"; +#endif + ShaderBody += "\t\t\t\t#define CAN_SKIP_VPOS\n"; + ShaderBody += "\t\t\t#endif\n"; + ShaderBody += "\t\t\t#include \"UnityCG.cginc\"\n"; + ShaderBody += "\t\t\t#include \"Lighting.cginc\"\n"; + ShaderBody += "\t\t\t#include \"UnityPBSLighting.cginc\"\n"; + + if( !( ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) && hasOpacity && hasOpacityMask ) ) + if( hasOpacity ) + ShaderBody += "\t\t\tsampler3D _DitherMaskLOD;\n"; + + //ShaderBody += "\t\t\tsampler3D _DitherMaskLOD;\n"; + + ShaderBody += "\t\t\tstruct v2f\n"; + ShaderBody += "\t\t\t{\n"; + ShaderBody += "\t\t\t\tV2F_SHADOW_CASTER;\n"; + int texcoordIndex = 1; + for( int i = 0; i < m_currentDataCollector.PackSlotsList.Count; i++ ) + { + int size = 4 - m_currentDataCollector.PackSlotsList[ i ]; + if( size > 0 ) + { + ShaderBody += "\t\t\t\tfloat" + size + " customPack" + ( i + 1 ) + " : TEXCOORD" + ( i + 1 ) + ";\n"; + } + texcoordIndex++; + } + + if( !m_currentDataCollector.UsingInternalData ) + ShaderBody += "\t\t\t\tfloat3 worldPos : TEXCOORD" + ( texcoordIndex++ ) + ";\n"; + if( m_currentDataCollector.UsingScreenPos ) + ShaderBody += "\t\t\t\tfloat4 screenPos : TEXCOORD" + ( texcoordIndex++ ) + ";\n"; + if( /*m_currentDataCollector.UsingWorldNormal || m_currentDataCollector.UsingWorldPosition ||*/ m_currentDataCollector.UsingInternalData || m_currentDataCollector.DirtyNormal ) + { + ShaderBody += "\t\t\t\tfloat4 tSpace0 : TEXCOORD" + ( texcoordIndex++ ) + ";\n"; + ShaderBody += "\t\t\t\tfloat4 tSpace1 : TEXCOORD" + ( texcoordIndex++ ) + ";\n"; + ShaderBody += "\t\t\t\tfloat4 tSpace2 : TEXCOORD" + ( texcoordIndex++ ) + ";\n"; + } + else if( !m_currentDataCollector.UsingInternalData && m_currentDataCollector.UsingWorldNormal ) + { + ShaderBody += "\t\t\t\tfloat3 worldNormal : TEXCOORD" + ( texcoordIndex++ ) + ";\n"; + } + + if( m_currentDataCollector.UsingVertexColor ) + ShaderBody += "\t\t\t\thalf4 color : COLOR0;\n"; + ShaderBody += "\t\t\t\tUNITY_VERTEX_INPUT_INSTANCE_ID\n"; + ShaderBody += "\t\t\t\tUNITY_VERTEX_OUTPUT_STEREO\n"; + ShaderBody += "\t\t\t};\n"; + + ShaderBody += "\t\t\tv2f vert( " + m_currentDataCollector.CustomAppDataName + " v )\n"; + ShaderBody += "\t\t\t{\n"; + ShaderBody += "\t\t\t\tv2f o;\n"; + + ShaderBody += "\t\t\t\tUNITY_SETUP_INSTANCE_ID( v );\n"; + ShaderBody += "\t\t\t\tUNITY_INITIALIZE_OUTPUT( v2f, o );\n"; + ShaderBody += "\t\t\t\tUNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( o );\n"; + ShaderBody += "\t\t\t\tUNITY_TRANSFER_INSTANCE_ID( v, o );\n"; + + if( m_currentDataCollector.DirtyPerVertexData || m_currentDataCollector.CustomShadowCoordsList.Count > 0 ) + ShaderBody += "\t\t\t\tInput customInputData;\n"; + if( m_currentDataCollector.DirtyPerVertexData ) + { + ShaderBody += "\t\t\t\tvertexDataFunc( v" + ( m_currentDataCollector.TesselationActive ? "" : ", customInputData" ) + " );\n"; + } + + ShaderBody += "\t\t\t\tfloat3 worldPos = mul( unity_ObjectToWorld, v.vertex ).xyz;\n"; + ShaderBody += "\t\t\t\thalf3 worldNormal = UnityObjectToWorldNormal( v.normal );\n"; + if( m_currentDataCollector.UsingInternalData || m_currentDataCollector.DirtyNormal ) + { + ShaderBody += "\t\t\t\thalf3 worldTangent = UnityObjectToWorldDir( v.tangent.xyz );\n"; + ShaderBody += "\t\t\t\thalf tangentSign = v.tangent.w * unity_WorldTransformParams.w;\n"; + ShaderBody += "\t\t\t\thalf3 worldBinormal = cross( worldNormal, worldTangent ) * tangentSign;\n"; + ShaderBody += "\t\t\t\to.tSpace0 = float4( worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x );\n"; + ShaderBody += "\t\t\t\to.tSpace1 = float4( worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y );\n"; + ShaderBody += "\t\t\t\to.tSpace2 = float4( worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z );\n"; + } + else if( !m_currentDataCollector.UsingInternalData && m_currentDataCollector.UsingWorldNormal ) + { + ShaderBody += "\t\t\t\to.worldNormal = worldNormal;\n"; + } + + for( int i = 0; i < m_currentDataCollector.CustomShadowCoordsList.Count; i++ ) + { + int size = UIUtils.GetChannelsAmount( m_currentDataCollector.CustomShadowCoordsList[ i ].DataType ); + string channels = string.Empty; + for( int j = 0; j < size; j++ ) + { + channels += Convert.ToChar( 120 + m_currentDataCollector.CustomShadowCoordsList[ i ].TextureIndex + j ); + } + channels = channels.Replace( '{', 'w' ); + ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = customInputData." + m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName + ";\n"; + + //TODO: TEMPORARY SOLUTION, this needs to go somewhere else, there's no need for these comparisons + if( m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName.StartsWith( "uv_" ) ) + { + ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = v.texcoord;\n"; + } + else if( m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName.StartsWith( "uv2_" ) ) + { + ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = v.texcoord1;\n"; + } + else if( m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName.StartsWith( "uv3_" ) ) + { + ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = v.texcoord2;\n"; + } + else if( m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName.StartsWith( "uv4_" ) ) + { + ShaderBody += "\t\t\t\to.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + " = v.texcoord3;\n"; + } + } + + if( !m_currentDataCollector.UsingInternalData ) + ShaderBody += "\t\t\t\to.worldPos = worldPos;\n"; + ShaderBody += "\t\t\t\tTRANSFER_SHADOW_CASTER_NORMALOFFSET( o )\n"; + if( m_currentDataCollector.UsingScreenPos ) + ShaderBody += "\t\t\t\to.screenPos = ComputeScreenPos( o.pos );\n"; + if( m_currentDataCollector.UsingVertexColor ) + ShaderBody += "\t\t\t\to.color = v.color;\n"; + ShaderBody += "\t\t\t\treturn o;\n"; + ShaderBody += "\t\t\t}\n"; + + ShaderBody += "\t\t\thalf4 frag( v2f IN\n"; + ShaderBody += "\t\t\t#if !defined( CAN_SKIP_VPOS )\n"; + ShaderBody += "\t\t\t, UNITY_VPOS_TYPE vpos : VPOS\n"; + ShaderBody += "\t\t\t#endif\n"; + ShaderBody += "\t\t\t) : SV_Target\n"; + ShaderBody += "\t\t\t{\n"; + ShaderBody += "\t\t\t\tUNITY_SETUP_INSTANCE_ID( IN );\n"; + ShaderBody += "\t\t\t\tInput surfIN;\n"; + ShaderBody += "\t\t\t\tUNITY_INITIALIZE_OUTPUT( Input, surfIN );\n"; + + for( int i = 0; i < m_currentDataCollector.CustomShadowCoordsList.Count; i++ ) + { + int size = UIUtils.GetChannelsAmount( m_currentDataCollector.CustomShadowCoordsList[ i ].DataType ); + string channels = string.Empty; + for( int j = 0; j < size; j++ ) + { + channels += Convert.ToChar( 120 + m_currentDataCollector.CustomShadowCoordsList[ i ].TextureIndex + j ); + } + channels = channels.Replace( '{', 'w' ); + ShaderBody += "\t\t\t\tsurfIN." + m_currentDataCollector.CustomShadowCoordsList[ i ].CoordName + " = IN.customPack" + ( m_currentDataCollector.CustomShadowCoordsList[ i ].TextureSlot + 1 ) + "." + channels + ";\n"; + } + + if( m_currentDataCollector.UsingInternalData ) + ShaderBody += "\t\t\t\tfloat3 worldPos = float3( IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w );\n"; + else + ShaderBody += "\t\t\t\tfloat3 worldPos = IN.worldPos;\n"; + ShaderBody += "\t\t\t\thalf3 worldViewDir = normalize( UnityWorldSpaceViewDir( worldPos ) );\n"; + + if( m_currentDataCollector.UsingViewDirection && !m_currentDataCollector.DirtyNormal ) + ShaderBody += "\t\t\t\tsurfIN.viewDir = worldViewDir;\n"; + else if( m_currentDataCollector.UsingViewDirection ) + ShaderBody += "\t\t\t\tsurfIN.viewDir = IN.tSpace0.xyz * worldViewDir.x + IN.tSpace1.xyz * worldViewDir.y + IN.tSpace2.xyz * worldViewDir.z;\n"; + + if( m_currentDataCollector.UsingWorldPosition ) + ShaderBody += "\t\t\t\tsurfIN.worldPos = worldPos;\n"; + + if( m_currentDataCollector.UsingWorldNormal && m_currentDataCollector.UsingInternalData ) + ShaderBody += "\t\t\t\tsurfIN.worldNormal = float3( IN.tSpace0.z, IN.tSpace1.z, IN.tSpace2.z );\n"; + else if( !m_currentDataCollector.UsingInternalData && m_currentDataCollector.UsingWorldNormal ) + ShaderBody += "\t\t\t\tsurfIN.worldNormal = IN.worldNormal;\n"; + + if( m_currentDataCollector.UsingWorldReflection ) + ShaderBody += "\t\t\t\tsurfIN.worldRefl = -worldViewDir;\n"; + + if( m_currentDataCollector.UsingInternalData ) + { + ShaderBody += "\t\t\t\tsurfIN.internalSurfaceTtoW0 = IN.tSpace0.xyz;\n"; + ShaderBody += "\t\t\t\tsurfIN.internalSurfaceTtoW1 = IN.tSpace1.xyz;\n"; + ShaderBody += "\t\t\t\tsurfIN.internalSurfaceTtoW2 = IN.tSpace2.xyz;\n"; + } + + if( m_currentDataCollector.UsingScreenPos ) + ShaderBody += "\t\t\t\tsurfIN.screenPos = IN.screenPos;\n"; + + if( m_currentDataCollector.UsingVertexColor ) + ShaderBody += "\t\t\t\tsurfIN.vertexColor = IN.color;\n"; + + ShaderBody += "\t\t\t\t" + outputStruct + " o;\n"; + ShaderBody += "\t\t\t\tUNITY_INITIALIZE_OUTPUT( " + outputStruct + ", o )\n"; + ShaderBody += "\t\t\t\tsurf( surfIN, o );\n"; + if( ( hasOpacity || hasOpacityMask ) && m_currentLightModel == StandardShaderLightModel.CustomLighting ) + { + ShaderBody += "\t\t\t\tUnityGI gi;\n"; + ShaderBody += "\t\t\t\tUNITY_INITIALIZE_OUTPUT( UnityGI, gi );\n"; + ShaderBody += "\t\t\t\to.Alpha = LightingStandardCustomLighting( o, worldViewDir, gi ).a;\n"; + } + ShaderBody += "\t\t\t\t#if defined( CAN_SKIP_VPOS )\n"; + ShaderBody += "\t\t\t\tfloat2 vpos = IN.pos;\n"; + ShaderBody += "\t\t\t\t#endif\n"; + + /*if( ( ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) && hasOpacity && m_inputPorts[ m_discardPortId ].IsConnected ) ) + { + + } + else*/ if(!( ( m_alphaToCoverage || m_inlineAlphaToCoverage.Active ) && hasOpacity && m_inputPorts[ m_discardPortId ].IsConnected ) && hasOpacity ) + { + ShaderBody += "\t\t\t\thalf alphaRef = tex3D( _DitherMaskLOD, float3( vpos.xy * 0.25, o.Alpha * 0.9375 ) ).a;\n"; + ShaderBody += "\t\t\t\tclip( alphaRef - 0.01 );\n"; + } + + ShaderBody += "\t\t\t\tSHADOW_CASTER_FRAGMENT( IN )\n"; + ShaderBody += "\t\t\t}\n"; + + ShaderBody += "\t\t\tENDCG\n"; + + ShaderBody += "\t\t}\n"; + } + + } + + if( !string.IsNullOrEmpty( bellowUsePasses ) ) + { + ShaderBody += bellowUsePasses; + } + + CloseSubShaderBody( ref ShaderBody ); + + if( m_dependenciesHelper.HasDependencies ) + { + ShaderBody += m_dependenciesHelper.GenerateDependencies(); + } + + if( m_fallbackHelper.Active ) + { + ShaderBody += m_fallbackHelper.TabbedFallbackShader; + } + else if( m_castShadows || m_receiveShadows ) + { + AddShaderProperty( ref ShaderBody, "Fallback", "Diffuse" ); + } + + if( !string.IsNullOrEmpty( m_customInspectorName ) ) + { + AddShaderProperty( ref ShaderBody, "CustomEditor", m_customInspectorName ); + } + } + CloseShaderBody( ref ShaderBody ); + + if( usingDebugPort ) + { + m_currentLightModel = cachedLightModel; + ContainerGraph.CurrentCanvasMode = cachedAvailability; + } + + // Generate Graph info + ShaderBody += ContainerGraph.ParentWindow.GenerateGraphInfo(); + + //TODO: Remove current SaveDebugShader and uncomment SaveToDisk as soon as pathname is editable + if( !String.IsNullOrEmpty( pathname ) ) + { + IOUtils.StartSaveThread( ShaderBody, ( isFullPath ? pathname : ( IOUtils.dataPath + pathname ) ) ); + } + else + { + IOUtils.StartSaveThread( ShaderBody, Application.dataPath + "/AmplifyShaderEditor/Samples/Shaders/" + m_shaderName + ".shader" ); + } + + // Load new shader into material + + if( CurrentShader == null ) + { + AssetDatabase.Refresh( ImportAssetOptions.ForceUpdate ); + CurrentShader = Shader.Find( ShaderName ); + } + //else + //{ + // // need to always get asset datapath because a user can change and asset location from the project window + // AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( m_currentShader ) ); + // //ShaderUtil.UpdateShaderAsset( m_currentShader, ShaderBody ); + //} + + if( m_currentShader != null ) + { + m_currentDataCollector.UpdateShaderImporter( ref m_currentShader ); + if( m_currentMaterial != null ) + { + if( m_currentShader != m_currentMaterial.shader ) + m_currentMaterial.shader = m_currentShader; +#if UNITY_5_6_OR_NEWER + if ( isInstancedShader ) + { + m_currentMaterial.enableInstancing = true; + } +#endif + m_currentDataCollector.UpdateMaterialOnPropertyNodes( m_currentMaterial ); + UpdateMaterialEditor(); + // need to always get asset datapath because a user can change and asset location from the project window + //AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( m_currentMaterial ) ); + } + } + + m_currentDataCollector.Destroy(); + m_currentDataCollector = null; + + return m_currentShader; + } + + public override void UpdateFromShader( Shader newShader ) + { + if( m_currentMaterial != null && m_currentMaterial.shader != newShader ) + { + m_currentMaterial.shader = newShader; + } + CurrentShader = newShader; + } + + public override void Destroy() + { + base.Destroy(); + + if( m_dummyProperty != null ) + { + m_dummyProperty.Destroy(); + GameObject.DestroyImmediate( m_dummyProperty ); + m_dummyProperty = null; + } + + m_drawInstancedHelper = null; + + m_translucencyPort = null; + m_transmissionPort = null; + m_refractionPort = null; + m_normalPort = null; + + m_renderingOptionsOpHelper.Destroy(); + m_renderingOptionsOpHelper = null; + + m_additionalIncludes.Destroy(); + m_additionalIncludes = null; + + m_additionalPragmas.Destroy(); + m_additionalPragmas = null; + + m_additionalDefines.Destroy(); + m_additionalDefines = null; + + m_additionalSurfaceOptions.Destroy(); + m_additionalSurfaceOptions = null; + + m_additionalDirectives.Destroy(); + m_additionalDirectives = null; + + m_customTagsHelper.Destroy(); + m_customTagsHelper = null; + + m_dependenciesHelper.Destroy(); + m_dependenciesHelper = null; + + m_renderingPlatformOpHelper = null; + m_inspectorDefaultStyle = null; + m_inspectorFoldoutStyle = null; + + m_zBufferHelper = null; + m_stencilBufferHelper = null; + m_blendOpsHelper = null; + m_tessOpHelper.Destroy(); + m_tessOpHelper = null; + m_outlineHelper.Destroy(); + m_outlineHelper = null; + m_colorMaskHelper.Destroy(); + m_colorMaskHelper = null; + m_billboardOpHelper = null; + + m_fallbackHelper.Destroy(); + GameObject.DestroyImmediate( m_fallbackHelper ); + m_fallbackHelper = null; + + m_usePass.Destroy(); + GameObject.DestroyImmediate( m_usePass ); + m_usePass = null; + } + + public override int VersionConvertInputPortId( int portId ) + { + int newPort = portId; + + //added translucency input after occlusion + if( UIUtils.CurrentShaderVersion() <= 2404 ) + { + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + case StandardShaderLightModel.StandardSpecular: + if( portId >= 6 ) + newPort += 1; + break; + case StandardShaderLightModel.CustomLighting: + case StandardShaderLightModel.Unlit: + case StandardShaderLightModel.Lambert: + case StandardShaderLightModel.BlinnPhong: + if( portId >= 5 ) + newPort += 1; + break; + } + } + + portId = newPort; + + //added transmission input after occlusion + if( UIUtils.CurrentShaderVersion() < 2407 ) + { + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + case StandardShaderLightModel.StandardSpecular: + if( portId >= 6 ) + newPort += 1; + break; + case StandardShaderLightModel.CustomLighting: + case StandardShaderLightModel.Unlit: + case StandardShaderLightModel.Lambert: + case StandardShaderLightModel.BlinnPhong: + if( portId >= 5 ) + newPort += 1; + break; + } + } + + portId = newPort; + + //added tessellation ports + if( UIUtils.CurrentShaderVersion() < 3002 ) + { + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + case StandardShaderLightModel.StandardSpecular: + if( portId >= 13 ) + newPort += 1; + break; + case StandardShaderLightModel.CustomLighting: + case StandardShaderLightModel.Unlit: + case StandardShaderLightModel.Lambert: + case StandardShaderLightModel.BlinnPhong: + if( portId >= 10 ) + newPort += 1; + break; + } + } + + portId = newPort; + + //added refraction after translucency + if( UIUtils.CurrentShaderVersion() < 3204 ) + { + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + case StandardShaderLightModel.StandardSpecular: + if( portId >= 8 ) + newPort += 1; + break; + case StandardShaderLightModel.CustomLighting: + case StandardShaderLightModel.Unlit: + case StandardShaderLightModel.Lambert: + case StandardShaderLightModel.BlinnPhong: + if( portId >= 7 ) + newPort += 1; + break; + } + } + + portId = newPort; + + //removed custom lighting port + //if ( UIUtils.CurrentShaderVersion() < 10003 ) //runs everytime because this system is only used after 5000 version + { + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + case StandardShaderLightModel.StandardSpecular: + if( portId >= 13 ) + newPort -= 1; + break; + case StandardShaderLightModel.CustomLighting: + case StandardShaderLightModel.Unlit: + case StandardShaderLightModel.Lambert: + case StandardShaderLightModel.BlinnPhong: + if( portId >= 12 ) + newPort -= 1; + break; + } + } + + portId = newPort; + + //if( UIUtils.CurrentShaderVersion() < 13802 ) //runs everytime because this system is only used after 5000 version + { + switch( m_currentLightModel ) + { + case StandardShaderLightModel.Standard: + case StandardShaderLightModel.StandardSpecular: + if( portId >= 11 ) + newPort += 1; + break; + case StandardShaderLightModel.CustomLighting: + case StandardShaderLightModel.Unlit: + case StandardShaderLightModel.Lambert: + case StandardShaderLightModel.BlinnPhong: + if( portId >= 10 ) + newPort += 1; + break; + } + } + + portId = newPort; + return newPort; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + try + { + base.ReadFromString( ref nodeParams ); + m_currentLightModel = (StandardShaderLightModel)Enum.Parse( typeof( StandardShaderLightModel ), GetCurrentParam( ref nodeParams ) ); + + if( CurrentMasterNodeCategory == AvailableShaderTypes.SurfaceShader && m_currentLightModel == StandardShaderLightModel.CustomLighting ) + { + ContainerGraph.CurrentCanvasMode = NodeAvailability.CustomLighting; + ContainerGraph.ParentWindow.CurrentNodeAvailability = NodeAvailability.CustomLighting; + } + else if( CurrentMasterNodeCategory == AvailableShaderTypes.SurfaceShader ) + { + ContainerGraph.CurrentCanvasMode = NodeAvailability.SurfaceShader; + ContainerGraph.ParentWindow.CurrentNodeAvailability = NodeAvailability.SurfaceShader; + } + //if ( _shaderCategory.Length > 0 ) + // _shaderCategory = UIUtils.RemoveInvalidCharacters( _shaderCategory ); + ShaderName = GetCurrentParam( ref nodeParams ); + if( m_shaderName.Length > 0 ) + ShaderName = UIUtils.RemoveShaderInvalidCharacters( ShaderName ); + + m_renderingOptionsOpHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + + m_cullMode = (CullMode)Enum.Parse( typeof( CullMode ), GetCurrentParam( ref nodeParams ) ); + m_zBufferHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + + string alphaMode = GetCurrentParam( ref nodeParams ); + + if( UIUtils.CurrentShaderVersion() < 4003 ) + { + if( alphaMode.Equals( "Fade" ) ) + { + alphaMode = "Transparent"; + } + else if( alphaMode.Equals( "Transparent" ) ) + { + alphaMode = "Premultiply"; + } + } + + m_alphaMode = (AlphaMode)Enum.Parse( typeof( AlphaMode ), alphaMode ); + m_opacityMaskClipValue = Convert.ToSingle( GetCurrentParam( ref nodeParams ) ); + m_keepAlpha = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_keepAlpha = true; + m_castShadows = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_queueOrder = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > 11 ) + { + m_customBlendMode = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_renderType = (RenderType)Enum.Parse( typeof( RenderType ), GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > 14305 ) + { + m_customRenderType = GetCurrentParam( ref nodeParams ); + } + m_renderQueue = (RenderQueue)Enum.Parse( typeof( RenderQueue ), GetCurrentParam( ref nodeParams ) ); + } + if( UIUtils.CurrentShaderVersion() > 2402 ) + { + m_renderPath = (RenderPath)Enum.Parse( typeof( RenderPath ), GetCurrentParam( ref nodeParams ) ); + } + if( UIUtils.CurrentShaderVersion() > 2405 ) + { + m_renderingPlatformOpHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 2500 ) + { + m_colorMaskHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 2501 ) + { + m_stencilBufferHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 2504 ) + { + m_tessOpHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 2505 ) + { + m_receiveShadows = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() > 3202 ) + { + m_blendOpsHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 3203 ) + { + m_grabOrder = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() > 5003 ) + { + m_outlineHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 5110 ) + { + m_billboardOpHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 6101 ) + { + m_vertexMode = (VertexMode)Enum.Parse( typeof( VertexMode ), GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() > 6102 ) + { + ShaderLOD = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_fallbackHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 7102 ) + { + m_maskClipOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_translucencyOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_refractionOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_tessellationOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() > 10010 && UIUtils.CurrentShaderVersion() < 15312 ) + { + m_additionalIncludes.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 11006 ) + { + m_customTagsHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 13102 && UIUtils.CurrentShaderVersion() < 15312 ) + { + m_additionalPragmas.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 13205 ) + { + m_alphaToCoverage = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() > 13903 ) + { + m_dependenciesHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 14005 && UIUtils.CurrentShaderVersion() < 15312 ) + { + m_additionalDefines.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 14501 ) + { + m_inlineCullMode.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 14502 ) + { + m_specColorOrderIndex = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + if( UIUtils.CurrentShaderVersion() > 15204 ) + { + m_inlineOpacityMaskClipValue.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 15311 ) + { + m_additionalDirectives.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + m_additionalSurfaceOptions.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + else + { + m_additionalDirectives.AddItems( AdditionalLineType.Define, m_additionalDefines.DefineList ); + m_additionalDirectives.AddItems( AdditionalLineType.Include, m_additionalIncludes.IncludeList ); + m_additionalDirectives.AddItems( AdditionalLineType.Pragma, m_additionalPragmas.PragmaList ); + } + + if( UIUtils.CurrentShaderVersion() > 15402 ) + { + m_usePass.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 16203 ) + { + m_drawInstancedHelper.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + } + + if( UIUtils.CurrentShaderVersion() > 16204 ) + m_inlineChromaticAberration.ReadFromString( ref m_currentReadParamIdx, ref nodeParams , false ); + + if( UIUtils.CurrentShaderVersion() > 16207 ) + m_inlineAlphaToCoverage.ReadFromString( ref m_currentReadParamIdx, ref nodeParams ); + + m_lightModelChanged = true; + m_lastLightModel = m_currentLightModel; + DeleteAllInputConnections( true ); + AddMasterPorts(); + UpdateFromBlendMode(); + m_customBlendMode = TestCustomBlendMode(); + + ContainerGraph.CurrentPrecision = m_currentPrecisionType; + } + catch( Exception e ) + { + Debug.Log( e ); + } + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + + // change port connection from emission to the new custom lighting port + if( m_currentLightModel == StandardShaderLightModel.CustomLighting && m_inputPorts[ m_emissionPortId ].IsConnected && UIUtils.CurrentShaderVersion() < 13802 ) + { + OutputPort port = m_inputPorts[ m_emissionPortId ].GetOutputConnection( 0 ); + m_inputPorts[ m_emissionPortId ].FullDeleteConnections(); + UIUtils.SetConnection( m_inputPorts[ m_customLightingPortId ].NodeId, m_inputPorts[ m_customLightingPortId ].PortId, port.NodeId, port.PortId ); + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentLightModel ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_shaderName ); + m_renderingOptionsOpHelper.WriteToString( ref nodeInfo ); + + IOUtils.AddFieldValueToString( ref nodeInfo, m_cullMode ); + m_zBufferHelper.WriteToString( ref nodeInfo ); + + IOUtils.AddFieldValueToString( ref nodeInfo, m_alphaMode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_opacityMaskClipValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_keepAlpha ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_castShadows ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_queueOrder ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_customBlendMode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_renderType ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_customRenderType ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_renderQueue ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_renderPath ); + m_renderingPlatformOpHelper.WriteToString( ref nodeInfo ); + m_colorMaskHelper.WriteToString( ref nodeInfo ); + m_stencilBufferHelper.WriteToString( ref nodeInfo ); + m_tessOpHelper.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_receiveShadows ); + m_blendOpsHelper.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_grabOrder ); + m_outlineHelper.WriteToString( ref nodeInfo ); + m_billboardOpHelper.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_vertexMode ); + IOUtils.AddFieldValueToString( ref nodeInfo, ShaderLOD ); + m_fallbackHelper.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_maskClipReorder != null ) ? m_maskClipReorder.OrderIndex : -1 ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_translucencyReorder != null ) ? m_translucencyReorder.OrderIndex : -1 ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_refractionReorder != null ) ? m_refractionReorder.OrderIndex : -1 ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_tessellationReorder != null ) ? m_tessellationReorder.OrderIndex : -1 ); + //m_additionalIncludes.WriteToString( ref nodeInfo ); + m_customTagsHelper.WriteToString( ref nodeInfo ); + //m_additionalPragmas.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_alphaToCoverage ); + m_dependenciesHelper.WriteToString( ref nodeInfo ); + //m_additionalDefines.WriteToString( ref nodeInfo ); + m_inlineCullMode.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_specColorReorder != null ) ? m_specColorReorder.OrderIndex : -1 ); + m_inlineOpacityMaskClipValue.WriteToString( ref nodeInfo ); + m_additionalDirectives.WriteToString( ref nodeInfo ); + m_additionalSurfaceOptions.WriteToString( ref nodeInfo ); + m_usePass.WriteToString( ref nodeInfo ); + m_drawInstancedHelper.WriteToString( ref nodeInfo ); + m_inlineChromaticAberration.WriteToString( ref nodeInfo ); + m_inlineAlphaToCoverage.WriteToString( ref nodeInfo ); + } + + private bool TestCustomBlendMode() + { + switch( m_alphaMode ) + { + case AlphaMode.Opaque: + { + if( m_renderType == RenderType.Opaque && m_renderQueue == RenderQueue.Geometry ) + return false; + } + break; + case AlphaMode.Masked: + { + if( m_renderType == RenderType.TransparentCutout && m_renderQueue == RenderQueue.AlphaTest ) + return false; + } + break; + case AlphaMode.Transparent: + case AlphaMode.Premultiply: + { + if( m_renderType == RenderType.Transparent && m_renderQueue == RenderQueue.Transparent ) + return false; + } + break; + case AlphaMode.Translucent: + { + if( m_renderType == RenderType.Opaque && m_renderQueue == RenderQueue.Transparent ) + return false; + } + break; + } + return true; + } + + private void UpdateFromBlendMode() + { + m_checkChanges = true; + bool lockRefractionPort = false; + if( m_currentLightModel == StandardShaderLightModel.Unlit || m_currentLightModel == StandardShaderLightModel.CustomLighting ) + { + lockRefractionPort = true; + } + + switch( m_alphaMode ) + { + case AlphaMode.Opaque: + { + m_renderType = RenderType.Opaque; + m_renderQueue = RenderQueue.Geometry; + m_keepAlpha = true; + m_refractionPort.Locked = true; + m_inputPorts[ m_opacityPortId ].Locked = true; + m_inputPorts[ m_discardPortId ].Locked = true; + } + break; + case AlphaMode.Masked: + { + m_renderType = RenderType.TransparentCutout; + m_renderQueue = RenderQueue.AlphaTest; + m_keepAlpha = true; + m_refractionPort.Locked = true; + m_inputPorts[ m_opacityPortId ].Locked = true; + m_inputPorts[ m_discardPortId ].Locked = false; + } + break; + case AlphaMode.Transparent: + case AlphaMode.Premultiply: + { + m_renderType = RenderType.Transparent; + m_renderQueue = RenderQueue.Transparent; + m_refractionPort.Locked = false || lockRefractionPort; + m_inputPorts[ m_opacityPortId ].Locked = false; + m_inputPorts[ m_discardPortId ].Locked = true; + } + break; + case AlphaMode.Translucent: + { + m_renderType = RenderType.Opaque; + m_renderQueue = RenderQueue.Transparent; + m_refractionPort.Locked = false || lockRefractionPort; + m_inputPorts[ m_opacityPortId ].Locked = false; + m_inputPorts[ m_discardPortId ].Locked = true; + } + break; + case AlphaMode.Custom: + { + m_refractionPort.Locked = false || lockRefractionPort; + m_inputPorts[ m_opacityPortId ].Locked = false; + m_inputPorts[ m_discardPortId ].Locked = false; + } + break; + } + + m_blendOpsHelper.SetBlendOpsFromBlendMode( m_alphaMode, ( m_alphaMode == AlphaMode.Custom || m_alphaMode == AlphaMode.Opaque ) ); + } + + public bool CastShadows { get { return m_castShadows; } } + public StandardShaderLightModel CurrentLightingModel { get { return m_currentLightModel; } } + public CullMode CurrentCullMode { get { return m_cullMode; } } + //public AdditionalIncludesHelper AdditionalIncludes { get { return m_additionalIncludes; } set { m_additionalIncludes = value; } } + //public AdditionalPragmasHelper AdditionalPragmas { get { return m_additionalPragmas; } set { m_additionalPragmas = value; } } + //public AdditionalDefinesHelper AdditionalDefines { get { return m_additionalDefines; } set { m_additionalDefines = value; } } + public TemplateAdditionalDirectivesHelper AdditionalDirectives { get { return m_additionalDirectives; } } + public OutlineOpHelper OutlineHelper { get { return m_outlineHelper; } } + public float OpacityMaskClipValue { get { return m_opacityMaskClipValue; } } + public InlineProperty InlineOpacityMaskClipValue { get { return m_inlineOpacityMaskClipValue; } set { m_inlineOpacityMaskClipValue = value; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StandardSurface.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StandardSurface.cs.meta new file mode 100644 index 00000000..0515f8ca --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StandardSurface.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 59e61f9559385a94a87d4d37dbd556f0 +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StencilBufferOpHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StencilBufferOpHelper.cs new file mode 100644 index 00000000..b613f0f1 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StencilBufferOpHelper.cs @@ -0,0 +1,304 @@ +using System; +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + + [Serializable] + public class StencilBufferOpHelper + { + public static readonly string[] StencilComparisonValues = + { + "<Default>", + "Greater" , + "GEqual" , + "Less" , + "LEqual" , + "Equal" , + "NotEqual" , + "Always" , + "Never" + }; + + public static readonly Dictionary<string,int> StencilComparisonValuesDict = new Dictionary<string, int>() + { + {"Greater" , 1}, + {"GEqual" , 2}, + {"Less" , 3}, + {"LEqual" , 4}, + {"Equal" , 5}, + {"NotEqual", 6}, + {"Always" , 7}, + {"Never" , 8}, + }; + + public static readonly string[] StencilComparisonLabels = + { + "<Default>", + "Greater" , + "Greater or Equal" , + "Less" , + "Less or Equal" , + "Equal" , + "Not Equal" , + "Always" , + "Never" + }; + + + public static readonly string[] StencilOpsValues = + { + "<Default>", + "Keep", + "Zero", + "Replace", + "IncrSat", + "DecrSat", + "Invert", + "IncrWrap", + "DecrWrap" + }; + + public static readonly Dictionary<string,int> StencilOpsValuesDict = new Dictionary<string, int>() + { + {"Keep", 1}, + {"Zero", 2}, + {"Replace", 3}, + {"IncrSat", 4}, + {"DecrSat", 5}, + {"Invert", 6}, + {"IncrWrap",7}, + {"DecrWrap",8}, + }; + + public static readonly string[] StencilOpsLabels = + { + "<Default>", + "Keep", + "Zero", + "Replace", + "IncrSat", + "DecrSat", + "Invert", + "IncrWrap", + "DecrWrap" + }; + + + private const string FoldoutLabelStr = " Stencil Buffer"; + private GUIContent ReferenceValueContent = new GUIContent( "Reference", "The value to be compared against (if Comparison is anything else than always) and/or the value to be written to the buffer (if either Pass, Fail or ZFail is set to replace)" ); + private GUIContent ReadMaskContent = new GUIContent( "Read Mask", "An 8 bit mask as an 0-255 integer, used when comparing the reference value with the contents of the buffer (referenceValue & readMask) comparisonFunction (stencilBufferValue & readMask)" ); + private GUIContent WriteMaskContent = new GUIContent( "Write Mask", "An 8 bit mask as an 0-255 integer, used when writing to the buffer" ); + private const string ComparisonStr = "Comparison"; + private const string PassStr = "Pass"; + private const string FailStr = "Fail"; + private const string ZFailStr = "ZFail"; + + private const string ComparisonFrontStr = "Comp. Front"; + private const string PassFrontStr = "Pass Front"; + private const string FailFrontStr = "Fail Front"; + private const string ZFailFrontStr = "ZFail Front"; + + private const string ComparisonBackStr = "Comp. Back"; + private const string PassBackStr = "Pass Back"; + private const string FailBackStr = "Fail Back"; + private const string ZFailBackStr = "ZFail Back"; + + private const int ReadMaskDefaultValue = 255; + private const int WriteMaskDefaultValue = 255; + private const int ComparisonDefaultValue = 0; + private const int PassStencilOpDefaultValue = 0; + private const int FailStencilOpDefaultValue = 0; + private const int ZFailStencilOpDefaultValue = 0; + + [SerializeField] + private bool m_active; + + [SerializeField] + private InlineProperty m_refValue = new InlineProperty(); + [SerializeField] + private InlineProperty m_readMask = new InlineProperty( ReadMaskDefaultValue ); + [SerializeField] + private InlineProperty m_writeMask = new InlineProperty( WriteMaskDefaultValue ); + + //Comparison Function + [SerializeField] + private InlineProperty m_comparisonFunctionIdx = new InlineProperty( ComparisonDefaultValue ); + [SerializeField] + private InlineProperty m_comparisonFunctionBackIdx = new InlineProperty( ComparisonDefaultValue ); + + //Pass Stencil Op + [SerializeField] + private InlineProperty m_passStencilOpIdx = new InlineProperty( PassStencilOpDefaultValue ); + [SerializeField] + private InlineProperty m_passStencilOpBackIdx = new InlineProperty( PassStencilOpDefaultValue ); + + //Fail Stencil Op + [SerializeField] + private InlineProperty m_failStencilOpIdx = new InlineProperty( FailStencilOpDefaultValue ); + [SerializeField] + private InlineProperty m_failStencilOpBackIdx = new InlineProperty( FailStencilOpDefaultValue ); + + //ZFail Stencil Op + [SerializeField] + private InlineProperty m_zFailStencilOpIdx = new InlineProperty( ZFailStencilOpDefaultValue ); + [SerializeField] + private InlineProperty m_zFailStencilOpBackIdx = new InlineProperty( ZFailStencilOpDefaultValue ); + + public string CreateStencilOp( UndoParentNode owner ) + { + string result = "\t\tStencil\n\t\t{\n"; + result += string.Format( "\t\t\tRef {0}\n", m_refValue.GetValueOrProperty() ); + if( m_readMask.Active || m_readMask.IntValue != ReadMaskDefaultValue ) + { + result += string.Format( "\t\t\tReadMask {0}\n", m_readMask.GetValueOrProperty() ); + } + + if( m_writeMask.Active || m_writeMask.IntValue != WriteMaskDefaultValue ) + { + result += string.Format( "\t\t\tWriteMask {0}\n", m_writeMask.GetValueOrProperty() ); + } + + if( ( owner as StandardSurfaceOutputNode ).CurrentCullMode == CullMode.Off ) + { + if( m_comparisonFunctionIdx.IntValue != ComparisonDefaultValue || m_comparisonFunctionIdx.Active ) + result += string.Format( "\t\t\tCompFront {0}\n", m_comparisonFunctionIdx.GetValueOrProperty( StencilComparisonValues[ m_comparisonFunctionIdx.IntValue ] ) ); + if( m_passStencilOpIdx.IntValue != PassStencilOpDefaultValue || m_passStencilOpIdx.Active ) + result += string.Format( "\t\t\tPassFront {0}\n", m_passStencilOpIdx.GetValueOrProperty( StencilOpsValues[ m_passStencilOpIdx.IntValue ] ) ); + if( m_failStencilOpIdx.IntValue != FailStencilOpDefaultValue || m_failStencilOpIdx.Active ) + result += string.Format( "\t\t\tFailFront {0}\n", m_failStencilOpIdx.GetValueOrProperty( StencilOpsValues[ m_failStencilOpIdx.IntValue ] ) ); + if( m_zFailStencilOpIdx.IntValue != ZFailStencilOpDefaultValue || m_zFailStencilOpIdx.Active ) + result += string.Format( "\t\t\tZFailFront {0}\n", m_zFailStencilOpIdx.GetValueOrProperty( StencilOpsValues[ m_zFailStencilOpIdx.IntValue ] ) ); + + if( m_comparisonFunctionBackIdx.IntValue != ComparisonDefaultValue || m_comparisonFunctionBackIdx.Active ) + result += string.Format( "\t\t\tCompBack {0}\n", m_comparisonFunctionBackIdx.GetValueOrProperty( StencilComparisonValues[ m_comparisonFunctionBackIdx.IntValue ] ) ); + if( m_passStencilOpBackIdx.IntValue != PassStencilOpDefaultValue || m_passStencilOpBackIdx.Active ) + result += string.Format( "\t\t\tPassBack {0}\n", m_passStencilOpBackIdx.GetValueOrProperty( StencilOpsValues[ m_passStencilOpBackIdx.IntValue ] ) ); + if( m_failStencilOpBackIdx.IntValue != FailStencilOpDefaultValue || m_failStencilOpBackIdx.Active ) + result += string.Format( "\t\t\tFailBack {0}\n", m_failStencilOpBackIdx.GetValueOrProperty( StencilOpsValues[ m_failStencilOpBackIdx.IntValue ] ) ); + if( m_zFailStencilOpBackIdx.IntValue != ZFailStencilOpDefaultValue || m_zFailStencilOpBackIdx.Active ) + result += string.Format( "\t\t\tZFailBack {0}\n", m_zFailStencilOpBackIdx.GetValueOrProperty( StencilOpsValues[ m_zFailStencilOpBackIdx.IntValue ] ) ); + } + else + { + if( m_comparisonFunctionIdx.IntValue != ComparisonDefaultValue || m_comparisonFunctionIdx.Active ) + result += string.Format( "\t\t\tComp {0}\n", m_comparisonFunctionIdx.GetValueOrProperty( StencilComparisonValues[ m_comparisonFunctionIdx.IntValue ] ) ); + if( m_passStencilOpIdx.IntValue != PassStencilOpDefaultValue || m_passStencilOpIdx.Active ) + result += string.Format( "\t\t\tPass {0}\n", m_passStencilOpIdx.GetValueOrProperty( StencilOpsValues[ m_passStencilOpIdx.IntValue ] ) ); + if( m_failStencilOpIdx.IntValue != FailStencilOpDefaultValue || m_failStencilOpIdx.Active ) + result += string.Format( "\t\t\tFail {0}\n", m_failStencilOpIdx.GetValueOrProperty( StencilOpsValues[ m_failStencilOpIdx.IntValue ] ) ); + if( m_zFailStencilOpIdx.IntValue != ZFailStencilOpDefaultValue || m_zFailStencilOpIdx.Active ) + result += string.Format( "\t\t\tZFail {0}\n", m_zFailStencilOpIdx.GetValueOrProperty( StencilOpsValues[ m_zFailStencilOpIdx.IntValue ] ) ); + } + + + result += "\t\t}\n"; + return result; + } + + public void Draw( UndoParentNode owner ) + { + bool foldoutValue = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedStencilOptions; + NodeUtils.DrawPropertyGroup( owner, ref foldoutValue, ref m_active, FoldoutLabelStr, () => + { + float cache = EditorGUIUtility.labelWidth; + float cache2 = EditorGUIUtility.fieldWidth; + EditorGUIUtility.labelWidth = 110; + EditorGUIUtility.fieldWidth = 30; + m_refValue.IntSlider( ref owner, ReferenceValueContent, 0, 255 ); + m_readMask.IntSlider( ref owner, ReadMaskContent, 0, 255 ); + m_writeMask.IntSlider( ref owner, WriteMaskContent, 0, 255 ); + //EditorGUIUtility.labelWidth = cache; + EditorGUIUtility.fieldWidth = cache2; + if( ( owner as StandardSurfaceOutputNode ).CurrentCullMode == CullMode.Off ) + { + m_comparisonFunctionIdx.EnumTypePopup( ref owner, ComparisonFrontStr, StencilComparisonLabels ); + m_passStencilOpIdx.EnumTypePopup( ref owner, PassFrontStr, StencilOpsLabels ); + m_failStencilOpIdx.EnumTypePopup( ref owner, FailFrontStr, StencilOpsLabels ); + m_zFailStencilOpIdx.EnumTypePopup( ref owner, ZFailFrontStr, StencilOpsLabels ); + EditorGUILayout.Separator(); + m_comparisonFunctionBackIdx.EnumTypePopup( ref owner, ComparisonBackStr, StencilComparisonLabels ); + m_passStencilOpBackIdx.EnumTypePopup( ref owner, PassBackStr, StencilOpsLabels ); + m_failStencilOpBackIdx.EnumTypePopup( ref owner, FailBackStr, StencilOpsLabels ); + m_zFailStencilOpBackIdx.EnumTypePopup( ref owner, ZFailBackStr, StencilOpsLabels ); + } + else + { + m_comparisonFunctionIdx.EnumTypePopup( ref owner, ComparisonStr, StencilComparisonLabels ); + m_passStencilOpIdx.EnumTypePopup( ref owner, PassFrontStr, StencilOpsLabels ); + m_failStencilOpIdx.EnumTypePopup( ref owner, FailFrontStr, StencilOpsLabels ); + m_zFailStencilOpIdx.EnumTypePopup( ref owner, ZFailFrontStr, StencilOpsLabels ); + } + EditorGUIUtility.labelWidth = cache; + } ); + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedStencilOptions = foldoutValue; + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + m_active = Convert.ToBoolean( nodeParams[ index++ ] ); + if( UIUtils.CurrentShaderVersion() > 14501 ) + { + m_refValue.ReadFromString( ref index, ref nodeParams ); + m_readMask.ReadFromString( ref index, ref nodeParams ); + m_writeMask.ReadFromString( ref index, ref nodeParams ); + m_comparisonFunctionIdx.ReadFromString( ref index, ref nodeParams ); + m_passStencilOpIdx.ReadFromString( ref index, ref nodeParams ); + m_failStencilOpIdx.ReadFromString( ref index, ref nodeParams ); + m_zFailStencilOpIdx.ReadFromString( ref index, ref nodeParams ); + } + else + { + m_refValue.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_readMask.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_writeMask.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_comparisonFunctionIdx.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_passStencilOpIdx.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_failStencilOpIdx.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_zFailStencilOpIdx.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 13203 ) + { + if( UIUtils.CurrentShaderVersion() > 14501 ) + { + m_comparisonFunctionBackIdx.ReadFromString( ref index, ref nodeParams ); + m_passStencilOpBackIdx.ReadFromString( ref index, ref nodeParams ); + m_failStencilOpBackIdx.ReadFromString( ref index, ref nodeParams ); + m_zFailStencilOpBackIdx.ReadFromString( ref index, ref nodeParams ); + } + else + { + m_comparisonFunctionBackIdx.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_passStencilOpBackIdx.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_failStencilOpBackIdx.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_zFailStencilOpBackIdx.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + } + } + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_active ); + m_refValue.WriteToString( ref nodeInfo ); + m_readMask.WriteToString( ref nodeInfo ); + m_writeMask.WriteToString( ref nodeInfo ); + m_comparisonFunctionIdx.WriteToString( ref nodeInfo ); + m_passStencilOpIdx.WriteToString( ref nodeInfo ); + m_failStencilOpIdx.WriteToString( ref nodeInfo ); + m_zFailStencilOpIdx.WriteToString( ref nodeInfo ); + m_comparisonFunctionBackIdx.WriteToString( ref nodeInfo ); + m_passStencilOpBackIdx.WriteToString( ref nodeInfo ); + m_failStencilOpBackIdx.WriteToString( ref nodeInfo ); + m_zFailStencilOpBackIdx.WriteToString( ref nodeInfo ); + } + + public bool Active + { + get { return m_active; } + set { m_active = value; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StencilBufferOpHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StencilBufferOpHelper.cs.meta new file mode 100644 index 00000000..6dc55180 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StencilBufferOpHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 0111d524dc809f14aa95e4e1ab93d37b +timeCreated: 1481126953 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TerrainDrawInstancedHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TerrainDrawInstancedHelper.cs new file mode 100644 index 00000000..751317d1 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TerrainDrawInstancedHelper.cs @@ -0,0 +1,374 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; + +using System; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + [Serializable] + public class TerrainDrawInstancedHelper + { +#if UNITY_2018_1_OR_NEWER + private readonly string[] InstancedPragmas = + { + "multi_compile_instancing", + "instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap forwardadd" + }; + + private readonly string[] InstancedGlobalsSRP = + { + "#ifdef UNITY_INSTANCING_ENABLED//ASE Terrain Instancing", + "\tTEXTURE2D(_TerrainHeightmapTexture);//ASE Terrain Instancing", + "\tTEXTURE2D( _TerrainNormalmapTexture);//ASE Terrain Instancing", + "#endif//ASE Terrain Instancing", + "UNITY_INSTANCING_BUFFER_START( Terrain )//ASE Terrain Instancing", + "\tUNITY_DEFINE_INSTANCED_PROP( float4, _TerrainPatchInstanceData )//ASE Terrain Instancing", + "UNITY_INSTANCING_BUFFER_END( Terrain)//ASE Terrain Instancing", + "CBUFFER_START( UnityTerrain)//ASE Terrain Instancing", + "\t#ifdef UNITY_INSTANCING_ENABLED//ASE Terrain Instancing", + "\t\tfloat4 _TerrainHeightmapRecipSize;//ASE Terrain Instancing", + "\t\tfloat4 _TerrainHeightmapScale;//ASE Terrain Instancing", + "\t#endif//ASE Terrain Instancing", + "CBUFFER_END//ASE Terrain Instancing" + }; + + private readonly string[] InstancedGlobalsDefault = + { + "#ifdef UNITY_INSTANCING_ENABLED//ASE Terrain Instancing", + "\tsampler2D _TerrainHeightmapTexture;//ASE Terrain Instancing", + "\tsampler2D _TerrainNormalmapTexture;//ASE Terrain Instancing", + "#endif//ASE Terrain Instancing", + "UNITY_INSTANCING_BUFFER_START( Terrain )//ASE Terrain Instancing", + "\tUNITY_DEFINE_INSTANCED_PROP( float4, _TerrainPatchInstanceData )//ASE Terrain Instancing", + "UNITY_INSTANCING_BUFFER_END( Terrain)//ASE Terrain Instancing", + "CBUFFER_START( UnityTerrain)//ASE Terrain Instancing", + "\t#ifdef UNITY_INSTANCING_ENABLED//ASE Terrain Instancing", + "\t\tfloat4 _TerrainHeightmapRecipSize;//ASE Terrain Instancing", + "\t\tfloat4 _TerrainHeightmapScale;//ASE Terrain Instancing", + "\t#endif//ASE Terrain Instancing", + "CBUFFER_END//ASE Terrain Instancing" + }; + + + private readonly string ApplyMeshModificationInstruction = "{0} = ApplyMeshModification({0});"; + + private readonly string[] ApplyMeshModificationFunctionSRP = + { + /*0 - struct name 1 - var name*/"{0} ApplyMeshModification( {0} {1} )\n", + "{\n", + "#ifdef UNITY_INSTANCING_ENABLED\n", + /* 0 vertex position*/"\tfloat2 patchVertex = {0}.xy;\n", + "\tfloat4 instanceData = UNITY_ACCESS_INSTANCED_PROP( Terrain, _TerrainPatchInstanceData );\n", + "\tfloat2 sampleCoords = ( patchVertex.xy + instanceData.xy ) * instanceData.z;\n", + "\tfloat height = UnpackHeightmap( _TerrainHeightmapTexture.Load( int3( sampleCoords, 0 ) ) );\n", + /*0 - vertex position*/"\t{0}.xz = sampleCoords* _TerrainHeightmapScale.xz;\n", + /*0 - vertex position*/"\t{0}.y = height* _TerrainHeightmapScale.y;\n", + "\t#ifdef ENABLE_TERRAIN_PERPIXEL_NORMAL\n", + /* 0 - vertex normal*/"\t\t{0} = float3(0, 1, 0);\n", + "\t#else\n", + /* 0 - vertex normal*/"\t\t{0} = _TerrainNormalmapTexture.Load(int3(sampleCoords, 0)).rgb* 2 - 1;\n", + "\t#endif\n", + "#ifdef ENABLE_TERRAIN_PERPIXEL_NORMAL\n", + /* 0 - tex coord*/"\t{0}.xy = sampleCoords;\n", + "#else\n", + /* 0 - tex coord*/"\t{0}.xy = sampleCoords* _TerrainHeightmapRecipSize.zw;\n", + "#endif\n", + "#endif\n", + /* 0 - var name*/"\treturn {0};\n", + "}\n" + }; + //{ + // /*0 - struct name 1 - var name*/"{0} ApplyMeshModification( {0} {1} )\n", + // "{\n", + // "#ifdef UNITY_INSTANCING_ENABLED\n", + // /* 0 vertex position*/"\tfloat2 patchVertex = {0}.xy;\n", + // "\t\tfloat4 instanceData = UNITY_ACCESS_INSTANCED_PROP( Terrain, _TerrainPatchInstanceData );\n", + // "\t\tfloat2 sampleCoords = ( patchVertex.xy + instanceData.xy ) * instanceData.z;\n", + // "\t\tfloat height = UnpackHeightmap( _TerrainHeightmapTexture.Load( int3( sampleCoords, 0 ) ) );\n", + // /*0 - vertex position*/"\t\t{0}.xz = sampleCoords* _TerrainHeightmapScale.xz;\n", + // /*0 - vertex position*/"\t\t{0}.y = height* _TerrainHeightmapScale.y;\n", + // "# ifdef ATTRIBUTES_NEED_NORMAL\n", + // /* 0 - vertex normal*/"\t\t{0} = _TerrainNormalmapTexture.Load(int3(sampleCoords, 0)).rgb* 2 - 1;\n", + // "\t#endif\n", + // "\t#if defined(VARYINGS_NEED_TEXCOORD0) || defined(VARYINGS_DS_NEED_TEXCOORD0)\n", + // "\t\t#ifdef ENABLE_TERRAIN_PERPIXEL_NORMAL\n", + // /* 0 - tex coord*/"\t\t\t{0} = sampleCoords;\n", + // "\t\t#else\n", + // /* 0 - tex coord*/"\t\t\t{0}.xy = sampleCoords* _TerrainHeightmapRecipSize.zw;\n", + // "\t\t#endif\n", + // "\t#endif\n", + // "#endif\n", + // "#ifdef ATTRIBUTES_NEED_TANGENT\n", + // /* 0 - tangent 1 - normal*/"\t\t{0}.xyz = cross( {1}, float3(0, 0, 1));\n", + // /*0 - tangent*/"\t{0}.w = -1;\n", + // "#endif\n", + // /* 0 - var name*/"\treturn {0};\n", + // "}\n" + //}; + + + + private readonly string[] ApplyMeshModificationFunctionDefaultTemplate = + { + /* 0 vertex struct */"{0} ApplyMeshModification( {0} {1} )", + "{\n", + "#ifdef UNITY_INSTANCING_ENABLED\n", + /*0 - vertex pos*/"\tfloat2 patchVertex = {0}.xy;\n", + "\tfloat4 instanceData = UNITY_ACCESS_INSTANCED_PROP( Terrain, _TerrainPatchInstanceData );\n", + "\tfloat2 sampleCoords = ( patchVertex.xy + instanceData.xy ) * instanceData.z;\n", + /* 0 - tex coords*/"\t{0} = float4( sampleCoords.xy * _TerrainHeightmapRecipSize.z, 0, 0 );\n", + /* 0 - tex coords*/"\tfloat height = UnpackHeightmap( tex2Dlod( _TerrainHeightmapTexture, {0} ) );\n", + /* 0 - vertex pos*/"\t{0}.xz = sampleCoords * _TerrainHeightmapScale.xz;\n", + /* 0 - vertex pos*/"\t{0}.y = height * _TerrainHeightmapScale.y;\n", + /* 0 - normal 1 - tex coord*/"\t{0} = tex2Dlod( _TerrainNormalmapTexture, {1} ).rgb * 2 - 1;\n", + "#endif\n", + /* var name*/"return {0};\n", + "}\n" + }; + + private readonly string ApplyMeshModificationInstructionStandard = "ApplyMeshModification({0});"; + private readonly string[] ApplyMeshModificationFunctionStandard = + { + "void ApplyMeshModification( inout {0} v )", + "#if defined(UNITY_INSTANCING_ENABLED) && !defined(SHADER_API_D3D11_9X)", + "\tfloat2 patchVertex = v.vertex.xy;", + "\tfloat4 instanceData = UNITY_ACCESS_INSTANCED_PROP(Terrain, _TerrainPatchInstanceData);", + "\t", + "\tfloat4 uvscale = instanceData.z * _TerrainHeightmapRecipSize;", + "\tfloat4 uvoffset = instanceData.xyxy * uvscale;", + "\tuvoffset.xy += 0.5f * _TerrainHeightmapRecipSize.xy;", + "\tfloat2 sampleCoords = (patchVertex.xy * uvscale.xy + uvoffset.xy);", + "\t", + "\tfloat hm = UnpackHeightmap(tex2Dlod(_TerrainHeightmapTexture, float4(sampleCoords, 0, 0)));", + "\tv.vertex.xz = (patchVertex.xy + instanceData.xy) * _TerrainHeightmapScale.xz * instanceData.z;", + "\tv.vertex.y = hm * _TerrainHeightmapScale.y;", + "\tv.vertex.w = 1.0f;", + "\t", + "\tv.texcoord.xy = (patchVertex.xy * uvscale.zw + uvoffset.zw);", + "\tv.texcoord3 = v.texcoord2 = v.texcoord1 = v.texcoord;", + "\t", + "\t#ifdef TERRAIN_INSTANCED_PERPIXEL_NORMAL", + "\t\tv.normal = float3(0, 1, 0);", + "\t\t//data.tc.zw = sampleCoords;", + "\t#else", + "\t\tfloat3 nor = tex2Dlod(_TerrainNormalmapTexture, float4(sampleCoords, 0, 0)).xyz;", + "\t\tv.normal = 2.0f * nor - 1.0f;", + "\t#endif", + "#endif", + }; + private readonly string[] AdditionalUsePasses = + { + "Hidden/Nature/Terrain/Utilities/PICKING", + "Hidden/Nature/Terrain/Utilities/SELECTION" + }; + private readonly string DrawInstancedLabel = "Instanced Terrain"; +#endif + [SerializeField] + private bool m_enable = false; + + public void Draw( UndoParentNode owner ) + { +#if UNITY_2018_1_OR_NEWER + m_enable = owner.EditorGUILayoutToggle( DrawInstancedLabel, m_enable ); +#endif + } + + public void UpdateDataCollectorForTemplates( ref MasterNodeDataCollector dataCollector, ref List<string> vertexInstructions ) + { +#if UNITY_2018_1_OR_NEWER + if( m_enable ) + { + for( int i = 0; i < AdditionalUsePasses.Length; i++ ) + { + dataCollector.AddUsePass( AdditionalUsePasses[ i ], false ); + } + + for( int i = 0; i < InstancedPragmas.Length; i++ ) + { + dataCollector.AddToPragmas( -1, InstancedPragmas[ i ] ); + } + + if( dataCollector.IsSRP ) + { + + TemplateFunctionData functionData = dataCollector.TemplateDataCollectorInstance.CurrentTemplateData.VertexFunctionData; + string uvCoord = dataCollector.TemplateDataCollectorInstance.GetUV( 0, MasterNodePortCategory.Vertex ); + string vertexNormal = dataCollector.TemplateDataCollectorInstance.GetVertexNormal( PrecisionType.Float, false, MasterNodePortCategory.Vertex ); + //string vertexTangent = dataCollector.TemplateDataCollectorInstance.GetVertexTangent( WirePortDataType.FLOAT4, PrecisionType.Float, false, MasterNodePortCategory.Vertex ); + string vertexPos = dataCollector.TemplateDataCollectorInstance.GetVertexPosition( WirePortDataType.OBJECT, PrecisionType.Float, false, MasterNodePortCategory.Vertex ); + + string functionHeader = string.Format( ApplyMeshModificationFunctionSRP[ 0 ], functionData.InVarType, functionData.InVarName ); + + //string functionBody = functionHeader + + // ApplyMeshModificationFunctionSRP[ 1 ] + + // ApplyMeshModificationFunctionSRP[ 2 ] + + // string.Format( ApplyMeshModificationFunctionSRP[ 3 ], vertexPos ) + + // ApplyMeshModificationFunctionSRP[ 4 ] + + // ApplyMeshModificationFunctionSRP[ 5 ] + + // ApplyMeshModificationFunctionSRP[ 6 ] + + // string.Format( ApplyMeshModificationFunctionSRP[ 7 ], vertexPos ) + + // string.Format( ApplyMeshModificationFunctionSRP[ 8 ], vertexPos ) + + // ApplyMeshModificationFunctionSRP[ 9 ] + + // string.Format( ApplyMeshModificationFunctionSRP[ 10 ], vertexNormal ) + + // ApplyMeshModificationFunctionSRP[ 11 ] + + // ApplyMeshModificationFunctionSRP[ 12 ] + + // ApplyMeshModificationFunctionSRP[ 13 ] + + // string.Format( ApplyMeshModificationFunctionSRP[ 14 ], uvCoord ) + + // ApplyMeshModificationFunctionSRP[ 15 ] + + // string.Format( ApplyMeshModificationFunctionSRP[ 16 ], uvCoord ) + + // ApplyMeshModificationFunctionSRP[ 17 ] + + // ApplyMeshModificationFunctionSRP[ 18 ] + + // ApplyMeshModificationFunctionSRP[ 19 ] + + // ApplyMeshModificationFunctionSRP[ 20 ] + + // string.Format( ApplyMeshModificationFunctionSRP[ 21 ], vertexTangent, vertexNormal ) + + // string.Format( ApplyMeshModificationFunctionSRP[ 22 ], vertexTangent ) + + // ApplyMeshModificationFunctionSRP[ 23 ] + + // string.Format( ApplyMeshModificationFunctionSRP[ 24 ], functionData.InVarName ) + + // ApplyMeshModificationFunctionSRP[ 25 ]; + string functionBody = functionHeader + + ApplyMeshModificationFunctionSRP[ 1 ] + + ApplyMeshModificationFunctionSRP[ 2 ] + + string.Format( ApplyMeshModificationFunctionSRP[ 3 ], vertexPos ) + + ApplyMeshModificationFunctionSRP[ 4 ] + + ApplyMeshModificationFunctionSRP[ 5 ] + + ApplyMeshModificationFunctionSRP[ 6 ] + + string.Format( ApplyMeshModificationFunctionSRP[ 7 ], vertexPos ) + + string.Format( ApplyMeshModificationFunctionSRP[ 8 ], vertexPos ) + + ApplyMeshModificationFunctionSRP[ 9 ] + + string.Format( ApplyMeshModificationFunctionSRP[ 10 ], vertexNormal ) + + ApplyMeshModificationFunctionSRP[ 11 ] + + string.Format( ApplyMeshModificationFunctionSRP[ 12 ], vertexNormal ) + + ApplyMeshModificationFunctionSRP[ 13 ] + + ApplyMeshModificationFunctionSRP[ 14 ] + + string.Format( ApplyMeshModificationFunctionSRP[ 15 ], uvCoord ) + + ApplyMeshModificationFunctionSRP[ 16 ] + + string.Format( ApplyMeshModificationFunctionSRP[ 17 ], uvCoord ) + + ApplyMeshModificationFunctionSRP[ 18 ] + + ApplyMeshModificationFunctionSRP[ 19 ] + + string.Format( ApplyMeshModificationFunctionSRP[ 20 ], functionData.InVarName ) + + ApplyMeshModificationFunctionSRP[ 21 ]; + dataCollector.AddFunction( functionHeader, functionBody ); + + for( int i = 0; i < InstancedGlobalsSRP.Length; i++ ) + { + dataCollector.AddToUniforms( -1, InstancedGlobalsSRP[ i ] ); + } + + + string vertexVarName = dataCollector.TemplateDataCollectorInstance.CurrentTemplateData.VertexFunctionData.InVarName; + vertexInstructions.Insert( 0, string.Format( ApplyMeshModificationInstruction, vertexVarName ) ); + } + else + { + TemplateFunctionData functionData = dataCollector.TemplateDataCollectorInstance.CurrentTemplateData.VertexFunctionData; + + string uvCoord = dataCollector.TemplateDataCollectorInstance.GetUV( 0, MasterNodePortCategory.Vertex ); + string vertexNormal = dataCollector.TemplateDataCollectorInstance.GetVertexNormal( PrecisionType.Float, false, MasterNodePortCategory.Vertex ); + string vertexPos = dataCollector.TemplateDataCollectorInstance.GetVertexPosition( WirePortDataType.OBJECT, PrecisionType.Float, false, MasterNodePortCategory.Vertex ); + + string functionHeader = string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 0 ], functionData.InVarType, functionData.InVarName ); + string functionBody = functionHeader + + ApplyMeshModificationFunctionDefaultTemplate[ 1 ] + + ApplyMeshModificationFunctionDefaultTemplate[ 2 ] + + string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 3 ], vertexPos ) + + ApplyMeshModificationFunctionDefaultTemplate[ 4 ] + + ApplyMeshModificationFunctionDefaultTemplate[ 5 ] + + string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 6 ], uvCoord ) + + string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 7 ], uvCoord ) + + string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 8 ], vertexPos ) + + string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 9 ], vertexPos ) + + string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 10 ], vertexNormal, uvCoord ) + + ApplyMeshModificationFunctionDefaultTemplate[ 11 ] + + string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 12 ], functionData.InVarName ) + + ApplyMeshModificationFunctionDefaultTemplate[ 13 ]; + + + dataCollector.AddFunction( functionHeader, functionBody ); + for( int i = 0; i < InstancedGlobalsDefault.Length; i++ ) + { + dataCollector.AddToUniforms( -1, InstancedGlobalsDefault[ i ] ); + } + + + string vertexVarName = dataCollector.TemplateDataCollectorInstance.CurrentTemplateData.VertexFunctionData.InVarName; + vertexInstructions.Insert( 0, string.Format( ApplyMeshModificationInstruction, vertexVarName ) ); + + } + } +#endif + } + + public void UpdateDataCollectorForStandard( ref MasterNodeDataCollector dataCollector ) + { +#if UNITY_2018_1_OR_NEWER + if( m_enable ) + { + for( int i = 0; i < AdditionalUsePasses.Length; i++ ) + { + dataCollector.AddUsePass( AdditionalUsePasses[ i ], false ); + } + + for( int i = 0; i < InstancedPragmas.Length; i++ ) + { + dataCollector.AddToPragmas( -1, InstancedPragmas[ i ] ); + } + string functionBody = string.Empty; + + string functionHeader = string.Format( ApplyMeshModificationFunctionStandard[ 0 ], dataCollector.SurfaceVertexStructure ); + IOUtils.AddFunctionHeader( ref functionBody, functionHeader ); + for( int i = 1; i < ApplyMeshModificationFunctionStandard.Length; i++ ) + { + IOUtils.AddFunctionLine( ref functionBody, ApplyMeshModificationFunctionStandard[ i ] ); + } + IOUtils.CloseFunctionBody( ref functionBody ); + + //string inputName = "input"; + //string uvCoord = "input.texcoord"; + //string vertexNormal = "input.normal"; + //string vertexPos = "input.vertex"; + + //string functionHeader = string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 0 ], dataCollector.SurfaceVertexStructure, inputName ); + //IOUtils.AddFunctionHeader( ref functionBody, functionHeader ); + //IOUtils.AddFunctionLine( ref functionBody, ApplyMeshModificationFunctionDefaultTemplate[ 1 ] ); + //IOUtils.AddFunctionLine( ref functionBody,ApplyMeshModificationFunctionDefaultTemplate[ 2 ] ); + //IOUtils.AddFunctionLine( ref functionBody,string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 3 ], vertexPos ) ); + //IOUtils.AddFunctionLine( ref functionBody,ApplyMeshModificationFunctionDefaultTemplate[ 4 ] ); + //IOUtils.AddFunctionLine( ref functionBody,ApplyMeshModificationFunctionDefaultTemplate[ 5 ] ); + //IOUtils.AddFunctionLine( ref functionBody,string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 6 ], uvCoord ) ); + //IOUtils.AddFunctionLine( ref functionBody,string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 7 ], uvCoord ) ); + //IOUtils.AddFunctionLine( ref functionBody,string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 8 ], vertexPos ) ); + //IOUtils.AddFunctionLine( ref functionBody,string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 9 ], vertexPos ) ); + //IOUtils.AddFunctionLine( ref functionBody,string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 10 ], vertexNormal, uvCoord ) ); + //IOUtils.AddFunctionLine( ref functionBody,ApplyMeshModificationFunctionDefaultTemplate[ 11 ] ); + //IOUtils.AddFunctionLine( ref functionBody,string.Format( ApplyMeshModificationFunctionDefaultTemplate[ 12 ], inputName ) ); + //IOUtils.AddFunctionLine( ref functionBody, ApplyMeshModificationFunctionDefaultTemplate[ 13 ] ); + //IOUtils.CloseFunctionBody( ref functionBody ); + + dataCollector.AddFunction( functionHeader, functionBody ); + for( int i = 0; i < InstancedGlobalsDefault.Length; i++ ) + { + dataCollector.AddToUniforms( -1, InstancedGlobalsDefault[ i ] ); + } + + dataCollector.AddVertexInstruction( string.Format( ApplyMeshModificationInstructionStandard, "v" ) ); + } +#endif + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + m_enable = Convert.ToBoolean( nodeParams[ index++ ] ); + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_enable ); + } + + public bool Enabled { get { return m_enable; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TerrainDrawInstancedHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TerrainDrawInstancedHelper.cs.meta new file mode 100644 index 00000000..9580ad09 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TerrainDrawInstancedHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 935c69709205e1c4dbd54da410518cc6 +timeCreated: 1548263010 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TessellationOpHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TessellationOpHelper.cs new file mode 100644 index 00000000..38d38f09 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TessellationOpHelper.cs @@ -0,0 +1,642 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + public sealed class TessellationOpHelper + { + public const string TessellationPortStr = "Tessellation"; + + + public const string TessSurfParam = "tessellate:tessFunction"; + public const string TessInclude = "Tessellation.cginc"; + //public const string CustomAppData = "\t\tstruct appdata\n" + + // "\t\t{\n" + + // "\t\t\tfloat4 vertex : POSITION;\n" + + // "\t\t\tfloat4 tangent : TANGENT;\n" + + // "\t\t\tfloat3 normal : NORMAL;\n" + + // "\t\t\tfloat4 texcoord : TEXCOORD0;\n" + + // "\t\t\tfloat4 texcoord1 : TEXCOORD1;\n" + + // "\t\t\tfloat4 texcoord2 : TEXCOORD2;\n" + + // "\t\t\tfloat4 texcoord3 : TEXCOORD3;\n" + + // "\t\t\tfixed4 color : COLOR;\n" + + // "\t\t\tUNITY_VERTEX_INPUT_INSTANCE_ID\n" + + // "\t\t};\n\n"; + + + + private const string TessUniformName = "_TessValue"; + private const string TessMinUniformName = "_TessMin"; + private const string TessMaxUniformName = "_TessMax"; + + //private GUIContent EnableTessContent = new GUIContent( "Tessellation", "Activates the use of tessellation which subdivides polygons to increase geometry detail using a set of rules\nDefault: OFF" ); + private GUIContent TessFactorContent = new GUIContent( "Tess", "Tessellation factor\nDefault: 4" ); + private GUIContent TessMinDistanceContent = new GUIContent( "Min", "Minimum tessellation distance\nDefault: 10" ); + private GUIContent TessMaxDistanceContent = new GUIContent( "Max", "Maximum tessellation distance\nDefault: 25" ); + + + private readonly int[] TesselationTypeValues = { 0, 1, 2, 3 }; + private readonly string[] TesselationTypeLabels = { "Distance-based", "Fixed", "Edge Length", "Edge Length Cull" }; + private readonly string TesselationTypeStr = "Type"; + + private const string TessProperty = "_TessValue( \"Max Tessellation\", Range( 1, 32 ) ) = {0}"; + private const string TessMinProperty = "_TessMin( \"Tess Min Distance\", Float ) = {0}"; + private const string TessMaxProperty = "_TessMax( \"Tess Max Distance\", Float ) = {0}"; + + private const string TessFunctionOpen = "\t\tfloat4 tessFunction( appdata_full v0, appdata_full v1, appdata_full v2 )\n\t\t{\n"; + private const string TessFunctionClose = "\t\t}\n"; + + // Custom function + private const string CustomFunctionBody = "\t\t\treturn {0};\n"; + + // Distance based function + private const string DistBasedTessFunctionBody = "\t\t\treturn UnityDistanceBasedTess( v0.vertex, v1.vertex, v2.vertex, _TessMin, _TessMax, _TessValue );\n"; + + // Fixed amount function + private const string FixedAmountTessFunctionOpen = "\t\tfloat4 tessFunction( )\n\t\t{\n"; + private const string FixedAmountTessFunctionBody = "\t\t\treturn _TessValue;\n"; + + // Edge Length + private GUIContent EdgeLengthContent = new GUIContent( "Edge Length", "Tessellation levels ccomputed based on triangle edge length on the screen\nDefault: 4" ); + private const string EdgeLengthTessProperty = "_EdgeLength ( \"Edge length\", Range( 2, 50 ) ) = {0}"; + private const string EdgeLengthTessUniformName = "_EdgeLength"; + + private const string EdgeLengthTessFunctionBody = "\t\t\treturn UnityEdgeLengthBasedTess (v0.vertex, v1.vertex, v2.vertex, _EdgeLength);\n"; + private const string EdgeLengthTessCullFunctionBody = "\t\t\treturn UnityEdgeLengthBasedTessCull (v0.vertex, v1.vertex, v2.vertex, _EdgeLength , _TessMaxDisp );\n"; + + + private const string EdgeLengthTessMaxDispProperty = "_TessMaxDisp( \"Max Displacement\", Float ) = {0}"; + private const string EdgeLengthTessMaxDispUniformName = "_TessMaxDisp"; + private GUIContent EdgeLengthTessMaxDisplacementContent = new GUIContent( "Max Disp.", "Max Displacement" ); + + // Phong + private GUIContent PhongEnableContent = new GUIContent( "Phong", "Modifies positions of the subdivided faces so that the resulting surface follows the mesh normals a bit\nDefault: OFF" ); + private GUIContent PhongStrengthContent = new GUIContent( "Strength", "Strength\nDefault: 0.5" ); + public const string PhongStrengthParam = "tessphong:_TessPhongStrength"; + + private const string PhongStrengthProperty = "_TessPhongStrength( \"Phong Tess Strength\", Range( 0, 1 ) ) = {0}"; + private const string PhongStrengthUniformName = "_TessPhongStrength"; + + [SerializeField] + private bool m_enabled = false; + + //private bool m_expanded = false; + + [SerializeField] + private int m_tessType = 2; + + [SerializeField] + private float m_tessMinDistance = 10f; + + [SerializeField] + private float m_tessMaxDistance = 25f; + + [SerializeField] + private float m_tessFactor = 15f; + + [SerializeField] + private float m_phongStrength = 0.5f; + + [SerializeField] + private bool m_phongEnabled = false; + + [SerializeField] + private string[] m_customData = { string.Empty, string.Empty, string.Empty }; + + [SerializeField] + private bool m_hasCustomFunction = false; + + [SerializeField] + private string m_customFunction = String.Empty; + + [SerializeField] + private string m_additionalData = string.Empty; + + [SerializeField] + private StandardSurfaceOutputNode m_parentSurface; + + private Dictionary<string, bool> m_additionalDataDict = new Dictionary<string, bool>(); + + private int m_masterNodeIndexPort = 0; + private int m_vertexOffsetIndexPort = 0; + //private int m_orderIndex = 1000; + + public void Draw( UndoParentNode owner, GUIStyle toolbarstyle, Material mat, bool connectedInput ) + { + Color cachedColor = GUI.color; + GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, 0.5f ); + EditorGUILayout.BeginHorizontal( toolbarstyle ); + GUI.color = cachedColor; + EditorGUI.BeginChangeCheck(); + m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedTesselation = GUILayout.Toggle( m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedTesselation, " Tessellation", UIUtils.MenuItemToggleStyle, GUILayout.ExpandWidth( true ) ); + if ( EditorGUI.EndChangeCheck() ) + { + EditorPrefs.SetBool( "ExpandedTesselation", m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedTesselation ); + } + + EditorGUI.BeginChangeCheck(); + m_enabled = owner.EditorGUILayoutToggle( string.Empty, m_enabled, UIUtils.MenuItemEnableStyle, GUILayout.Width( 16 ) ); + if ( EditorGUI.EndChangeCheck() ) + { + if ( m_enabled ) + UpdateToMaterial( mat, !connectedInput ); + + UIUtils.RequestSave(); + } + + EditorGUILayout.EndHorizontal(); + + m_enabled = m_enabled || connectedInput; + + if ( m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedTesselation ) + { + cachedColor = GUI.color; + GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, ( EditorGUIUtility.isProSkin ? 0.5f : 0.25f ) ); + EditorGUILayout.BeginVertical( UIUtils.MenuItemBackgroundStyle ); + GUI.color = cachedColor; + + EditorGUILayout.Separator(); + EditorGUI.BeginDisabledGroup( !m_enabled ); + + EditorGUI.indentLevel += 1; + + m_phongEnabled = owner.EditorGUILayoutToggle( PhongEnableContent, m_phongEnabled ); + if ( m_phongEnabled ) + { + EditorGUI.indentLevel += 1; + EditorGUI.BeginChangeCheck(); + m_phongStrength = owner.EditorGUILayoutSlider( PhongStrengthContent, m_phongStrength, 0.0f, 1.0f ); + if ( EditorGUI.EndChangeCheck() && mat != null ) + { + if ( mat.HasProperty( PhongStrengthUniformName ) ) + mat.SetFloat( PhongStrengthUniformName, m_phongStrength ); + } + + EditorGUI.indentLevel -= 1; + } + + bool guiEnabled = GUI.enabled; + GUI.enabled = !connectedInput && m_enabled; + + m_tessType = owner.EditorGUILayoutIntPopup( TesselationTypeStr, m_tessType, TesselationTypeLabels, TesselationTypeValues ); + + switch ( m_tessType ) + { + case 0: + { + EditorGUI.BeginChangeCheck(); + m_tessFactor = owner.EditorGUILayoutSlider( TessFactorContent, m_tessFactor, 1, 32 ); + if ( EditorGUI.EndChangeCheck() && mat != null ) + { + if ( mat.HasProperty( TessUniformName ) ) + mat.SetFloat( TessUniformName, m_tessFactor ); + } + + EditorGUI.BeginChangeCheck(); + m_tessMinDistance = owner.EditorGUILayoutFloatField( TessMinDistanceContent, m_tessMinDistance ); + if ( EditorGUI.EndChangeCheck() && mat != null ) + { + if ( mat.HasProperty( TessMinUniformName ) ) + mat.SetFloat( TessMinUniformName, m_tessMinDistance ); + } + + EditorGUI.BeginChangeCheck(); + m_tessMaxDistance = owner.EditorGUILayoutFloatField( TessMaxDistanceContent, m_tessMaxDistance ); + if ( EditorGUI.EndChangeCheck() && mat != null ) + { + if ( mat.HasProperty( TessMaxUniformName ) ) + mat.SetFloat( TessMaxUniformName, m_tessMaxDistance ); + } + } + break; + case 1: + { + EditorGUI.BeginChangeCheck(); + m_tessFactor = owner.EditorGUILayoutSlider( TessFactorContent, m_tessFactor, 1, 32 ); + if ( EditorGUI.EndChangeCheck() && mat != null ) + { + if ( mat.HasProperty( TessUniformName ) ) + mat.SetFloat( TessUniformName, m_tessFactor ); + } + } + break; + case 2: + { + EditorGUI.BeginChangeCheck(); + m_tessFactor = owner.EditorGUILayoutSlider( EdgeLengthContent, m_tessFactor, 2, 50 ); + if ( EditorGUI.EndChangeCheck() && mat != null ) + { + if ( mat.HasProperty( EdgeLengthTessUniformName ) ) + mat.SetFloat( EdgeLengthTessUniformName, m_tessFactor ); + } + } + break; + case 3: + { + EditorGUI.BeginChangeCheck(); + m_tessFactor = owner.EditorGUILayoutSlider( EdgeLengthContent, m_tessFactor, 2, 50 ); + if ( EditorGUI.EndChangeCheck() && mat != null ) + { + if ( mat.HasProperty( EdgeLengthTessUniformName ) ) + mat.SetFloat( EdgeLengthTessUniformName, m_tessFactor ); + } + + EditorGUI.BeginChangeCheck(); + m_tessMaxDistance = owner.EditorGUILayoutFloatField( EdgeLengthTessMaxDisplacementContent, m_tessMaxDistance ); + if ( EditorGUI.EndChangeCheck() && mat != null ) + { + if ( mat.HasProperty( TessMinUniformName ) ) + mat.SetFloat( TessMinUniformName, m_tessMaxDistance ); + } + } + break; + } + GUI.enabled = guiEnabled; + EditorGUI.indentLevel -= 1; + EditorGUI.EndDisabledGroup(); + EditorGUILayout.Separator(); + EditorGUILayout.EndVertical(); + } + } + + public void UpdateToMaterial( Material mat, bool updateInternals ) + { + if ( mat == null ) + return; + + if ( m_phongEnabled ) + { + if ( mat.HasProperty( PhongStrengthUniformName ) ) + mat.SetFloat( PhongStrengthUniformName, m_phongStrength ); + } + + if ( updateInternals ) + { + switch ( m_tessType ) + { + case 0: + { + if ( mat.HasProperty( TessUniformName ) ) + mat.SetFloat( TessUniformName, m_tessFactor ); + + if ( mat.HasProperty( TessMinUniformName ) ) + mat.SetFloat( TessMinUniformName, m_tessMinDistance ); + + if ( mat.HasProperty( TessMaxUniformName ) ) + mat.SetFloat( TessMaxUniformName, m_tessMaxDistance ); + } + break; + case 1: + { + if ( mat.HasProperty( TessUniformName ) ) + mat.SetFloat( TessUniformName, m_tessFactor ); + } + break; + case 2: + { + + if ( mat.HasProperty( EdgeLengthTessUniformName ) ) + mat.SetFloat( EdgeLengthTessUniformName, m_tessFactor ); + } + break; + case 3: + { + if ( mat.HasProperty( EdgeLengthTessUniformName ) ) + mat.SetFloat( EdgeLengthTessUniformName, m_tessFactor ); + + if ( mat.HasProperty( TessMinUniformName ) ) + mat.SetFloat( TessMinUniformName, m_tessMaxDistance ); + } + break; + } + } + } + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + m_enabled = Convert.ToBoolean( nodeParams[ index++ ] ); + m_tessType = Convert.ToInt32( nodeParams[ index++ ] ); + m_tessFactor = Convert.ToSingle( nodeParams[ index++ ] ); + m_tessMinDistance = Convert.ToSingle( nodeParams[ index++ ] ); + m_tessMaxDistance = Convert.ToSingle( nodeParams[ index++ ] ); + if ( UIUtils.CurrentShaderVersion() > 3001 ) + { + m_phongEnabled = Convert.ToBoolean( nodeParams[ index++ ] ); + m_phongStrength = Convert.ToSingle( nodeParams[ index++ ] ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_enabled ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_tessType ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_tessFactor ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_tessMinDistance ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_tessMaxDistance ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_phongEnabled ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_phongStrength ); + } + + public string Uniforms() + { + string uniforms = string.Empty; + switch( m_tessType ) + { + case 0: + { + if( !m_hasCustomFunction ) + { + + //Tess + uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessUniformName + ";\n"; + + //Min + uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessMinUniformName + ";\n"; + + //Max + uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessMaxUniformName + ";\n"; + } + } + break; + case 1: + //Tess + if( !m_hasCustomFunction ) + { + uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessUniformName + ";\n"; + } + break; + } + + if( m_phongEnabled ) + { + uniforms += "\t\tuniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + PhongStrengthUniformName + ";\n" ; + } + + return uniforms; + } + + public void AddToDataCollector( ref MasterNodeDataCollector dataCollector, int reorder ) + { + int orderIndex = reorder; + switch ( m_tessType ) + { + case 0: + { + dataCollector.AddToIncludes( -1, TessellationOpHelper.TessInclude ); + if ( !m_hasCustomFunction ) + { + //Tess + dataCollector.AddToProperties( -1, string.Format( TessProperty, m_tessFactor ), orderIndex++ ); + dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessUniformName + ";" ); + + //Min + dataCollector.AddToProperties( -1, string.Format( TessMinProperty, m_tessMinDistance ), orderIndex++ ); + dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessMinUniformName + ";" ); + + //Max + dataCollector.AddToProperties( -1, string.Format( TessMaxProperty, m_tessMaxDistance ), orderIndex++ ); + dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessMaxUniformName + ";" ); + } + } + break; + case 1: + { + //Tess + if ( !m_hasCustomFunction ) + { + dataCollector.AddToProperties( -1, string.Format( TessProperty, m_tessFactor ), orderIndex++ ); + dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + TessUniformName + ";" ); + } + } + break; + case 2: + { + dataCollector.AddToIncludes( -1, TessellationOpHelper.TessInclude ); + + //Tess + if ( !m_hasCustomFunction ) + { + dataCollector.AddToProperties( -1, string.Format( EdgeLengthTessProperty, m_tessFactor ), orderIndex++ ); + dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + EdgeLengthTessUniformName + ";" ); + } + } + break; + case 3: + { + dataCollector.AddToIncludes( -1, TessellationOpHelper.TessInclude ); + + if ( !m_hasCustomFunction ) + { + //Tess + dataCollector.AddToProperties( -1, string.Format( EdgeLengthTessProperty, m_tessFactor ), orderIndex++ ); + dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + EdgeLengthTessUniformName + ";" ); + + //Max Displacement + dataCollector.AddToProperties( -1, string.Format( EdgeLengthTessMaxDispProperty, m_tessMaxDistance ), orderIndex++ ); + dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + EdgeLengthTessMaxDispUniformName + ";" ); + } + } + break; + } + + if ( m_phongEnabled ) + { + dataCollector.AddToProperties( -1, string.Format( PhongStrengthProperty, m_phongStrength ), orderIndex++ ); + dataCollector.AddToUniforms( -1, "uniform " + UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT ) + " " + PhongStrengthUniformName + ";" ); + } + } + + //ToDo: Optimize material property fetches to use Id instead of string + public void UpdateFromMaterial( Material mat ) + { + if ( m_enabled ) + { + if ( m_phongEnabled ) + { + if ( mat.HasProperty( PhongStrengthUniformName ) ) + m_phongStrength = mat.GetFloat( PhongStrengthUniformName ); + } + + switch ( m_tessType ) + { + case 0: + { + if ( mat.HasProperty( TessUniformName ) ) + m_tessFactor = mat.GetFloat( TessUniformName ); + + if ( mat.HasProperty( TessMinUniformName ) ) + m_tessMinDistance = mat.GetFloat( TessMinUniformName ); + + if ( mat.HasProperty( TessMaxUniformName ) ) + m_tessMaxDistance = mat.GetFloat( TessMaxUniformName ); + } + break; + case 1: + { + if ( mat.HasProperty( TessUniformName ) ) + m_tessFactor = mat.GetFloat( TessUniformName ); + } + break; + case 2: + { + if ( mat.HasProperty( EdgeLengthTessUniformName ) ) + m_tessFactor = mat.GetFloat( EdgeLengthTessUniformName ); + } + break; + case 3: + { + if ( mat.HasProperty( EdgeLengthTessUniformName ) ) + m_tessFactor = mat.GetFloat( EdgeLengthTessUniformName ); + + if ( mat.HasProperty( EdgeLengthTessMaxDispUniformName ) ) + m_tessMaxDistance = mat.GetFloat( EdgeLengthTessMaxDispUniformName ); + } + break; + } + } + } + + public void WriteToOptionalParams( ref string optionalParams ) + { + optionalParams += TessellationOpHelper.TessSurfParam + Constants.OptionalParametersSep; + if ( m_phongEnabled ) + { + optionalParams += TessellationOpHelper.PhongStrengthParam + Constants.OptionalParametersSep; + } + } + + public void Reset() + { + m_hasCustomFunction = false; + m_customFunction = string.Empty; + + m_additionalData = string.Empty; + m_additionalDataDict.Clear(); + switch ( m_tessType ) + { + case 0: + { + m_customData[ 0 ] = TessUniformName; + m_customData[ 1 ] = TessMinUniformName; + m_customData[ 2 ] = TessMaxUniformName; + } + break; + case 1: + { + m_customData[ 0 ] = TessUniformName; + m_customData[ 1 ] = string.Empty; + m_customData[ 2 ] = string.Empty; + } + break; + case 2: + { + m_customData[ 0 ] = EdgeLengthTessUniformName; + m_customData[ 1 ] = string.Empty; + m_customData[ 2 ] = string.Empty; + } + break; + case 3: + { + m_customData[ 0 ] = EdgeLengthTessUniformName; + m_customData[ 1 ] = EdgeLengthTessMaxDispUniformName; + m_customData[ 2 ] = string.Empty; + } + break; + } + } + + public string GetCurrentTessellationFunction + { + get + { + if ( m_hasCustomFunction ) + { + return TessFunctionOpen + + m_customFunction + + TessFunctionClose; + } + + string tessFunction = string.Empty; + switch ( m_tessType ) + { + case 0: + { + tessFunction = TessFunctionOpen + + DistBasedTessFunctionBody + + TessFunctionClose; + } + break; + case 1: + { + tessFunction = FixedAmountTessFunctionOpen + + FixedAmountTessFunctionBody + + TessFunctionClose; + } + break; + case 2: + { + tessFunction = TessFunctionOpen + + EdgeLengthTessFunctionBody + + TessFunctionClose; + } + break; + case 3: + { + tessFunction = TessFunctionOpen + + EdgeLengthTessCullFunctionBody + + TessFunctionClose; + } + break; + } + return tessFunction; + } + } + + public void AddAdditionalData( string data ) + { + if ( !m_additionalDataDict.ContainsKey( data ) ) + { + m_additionalDataDict.Add( data, true ); + m_additionalData += data; + } + } + + public void AddCustomFunction( string returnData ) + { + m_hasCustomFunction = true; + m_customFunction = m_additionalData + string.Format( CustomFunctionBody, returnData ); + } + + public void Destroy() + { + m_additionalDataDict.Clear(); + m_additionalDataDict = null; + } + + public bool IsTessellationPort( int index ) + { + return index == m_masterNodeIndexPort; + } + + public bool EnableTesselation { get { return m_enabled; } } + + public int TessType { get { return m_tessType; } } + public int MasterNodeIndexPort + { + get { return m_masterNodeIndexPort; } + set { m_masterNodeIndexPort = value; } + } + public int VertexOffsetIndexPort + { + get { return m_vertexOffsetIndexPort; } + set { m_vertexOffsetIndexPort = value; } + } + + public StandardSurfaceOutputNode ParentSurface { get { return m_parentSurface; } set { m_parentSurface = value; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TessellationOpHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TessellationOpHelper.cs.meta new file mode 100644 index 00000000..c4400a8a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TessellationOpHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c6fbad94b0fc6b948be3a3dc61232c05 +timeCreated: 1481126959 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/UsePassHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/UsePassHelper.cs new file mode 100644 index 00000000..d6e34adf --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/UsePassHelper.cs @@ -0,0 +1,360 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEditorInternal; + +namespace AmplifyShaderEditor +{ + public enum UsePassLocation + { + Above, + Below + } + + [Serializable] + public class UsePassItem : ScriptableObject + { + public UsePassLocation Location; + public string Value; + public UsePassItem() + { + Location = UsePassLocation.Above; + Value = string.Empty; + } + + public UsePassItem( UsePassLocation location, string name ) + { + Location = location; + Value = name; + } + + } + + [Serializable] + public class UsePassHelper : ScriptableObject + { + private const string UseGrabFormatNewLine = "UsePass \"{0}\"\n"; + private const string UseGrabFormat = "UsePass \"{0}\""; + private const float ShaderKeywordButtonLayoutWidth = 15; + private const string ShaderPoputContext = "CONTEXT/ShaderPopup"; + + [SerializeField] + private List<UsePassItem> m_items = new List<UsePassItem>(); + + [SerializeField] + private UndoParentNode m_owner = null; + + [SerializeField] + protected bool m_isDirty = false; + + [SerializeField] + protected string m_moduleName = string.Empty; + + private ReorderableList m_reordableList = null; + private ReordableAction m_actionType = ReordableAction.None; + private int m_actionIndex = 0; + private GUIStyle m_propertyAdjustment; + + private Material m_dummyMaterial; + private MenuCommand m_dummyCommand; + private int m_currentUsePassIdx = 0; + + public void Init( string moduleName ) + { + hideFlags = HideFlags.HideAndDontSave; + m_moduleName = moduleName; + } + + void DrawButtons() + { + EditorGUILayout.Separator(); + + // Add keyword + if( GUILayout.Button( string.Empty, UIUtils.PlusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + UsePassItem newItem = ScriptableObject.CreateInstance<UsePassItem>(); + newItem.hideFlags = HideFlags.HideAndDontSave; + m_items.Add( newItem ); + EditorGUI.FocusTextInControl( null ); + m_isDirty = true; + } + + //Remove keyword + if( GUILayout.Button( string.Empty, UIUtils.MinusStyle, GUILayout.Width( ShaderKeywordButtonLayoutWidth ) ) ) + { + if( m_items.Count > 0 ) + { + UsePassItem itemToDelete = m_items[ m_items.Count - 1 ]; + m_items.RemoveAt( m_items.Count - 1 ); + ScriptableObject.DestroyImmediate( itemToDelete ); + EditorGUI.FocusTextInControl( null ); + } + m_isDirty = true; + } + } + + public void Draw( UndoParentNode owner, bool style = true ) + { + if( m_owner == null ) + m_owner = owner; + + if( m_reordableList == null ) + { + m_reordableList = new ReorderableList( m_items, typeof( UsePassItem ), true, false, false, false ) + { + headerHeight = 0, + footerHeight = 0, + showDefaultBackground = false, + drawElementCallback = ( Rect rect, int index, bool isActive, bool isFocused ) => + { + if( m_items[ index ] != null ) + { + float labelWidthMultiplier; + float popUpWidth; + float shaderSelectorMultiplier; + float buttonPlusPosMultiplier; + if( style ) + { + rect.x -= 10; + labelWidthMultiplier = 0.9f; + popUpWidth = 0.31f; + shaderSelectorMultiplier = 1.01f; + buttonPlusPosMultiplier = 0.78f; + } + else + { + rect.x -= 1; + labelWidthMultiplier = 1.01f; + popUpWidth = 0.25f; + shaderSelectorMultiplier = 1.0f; + buttonPlusPosMultiplier = 0.55f; + } + + Rect popupPos = new Rect( rect.x, rect.y + 2, popUpWidth * rect.width, rect.height ); + Rect labelPos = new Rect( rect.x + popupPos.width * labelWidthMultiplier, rect.y, 0.59f * rect.width, rect.height ); + + Rect shaderSelectorPos = new Rect( labelPos.x + labelPos.width* shaderSelectorMultiplier, rect.y, 15, rect.height ); + + Rect buttonPlusPos = new Rect( shaderSelectorPos.x + shaderSelectorPos.width * buttonPlusPosMultiplier, rect.y, ShaderKeywordButtonLayoutWidth, rect.height ); + Rect buttonMinusPos = new Rect( buttonPlusPos.x + buttonPlusPos.width, rect.y, ShaderKeywordButtonLayoutWidth, rect.height ); + + EditorGUI.BeginChangeCheck(); + m_items[ index ].Location = (UsePassLocation)owner.EditorGUIEnumPopup( popupPos, m_items[ index ].Location ); + + if( EditorGUI.EndChangeCheck() && m_items[ index ].Location == UsePassLocation.Below && m_owner != null && m_owner.ContainerGraph.CurrentCanvasMode == NodeAvailability.TemplateShader ) + { + m_items[ index ].Location = UsePassLocation.Above; + UIUtils.ShowMessage( "Below option still not available on templates" ); + } + m_items[ index ].Value = owner.EditorGUITextField( labelPos, string.Empty, m_items[ index ].Value ); + + if( GUI.Button( shaderSelectorPos, string.Empty, UIUtils.InspectorPopdropdownFallback ) ) + { + EditorGUI.FocusTextInControl( null ); + GUI.FocusControl( null ); + m_currentUsePassIdx = index; + DisplayShaderContext( owner, GUILayoutUtility.GetRect( GUIContent.none, EditorStyles.popup ) ); + } + + if( GUI.Button( buttonPlusPos, string.Empty, UIUtils.PlusStyle ) ) + { + m_actionType = ReordableAction.Add; + m_actionIndex = index; + } + + if( GUI.Button( buttonMinusPos, string.Empty, UIUtils.MinusStyle ) ) + { + m_actionType = ReordableAction.Remove; + m_actionIndex = index; + } + } + } + }; + } + + if( m_actionType != ReordableAction.None ) + { + switch( m_actionType ) + { + case ReordableAction.Add: + UsePassItem newItem = ScriptableObject.CreateInstance<UsePassItem>(); + newItem.hideFlags = HideFlags.HideAndDontSave; + m_items.Insert( m_actionIndex + 1, newItem ); + break; + case ReordableAction.Remove: + UsePassItem itemToDelete = m_items[ m_actionIndex ]; + m_items.RemoveAt( m_actionIndex ); + ScriptableObject.DestroyImmediate( itemToDelete ); + break; + } + m_isDirty = true; + m_actionType = ReordableAction.None; + EditorGUI.FocusTextInControl( null ); + } + bool foldoutValue = owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedUsePass; + if( style ) + { + NodeUtils.DrawPropertyGroup( ref foldoutValue, m_moduleName, DrawReordableList, DrawButtons ); + } + else + { + NodeUtils.DrawNestedPropertyGroup( ref foldoutValue, m_moduleName, DrawReordableList, DrawButtons ); + } + owner.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedUsePass = foldoutValue; + } + + private void DisplayShaderContext( UndoParentNode node, Rect r ) + { + if( m_dummyCommand == null ) + m_dummyCommand = new MenuCommand( this, 0 ); + + if( m_dummyMaterial == null ) + m_dummyMaterial = new Material( Shader.Find( "Hidden/ASESShaderSelectorUnlit" ) ); + +#pragma warning disable 0618 + UnityEditorInternal.InternalEditorUtility.SetupShaderMenu( m_dummyMaterial ); +#pragma warning restore 0618 + EditorUtility.DisplayPopupMenu( r, ShaderPoputContext, m_dummyCommand ); + } + + private void OnSelectedShaderPopup( string command, Shader shader ) + { + if( shader != null ) + { + UIUtils.MarkUndoAction(); + Undo.RecordObject( m_owner, "Selected Use Pass shader" ); + m_items[ m_currentUsePassIdx ].Value = shader.name; + } + } + + void DrawReordableList() + { + if( m_reordableList != null ) + { + if( m_propertyAdjustment == null ) + { + m_propertyAdjustment = new GUIStyle(); + m_propertyAdjustment.padding.left = 17; + } + EditorGUILayout.Space(); + + if( m_items.Count == 0 ) + { + EditorGUILayout.HelpBox( "Your list is Empty!\nUse the plus button to add one.", MessageType.Info ); + } + else + { + m_reordableList.DoLayoutList(); + } + EditorGUILayout.Space(); + } + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + try + { + int count = Convert.ToInt32( nodeParams[ index++ ] ); + for( int i = 0; i < count; i++ ) + { + string locationValue = nodeParams[ index++ ]; + // REMOVE THIS TEST AFTER A COUPLE OF VERSIONS (curr v1.5.6 r02) + if( locationValue.Equals( "Bellow" ) ) locationValue = "Below"; + + UsePassLocation location = (UsePassLocation)Enum.Parse( typeof( UsePassLocation ), locationValue ); + string name = nodeParams[ index++ ]; + UsePassItem newItem = ScriptableObject.CreateInstance<UsePassItem>(); + newItem.hideFlags = HideFlags.HideAndDontSave; + newItem.Location = location; + newItem.Value = name; + m_items.Add( newItem ); + } + } + catch( Exception e ) + { + Debug.LogException( e ); + } + } + + public void WriteToString( ref string nodeInfo ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_items.Count ); + for( int i = 0; i < m_items.Count; i++ ) + { + IOUtils.AddFieldValueToString( ref nodeInfo, m_items[ i ].Location ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_items[ i ].Value ); + } + } + + public void BuildUsePassInfo( MasterNodeDataCollector dataCollector, ref string aboveItems, ref string bellowItems, string tabs) + { + int count = 0; + count = dataCollector.AboveUsePassesList.Count; + for( int i = 0; i < count; i++ ) + { + aboveItems += tabs + string.Format( UseGrabFormatNewLine, dataCollector.AboveUsePassesList[ i ].PropertyName ); + } + + count = dataCollector.BelowUsePassesList.Count; + for( int i = 0; i < count; i++ ) + { + bellowItems += tabs + string.Format( UseGrabFormatNewLine, dataCollector.BelowUsePassesList[ i ].PropertyName ); + } + + count = m_items.Count; + for( int i = 0; i < count; i++ ) + { + if( m_items[ i ].Location == UsePassLocation.Above ) + { + aboveItems += tabs + string.Format( UseGrabFormatNewLine, m_items[ i ].Value ); + } + else + { + bellowItems += tabs + string.Format( UseGrabFormatNewLine, m_items[ i ].Value ); + } + } + } + + public void BuildUsePassInfo( MasterNodeDataCollector dataCollector, ref List<PropertyDataCollector> aboveItems, ref List<PropertyDataCollector> bellowItems ) + { + int count = 0; + count = dataCollector.AboveUsePassesList.Count; + for( int i = 0; i < count; i++ ) + { + aboveItems.Add( new PropertyDataCollector( -1, string.Format( UseGrabFormat, dataCollector.AboveUsePassesList[ i ].PropertyName ) ) ); + } + + count = dataCollector.BelowUsePassesList.Count; + for( int i = 0; i < count; i++ ) + { + bellowItems.Add( new PropertyDataCollector( -1, string.Format( UseGrabFormat, dataCollector.BelowUsePassesList[ i ].PropertyName ) ) ); + } + + + count = m_items.Count; + for( int i = 0; i < count; i++ ) + { + if( m_items[ i ].Location == UsePassLocation.Above ) + { + aboveItems.Add( new PropertyDataCollector(-1,string.Format( UseGrabFormat, m_items[ i ].Value ))); + } + else + { + bellowItems.Add( new PropertyDataCollector( -1, string.Format( UseGrabFormat, m_items[ i ].Value ) ) ); + } + } + } + + //public string ModuleName { set { m_moduleName = value; } } + public void Destroy() + { + m_owner = null; + m_items.Clear(); + m_items = null; + m_reordableList = null; + m_dummyMaterial = null; + m_dummyCommand = null; + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/UsePassHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/UsePassHelper.cs.meta new file mode 100644 index 00000000..ddf906c5 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/UsePassHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d818a147712609646b8d6f0f7c2ae731 +timeCreated: 1530179906 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ZBufferOpHelper.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ZBufferOpHelper.cs new file mode 100644 index 00000000..d09b8c04 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ZBufferOpHelper.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + public enum ZWriteMode + { + On, + Off + } + + public enum ZTestMode + { + Less, + Greater, + LEqual, + GEqual, + Equal, + NotEqual, + Always + } + + [Serializable] + class ZBufferOpHelper + { + public static readonly string DepthParametersStr = " Depth"; + public static readonly string ZWriteModeStr = "ZWrite Mode"; + public static readonly string ZTestModeStr = "ZTest Mode"; + public static readonly string OffsetStr = "Offset"; + public static readonly string OffsetFactorStr = "Factor"; + public static readonly string OffsetUnitsStr = "Units"; + private const string ExtraDepthPassStr = "Extra Depth Pass"; + private const string DepthZTestStr = "Depth ZTest"; + + public static readonly string[] ZTestModeLabels = + { + "<Default>", + "Less", + "Greater", + "Less or Equal", + "Greater or Equal", + "Equal", + "Not Equal", + "Always" + }; + + public static readonly string[] ZTestModeValues = + { + "<Default>", + "Less", + "Greater", + "LEqual", + "GEqual", + "Equal", + "NotEqual", + "Always" + }; + + public static readonly string[] ZWriteModeValues = + { + "<Default>", + "On", + "Off" + }; + + public static readonly Dictionary<ZTestMode, int> ZTestModeDict = new Dictionary<ZTestMode, int> + { + {ZTestMode.Less,1 }, + {ZTestMode.Greater,2}, + {ZTestMode.LEqual,3}, + {ZTestMode.GEqual,4}, + {ZTestMode.Equal,5}, + {ZTestMode.NotEqual,6}, + {ZTestMode.Always,7} + }; + + public static readonly Dictionary<ZWriteMode, int> ZWriteModeDict = new Dictionary<ZWriteMode, int> + { + { ZWriteMode.On,1}, + { ZWriteMode.Off,2} + }; + + + [SerializeField] + private InlineProperty m_zTestMode = new InlineProperty(); + + [SerializeField] + private InlineProperty m_zWriteMode = new InlineProperty(); + [SerializeField] + private InlineProperty m_offsetFactor = new InlineProperty(); + + [SerializeField] + private InlineProperty m_offsetUnits = new InlineProperty(); + + [SerializeField] + private bool m_offsetEnabled; + + [SerializeField] + private bool m_extraDepthPass; + + [SerializeField] + private int m_extrazTestMode = 0; + + [SerializeField] + private StandardSurfaceOutputNode m_parentSurface; + + public string CreateDepthInfo( bool outlineZWrite, bool outlineZTest ) + { + string result = string.Empty; + if( m_zWriteMode.IntValue != 0 || m_zWriteMode.Active ) + { + MasterNode.AddRenderState( ref result, "ZWrite", m_zWriteMode.GetValueOrProperty( ZWriteModeValues[ m_zWriteMode.IntValue ] ) ); + } + else if( outlineZWrite ) + { + MasterNode.AddRenderState( ref result, "ZWrite", ZWriteModeValues[ 1 ] ); + } + + if( m_zTestMode.IntValue != 0 || m_zTestMode.Active ) + { + MasterNode.AddRenderState( ref result, "ZTest", m_zTestMode.GetValueOrProperty( ZTestModeValues[ m_zTestMode.IntValue ] ) ); + } + else if( outlineZTest ) + { + MasterNode.AddRenderState( ref result, "ZTest", ZTestModeValues[ 3 ] ); + } + + if( m_offsetEnabled ) + { + MasterNode.AddRenderState( ref result, "Offset ", m_offsetFactor.GetValueOrProperty() + " , " + m_offsetUnits.GetValueOrProperty() ); + } + + return result; + } + + public void Draw( UndoParentNode owner, GUIStyle toolbarstyle, bool customBlendAvailable ) + { + Color cachedColor = GUI.color; + GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, 0.5f ); + EditorGUILayout.BeginHorizontal( toolbarstyle ); + GUI.color = cachedColor; + EditorGUI.BeginChangeCheck(); + m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedDepth = owner.GUILayoutToggle( m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedDepth, DepthParametersStr, UIUtils.MenuItemToggleStyle ); + if( EditorGUI.EndChangeCheck() ) + { + EditorPrefs.SetBool( "ExpandedDepth", m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedDepth ); + } + EditorGUILayout.EndHorizontal(); + + if( m_parentSurface.ContainerGraph.ParentWindow.InnerWindowVariables.ExpandedDepth ) + { + cachedColor = GUI.color; + GUI.color = new Color( cachedColor.r, cachedColor.g, cachedColor.b, ( EditorGUIUtility.isProSkin ? 0.5f : 0.25f ) ); + EditorGUILayout.BeginVertical( UIUtils.MenuItemBackgroundStyle ); + GUI.color = cachedColor; + + EditorGUI.indentLevel++; + if( !customBlendAvailable ) + EditorGUILayout.HelpBox( "Depth Writing is only available for Opaque or Custom blend modes", MessageType.Warning ); + + EditorGUILayout.Separator(); + EditorGUI.BeginDisabledGroup( !customBlendAvailable ); + + m_zWriteMode.EnumTypePopup( ref owner, ZWriteModeStr, ZWriteModeValues ); + m_zTestMode.EnumTypePopup( ref owner, ZTestModeStr, ZTestModeLabels ); + //m_zWriteMode = owner.EditorGUILayoutPopup( ZWriteModeStr, m_zWriteMode, ZWriteModeValues ); + //m_zTestMode = owner.EditorGUILayoutPopup( ZTestModeStr, m_zTestMode, ZTestModeLabels ); + m_offsetEnabled = owner.EditorGUILayoutToggle( OffsetStr, m_offsetEnabled ); + if( m_offsetEnabled ) + { + EditorGUI.indentLevel++; + m_offsetFactor.FloatField( ref owner , OffsetFactorStr ); + m_offsetUnits.FloatField( ref owner , OffsetUnitsStr ); + EditorGUI.indentLevel--; + } + + m_extraDepthPass = owner.EditorGUILayoutToggle( ExtraDepthPassStr, m_extraDepthPass ); + if( m_extraDepthPass ) + { + EditorGUI.indentLevel++; + m_extrazTestMode = owner.EditorGUILayoutPopup( DepthZTestStr, m_extrazTestMode, ZTestModeLabels ); + EditorGUI.indentLevel--; + } + EditorGUILayout.Separator(); + EditorGUI.indentLevel--; + EditorGUI.EndDisabledGroup(); + EditorGUILayout.EndVertical(); + } + + EditorGUI.EndDisabledGroup(); + } + + public void DrawExtraDepthPass( ref string shaderBody ) + { + if( m_extraDepthPass ) + { + shaderBody += "\t\tPass\n"; + shaderBody += "\t\t{\n"; + shaderBody += "\t\t\tColorMask 0\n"; + if( m_extrazTestMode != 0 ) + shaderBody += "\t\t\tZTest " + ZTestModeValues[ m_extrazTestMode ] + "\n"; + shaderBody += "\t\t\tZWrite On\n"; + shaderBody += "\t\t}\n\n"; + } + } + + public void ReadFromString( ref uint index, ref string[] nodeParams ) + { + if( UIUtils.CurrentShaderVersion() < 2502 ) + { + string zWriteMode = nodeParams[ index++ ]; + m_zWriteMode.IntValue = zWriteMode.Equals( "Off" ) ? 2 : 0; + + string zTestMode = nodeParams[ index++ ]; + for( int i = 0; i < ZTestModeValues.Length; i++ ) + { + if( zTestMode.Equals( ZTestModeValues[ i ] ) ) + { + m_zTestMode.IntValue = i; + break; + } + } + } + else + { + if( UIUtils.CurrentShaderVersion() > 14501 ) + { + m_zWriteMode.ReadFromString( ref index, ref nodeParams ); + m_zTestMode.ReadFromString( ref index, ref nodeParams ); + } + else + { + m_zWriteMode.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + m_zTestMode.IntValue = Convert.ToInt32( nodeParams[ index++ ] ); + } + m_offsetEnabled = Convert.ToBoolean( nodeParams[ index++ ] ); + + if( UIUtils.CurrentShaderVersion() > 15303 ) + { + m_offsetFactor.ReadFromString( ref index, ref nodeParams ); + m_offsetUnits.ReadFromString( ref index, ref nodeParams ); + } + else + { + m_offsetFactor.FloatValue = Convert.ToSingle( nodeParams[ index++ ] ); + m_offsetUnits.FloatValue = Convert.ToSingle( nodeParams[ index++ ] ); + } + + if( UIUtils.CurrentShaderVersion() > 14202 ) + { + m_extraDepthPass = Convert.ToBoolean( nodeParams[ index++ ] ); + m_extrazTestMode = Convert.ToInt32( nodeParams[ index++ ] ); + } + } + } + + public void WriteToString( ref string nodeInfo ) + { + m_zWriteMode.WriteToString( ref nodeInfo ); + m_zTestMode.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_offsetEnabled ); + m_offsetFactor.WriteToString( ref nodeInfo ); + m_offsetUnits.WriteToString( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_extraDepthPass ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_extrazTestMode ); + } + public bool IsActive { get { return m_zTestMode.IntValue != 0 || m_zWriteMode.IntValue != 0 || m_offsetEnabled || m_zTestMode.Active || m_zWriteMode.Active; } } + public StandardSurfaceOutputNode ParentSurface { get { return m_parentSurface; } set { m_parentSurface = value; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ZBufferOpHelper.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ZBufferOpHelper.cs.meta new file mode 100644 index 00000000..edee7bf1 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ZBufferOpHelper.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f35a3e26a28596b4f9b54a1f2689db06 +timeCreated: 1481126960 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |