You've already forked FateViewer
Add project files.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0801a5994efb46142ad8dcc0fe3c47f8
|
||||
timeCreated: 1513252939
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74ff3d342e013f64198aaf767e623962
|
||||
timeCreated: 1498123240
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3153b4d10effd174988d75b84b12d281
|
||||
timeCreated: 1504515475
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d830b2cc8bc5e174485077319135fc1e
|
||||
timeCreated: 1528881842
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,249 @@
|
||||
// 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 )",
|
||||
//Had to comment this one out in HDRP since it was moving the vertices to incorrect locations
|
||||
// Over HDRP the correct results are achievied without having to do this operation
|
||||
//This is because the vertex position variable is a float3 and an implicit cast is done to float4
|
||||
//with w set to 0, this makes the multiplication below only affects rotation and not translation
|
||||
//thus no adding the world translation is needed to counter the GetObjectToWorldMatrix() operation
|
||||
"//{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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 837b906a268babc49ac733573c5b3394
|
||||
timeCreated: 1489159407
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 ); } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b59649a5f829e24cb4de8c1a715f8b4
|
||||
timeCreated: 1485530925
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a47d8101acb2e94d95016b69a1c2e41
|
||||
timeCreated: 1481126957
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf65efd881afd1b4cbd2b27f3f17251b
|
||||
timeCreated: 1488903773
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,482 @@
|
||||
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 DisableBatching m_disableBatching = DisableBatching.False;
|
||||
[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_disableBatching = DisableBatching.False;
|
||||
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_disableBatching = other.m_disableBatching;
|
||||
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;
|
||||
case TemplateSpecialTags.DisableBatching:
|
||||
{
|
||||
if( !TemplateHelperFunctions.StringToDisableBatching.TryGetValue( value[ 0 ], out m_disableBatching ) )
|
||||
{
|
||||
m_disableBatching = DisableBatching.False;
|
||||
TagValue = value[ 0 ];
|
||||
}
|
||||
}
|
||||
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 if( TagName.Equals( Constants.DisableBatchingHelperStr ) )
|
||||
{
|
||||
m_specialTag = TemplateSpecialTags.DisableBatching;
|
||||
if( !TemplateHelperFunctions.StringToDisableBatching.TryGetValue( TagValue, out m_disableBatching ) )
|
||||
{
|
||||
m_disableBatching = DisableBatching.False;
|
||||
}
|
||||
}
|
||||
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;
|
||||
case TemplateSpecialTags.DisableBatching:
|
||||
{
|
||||
if( !TemplateHelperFunctions.StringToDisableBatching.TryGetValue( TagValue, out m_disableBatching ) )
|
||||
{
|
||||
m_disableBatching = DisableBatching.False;
|
||||
}
|
||||
}
|
||||
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;
|
||||
case TemplateSpecialTags.DisableBatching:
|
||||
return TagName + IOUtils.VALUE_SEPARATOR +
|
||||
Batching.ToString() + IOUtils.VALUE_SEPARATOR +
|
||||
m_specialTag;
|
||||
}
|
||||
|
||||
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.DisableBatching:
|
||||
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.DisableBatching:
|
||||
{
|
||||
TagValue = m_disableBatching.ToString();
|
||||
}
|
||||
break;
|
||||
case TemplateSpecialTags.RenderType:
|
||||
{
|
||||
//if( m_renderType != RenderType.Custom )
|
||||
// TagValue = m_renderType.ToString();
|
||||
}
|
||||
break;
|
||||
case TemplateSpecialTags.Queue:
|
||||
{
|
||||
BuildQueueTagValue();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DisableBatching Batching
|
||||
{
|
||||
get { return m_disableBatching; }
|
||||
set { m_disableBatching = value;
|
||||
TagValue = value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ed32be99aefda24483c9e3499a5cd23
|
||||
timeCreated: 1500400244
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2daff2983fe91ac43953017a8be984a7
|
||||
timeCreated: 1512404972
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 ); } }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd5a03cee1255ba438e2062d215b70b6
|
||||
timeCreated: 1490378537
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,527 @@
|
||||
// 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",
|
||||
"Sampler 2D Array",
|
||||
"Sampler State",
|
||||
"Custom"};
|
||||
|
||||
[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;
|
||||
case WirePortDataType.SAMPLER2DARRAY: m_selectedInputTypeInt = 12; break;
|
||||
case WirePortDataType.SAMPLERSTATE: m_selectedInputTypeInt = 13; break;
|
||||
case WirePortDataType.OBJECT: m_selectedInputTypeInt = 14; 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_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;
|
||||
case 12: m_selectedInputType = WirePortDataType.SAMPLER2DARRAY; break;
|
||||
case 13: m_selectedInputType = WirePortDataType.SAMPLERSTATE; break;
|
||||
case 14: m_selectedInputType = WirePortDataType.OBJECT; 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:
|
||||
case WirePortDataType.SAMPLER2DARRAY:
|
||||
{
|
||||
types = new WirePortDataType[] { WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE, WirePortDataType.SAMPLER2DARRAY, WirePortDataType.OBJECT };
|
||||
}
|
||||
break;
|
||||
case WirePortDataType.SAMPLERSTATE:
|
||||
{
|
||||
types = new WirePortDataType[] { WirePortDataType.SAMPLERSTATE };
|
||||
}
|
||||
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 override void RefreshExternalReferences()
|
||||
{
|
||||
base.RefreshExternalReferences();
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64064ea01705e084cbe00a3bbeef2c3d
|
||||
timeCreated: 1491927259
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b3de46feda5b0f4ea58c852c4a521a9
|
||||
timeCreated: 1492001141
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6293b1f56d13d6c4ca6a8e2a8099cca9
|
||||
timeCreated: 1491917775
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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_subtitle = "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_subtitle );
|
||||
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_subtitle;
|
||||
// m_containerGraph.CurrentShaderFunction.FunctionSubtitle = m_subttile;
|
||||
}
|
||||
|
||||
public override void DrawProperties()
|
||||
{
|
||||
base.DrawProperties();
|
||||
EditorGUILayout.BeginVertical();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
m_subtitle = EditorGUILayoutTextField( "Name", m_subtitle );
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
SetTitleText( m_subtitle );
|
||||
//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_subtitle );
|
||||
}
|
||||
|
||||
public override void ReadFromString( ref string[] nodeParams )
|
||||
{
|
||||
base.ReadFromString( ref nodeParams );
|
||||
m_subtitle = GetCurrentParam( ref nodeParams );
|
||||
SetTitleText( m_subtitle );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97d5e0cd26200a64fa9d127599406008
|
||||
timeCreated: 1522434121
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,885 @@
|
||||
// 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;
|
||||
|
||||
private bool m_dirtySettings = false;
|
||||
|
||||
[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();
|
||||
}
|
||||
|
||||
if( m_functionSwitchReference.DirtySettings )
|
||||
{
|
||||
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();
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( EditorGUI.EndChangeCheck() )
|
||||
{
|
||||
m_dirtySettings = true;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
if( m_dirtySettings )
|
||||
m_dirtySettings = false;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
if( m_inputPorts[ m_currentSelectedInput ].IsConnected )
|
||||
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; }
|
||||
}
|
||||
public bool DirtySettings { get { return m_dirtySettings; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bd66b9ffd0acf84ab46c9f83300495c
|
||||
timeCreated: 1515408158
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84a4868e0b1e8dd4bb0e71c8d9a9c130
|
||||
timeCreated: 1535365719
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b0e734d4c354c74999e20ce054628d2
|
||||
timeCreated: 1481126955
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1021
Assets/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs
Normal file
1021
Assets/AmplifyShaderEditor/Plugins/Editor/Nodes/Master/MasterNode.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fc2c839ab9f3a045877b59493c51502
|
||||
timeCreated: 1481126957
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d026d775ff431f34789437db3fb4abbb
|
||||
timeCreated: 1481126959
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,633 @@
|
||||
// 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_standardAdditionalDirectives = 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 );
|
||||
}
|
||||
AddMultibodyString( m_standardAdditionalDirectives, 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, !InputList[ i ].IsDirective );
|
||||
}
|
||||
}
|
||||
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 ] );
|
||||
//}
|
||||
|
||||
//Instanced block name must differ from used on main shader so it won't throw a duplicate name error
|
||||
shaderName = shaderName+ "Outline";
|
||||
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 StandardAdditionalDirectives { get { return m_standardAdditionalDirectives; } set { m_standardAdditionalDirectives = 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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0900a4b7d1563e49b6184d7579dcbec
|
||||
timeCreated: 1487331466
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed0ee3a73f11f344495d16b54bb3af29
|
||||
timeCreated: 1491918470
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26d840af03d4f7b418e9c7bece143648
|
||||
timeCreated: 1488906067
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50a1f03b042823f469cef7d97c73fdc3
|
||||
timeCreated: 1488907373
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59e61f9559385a94a87d4d37dbd556f0
|
||||
timeCreated: 1481126956
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0111d524dc809f14aa95e4e1ab93d37b
|
||||
timeCreated: 1481126953
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,375 @@
|
||||
// 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",
|
||||
"\tSAMPLER(sampler_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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 935c69709205e1c4dbd54da410518cc6
|
||||
timeCreated: 1548263010
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6fbad94b0fc6b948be3a3dc61232c05
|
||||
timeCreated: 1481126959
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d818a147712609646b8d6f0f7c2ae731
|
||||
timeCreated: 1530179906
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 , false );
|
||||
m_offsetUnits.ReadFromString( ref index, ref nodeParams , false );
|
||||
}
|
||||
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; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f35a3e26a28596b4f9b54a1f2689db06
|
||||
timeCreated: 1481126960
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user