summaryrefslogtreecommitdiff
path: root/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2020-10-23 13:08:43 +0800
committerchai <chaifix@163.com>2020-10-23 13:08:43 +0800
commitb82da95b5181ac8bbae38efb13e950d5e88a4caa (patch)
tree48a6f3269276484bbc7cfc95f0651f40a2176aa1 /Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master
parent917e9e0b320775634dc2e710f7deac74fd0822f0 (diff)
*移动amplify shader editor到third party目录
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master')
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalDefinesHelper.cs140
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalDefinesHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalIncludesHelper.cs154
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalIncludesHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalPragmasHelper.cs141
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalPragmasHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalSurfaceOptionsHelper.cs153
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/AdditionalSurfaceOptionsHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BillboardOpHelper.cs242
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BillboardOpHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BlendOpsHelper.cs447
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/BlendOpsHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CodeGenerationData.cs24
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CodeGenerationData.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ColorMaskHelper.cs107
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ColorMaskHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CustomTagsHelper.cs436
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/CustomTagsHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/DependenciesHelper.cs210
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/DependenciesHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FallbackPickerHelper.cs119
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FallbackPickerHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionInput.cs523
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionInput.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionNode.cs1236
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionOutput.cs318
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionOutput.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSubtitle.cs124
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSubtitle.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitch.cs867
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitch.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitchByPipeline.cs102
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/FunctionSwitchByPipeline.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/LogNode.cs80
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/LogNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs979
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNodeDataCollector.cs2038
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNodeDataCollector.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutlineOpHelper.cs629
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutlineOpHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutputNode.cs90
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/OutputNode.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingOptionsOpHelper.cs227
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingOptionsOpHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingPlatformsOpHelper.cs238
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/RenderingPlatformsOpHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StandardSurface.cs3302
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StandardSurface.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StencilBufferOpHelper.cs304
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/StencilBufferOpHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TerrainDrawInstancedHelper.cs374
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TerrainDrawInstancedHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TessellationOpHelper.cs642
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/TessellationOpHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/UsePassHelper.cs360
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/UsePassHelper.cs.meta12
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ZBufferOpHelper.cs272
-rw-r--r--Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/ZBufferOpHelper.cs.meta12
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: