diff options
Diffstat (limited to 'Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures')
26 files changed, 6709 insertions, 0 deletions
diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/BlendNormalsNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/BlendNormalsNode.cs new file mode 100644 index 00000000..6c063c65 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/BlendNormalsNode.cs @@ -0,0 +1,99 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +using UnityEngine; +using UnityEditor; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Blend Normals", "Textures", "Blend Normals" )] + public class BlendNormalsNode : ParentNode + { + public readonly static string[] ModeListStr = { "Tangent Normals", "Reoriented Tangent Normals", "Reoriented World Normals" }; + public readonly static int[] ModeListInt = { 0, 1, 2 }; + + [SerializeField] + public int m_selectedMode = 0; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT3, false, "Normal A" ); + AddInputPort( WirePortDataType.FLOAT3, false, "Normal B" ); + AddInputPort( WirePortDataType.FLOAT3, false, "Vertex Normal" ); + m_inputPorts[ 2 ].Visible = false; + AddOutputPort( WirePortDataType.FLOAT3, "XYZ" ); + m_useInternalPortData = true; + m_previewShaderGUID = "bcdf750ff5f70444f98b8a3efa50dc6f"; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( !( dataCollector.IsTemplate && dataCollector.IsSRP ) ) + dataCollector.AddToIncludes( UniqueId, Constants.UnityStandardUtilsLibFuncs ); + + string _inputA = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string _inputB = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ); + string result = "BlendNormals( " + _inputA + " , " + _inputB + " )"; + + if( dataCollector.IsTemplate && dataCollector.IsSRP ) + { + switch( m_selectedMode ) + { + default: + case 0: + result = "BlendNormal( " + _inputA + " , " + _inputB + " )"; + break; + case 1: + result = "BlendNormalRNM( " + _inputA + " , " + _inputB + " )"; + break; + case 2: + string inputC = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + result = "BlendNormalWorldspaceRNM( " + _inputA + " , " + _inputB + ", " + inputC + " )"; + break; + } + } + return CreateOutputLocalVariable( 0, result, ref dataCollector ); + } + + public override void DrawProperties() + { + base.DrawProperties(); + if( ContainerGraph.IsSRP ) + { + NodeUtils.DrawPropertyGroup( ref m_propertiesFoldout, Constants.ParameterLabelStr, () => + { + EditorGUI.BeginChangeCheck(); + m_selectedMode = EditorGUILayoutIntPopup( "Mode", m_selectedMode, ModeListStr, ModeListInt ); + if( EditorGUI.EndChangeCheck() ) + { + if( m_selectedMode == 2 ) + { + m_inputPorts[ 2 ].Visible = true; + } + else + { + m_inputPorts[ 2 ].Visible = false; + } + m_sizeIsDirty = true; + } + } ); + } + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + if( UIUtils.CurrentShaderVersion() > 14503 ) + m_selectedMode = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedMode ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/BlendNormalsNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/BlendNormalsNode.cs.meta new file mode 100644 index 00000000..b92fa344 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/BlendNormalsNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: eceb6029efe39524d83b45c10a979943 +timeCreated: 1481126960 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/HeightMapBlendNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/HeightMapBlendNode.cs new file mode 100644 index 00000000..fc1744f5 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/HeightMapBlendNode.cs @@ -0,0 +1,53 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +// +// Custom Node HeightMap Texture Masking +// Donated by Rea + +using UnityEngine; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "HeightMap Texture Blend", "Textures", "Advanced Texture Blending by using heightMap and splatMask, usefull for texture layering ", null, KeyCode.None, true, false, null, null, "Rea" )] + public sealed class HeightMapBlendNode : ParentNode + { + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT, false, "HeightMap" ); + AddInputPort( WirePortDataType.FLOAT, false, "SplatMask" ); + AddInputPort( WirePortDataType.FLOAT, false, "BlendStrength" ); + AddOutputVectorPorts( WirePortDataType.FLOAT, Constants.EmptyPortValue ); + m_textLabelWidth = 120; + m_useInternalPortData = true; + m_inputPorts[ 2 ].FloatInternalData = 1; + m_previewShaderGUID = "b2ac23d6d5dcb334982b6f31c2e7a734"; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if ( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + + string HeightMap = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string SplatMask = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector); + string Blend = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + + string HeightMask = "saturate(pow(((" + HeightMap + "*" + SplatMask + ")*4)+(" + SplatMask + "*2)," + Blend + "))"; + string varName = "HeightMask" + OutputId; + + RegisterLocalVariable( 0, HeightMask, ref dataCollector , varName ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + /* + A = (heightMap * SplatMask)*4 + B = SplatMask*2 + C = pow(A+B,Blend) + saturate(C) + saturate(pow(((heightMap * SplatMask)*4)+(SplatMask*2),Blend)); + */ + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/HeightMapBlendNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/HeightMapBlendNode.cs.meta new file mode 100644 index 00000000..62736ab3 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/HeightMapBlendNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b80a218ca12b89948b83d0dee41fc056 +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/PannerNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/PannerNode.cs new file mode 100644 index 00000000..e20c8c05 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/PannerNode.cs @@ -0,0 +1,110 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Panner", "UV Coordinates", "Pans UV texture coordinates according to its inputs" )] + public sealed class PannerNode : ParentNode + { + private const string _speedXStr = "Speed X"; + private const string _speedYStr = "Speed Y"; + + private int m_cachedUsingEditorId = -1; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ,-1,MasterNodePortCategory.Fragment,0); + AddInputPort( WirePortDataType.FLOAT2, false, "Speed", -1, MasterNodePortCategory.Fragment, 2 ); + AddInputPort( WirePortDataType.FLOAT, false, "Time", -1, MasterNodePortCategory.Fragment, 1 ); + AddOutputPort( WirePortDataType.FLOAT2, "Out" ); + m_textLabelWidth = 70; + m_useInternalPortData = true; + m_previewShaderGUID = "6f89a5d96bdad114b9bbd0c236cac622"; + m_inputPorts[ 2 ].FloatInternalData = 1; + m_continuousPreviewRefresh = true; + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + + if ( m_cachedUsingEditorId == -1 ) + m_cachedUsingEditorId = Shader.PropertyToID( "_UsingEditor" ); + + PreviewMaterial.SetFloat( m_cachedUsingEditorId, ( m_inputPorts[ 2 ].IsConnected ? 0 : 1 ) ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + if( portId == 1 ) + { + m_continuousPreviewRefresh = false; + } + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + if( portId == 1 ) + { + m_continuousPreviewRefresh = true; + } + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + + string timePort = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + + if( !m_inputPorts[ 2 ].IsConnected ) + { + if( !( dataCollector.IsTemplate && dataCollector.IsSRP ) ) + dataCollector.AddToIncludes( UniqueId, Constants.UnityShaderVariables ); + timePort += " * _Time.y"; + } + + string speed = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ); + string result = "( " + timePort + " * " + speed + " + " + m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ) + ")"; + + RegisterLocalVariable( 0, result, ref dataCollector, "panner" + OutputId ); + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + if( UIUtils.CurrentShaderVersion() < 13107 ) + { + // The internal data for the new port can be set in here since it didn't existed + // on older shader versions + float speedX = Convert.ToSingle( GetCurrentParam( ref nodeParams ) ); + float speedY = Convert.ToSingle( GetCurrentParam( ref nodeParams ) ); + m_inputPorts[ 1 ].Vector2InternalData = new Vector2( speedX, speedY ); + } + } + + public override void ReadInputDataFromString( ref string[] nodeParams ) + { + base.ReadInputDataFromString( ref nodeParams ); + if( UIUtils.CurrentShaderVersion() < 13107 ) + { + //Time Port must be rewritten after internal data is read + // already existed in previous shaders + m_inputPorts[ 2 ].FloatInternalData = 1; + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/PannerNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/PannerNode.cs.meta new file mode 100644 index 00000000..e05e46eb --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/PannerNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 08ddf1dd61719944b9e50d4bc87c0413 +timeCreated: 1481126953 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/RotatorNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/RotatorNode.cs new file mode 100644 index 00000000..18aa7781 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/RotatorNode.cs @@ -0,0 +1,96 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Rotator", "UV Coordinates", "Rotates UVs or any Vector2 value from an Anchor point for a specified Time value")] + public sealed class RotatorNode : ParentNode + { + private int m_cachedUsingEditorId = -1; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ); + AddInputPort( WirePortDataType.FLOAT2, false, "Anchor" ); + AddInputPort( WirePortDataType.FLOAT, false, "Time" ); + AddOutputPort( WirePortDataType.FLOAT2, "Out" ); + m_useInternalPortData = true; + m_inputPorts[ 2 ].FloatInternalData = 1; + m_textLabelWidth = 50; + m_previewShaderGUID = "e21408a1c7f12f14bbc2652f69bce1fc"; + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + + if ( m_cachedUsingEditorId == -1 ) + m_cachedUsingEditorId = Shader.PropertyToID( "_UsingEditor" ); + + PreviewMaterial.SetFloat( m_cachedUsingEditorId, (m_inputPorts[ 2 ].IsConnected ? 0 : 1 ) ); + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + if( portId == 2 ) + { + m_continuousPreviewRefresh = false; + } + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + if( portId == 2 ) + { + m_continuousPreviewRefresh = true; + } + } + + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + + string result = string.Empty; + string uv = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string anchor = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ); + + string time = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + if ( !m_inputPorts[ 2 ].IsConnected ) + { + if( !( dataCollector.IsTemplate && dataCollector.IsSRP ) ) + dataCollector.AddToIncludes( UniqueId, Constants.UnityShaderVariables ); + time += " * _Time.y"; + } + + result += uv; + + string cosVar = "cos" + OutputId; + string sinVar = "sin" + OutputId; + dataCollector.AddLocalVariable( UniqueId, "float " + cosVar + " = cos( "+time+" );"); + dataCollector.AddLocalVariable( UniqueId, "float " + sinVar + " = sin( "+time+" );"); + + string value = "mul( " + result + " - " + anchor + " , float2x2( "+cosVar+" , -"+sinVar+" , "+sinVar+" , "+cosVar+" )) + "+anchor; + RegisterLocalVariable( 0, value, ref dataCollector, "rotator" + OutputId ); + + return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ); + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + if( UIUtils.CurrentShaderVersion() < 13107 ) + { + m_inputPorts[ 2 ].FloatInternalData = 1; + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/RotatorNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/RotatorNode.cs.meta new file mode 100644 index 00000000..b031237a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/RotatorNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e228d03a789934a4f90f9587396692e3 +timeCreated: 1481126959 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SamplerNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SamplerNode.cs new file mode 100644 index 00000000..5cf0833c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SamplerNode.cs @@ -0,0 +1,2091 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + // Disabling Substance Deprecated warning + + public enum TexReferenceType + { + Object = 0, + Instance + } + + public enum MipType + { + Auto, + MipLevel, + MipBias, + Derivative + } + + public enum ReferenceState + { + Self, + Connected, + Instance + } + + [Serializable] +#if UNITY_2018_1_OR_NEWER + [NodeAttributes( "Texture Sample", "Textures", "Samples a chosen texture and returns its color values, <b>Texture</b> and <b>UVs</b> can be overriden and you can select different mip modes and levels. It can also unpack and scale textures marked as normalmaps.", KeyCode.T, true, 0, int.MaxValue, typeof( Texture ), typeof( Texture2D ), typeof( Texture3D ), typeof( Cubemap ), typeof( CustomRenderTexture ) )] +#else + + // Disabling Substance Deprecated warning +#pragma warning disable 0618 + [NodeAttributes( "Texture Sample", "Textures", "Samples a chosen texture and returns its color values, <b>Texture</b> and <b>UVs</b> can be overriden and you can select different mip modes and levels. It can also unpack and scale textures marked as normalmaps.", KeyCode.T, true, 0, int.MaxValue, typeof( Texture ), typeof( Texture2D ), typeof( Texture3D ), typeof( Cubemap ), typeof( ProceduralTexture ), typeof( RenderTexture ) +#if UNITY_2017_1_OR_NEWER + ,typeof( CustomRenderTexture ) +#endif + )] +#pragma warning restore 0618 +#endif + public sealed class SamplerNode : TexturePropertyNode + { + private const string MipModeStr = "Mip Mode"; + + private const string DefaultTextureUseSematicsStr = "Use Semantics"; + private const string DefaultTextureIsNormalMapsStr = "Is Normal Map"; + + private const string NormalScaleStr = "Scale"; + + private float InstanceIconWidth = 19; + private float InstanceIconHeight = 19; + + private readonly Color ReferenceHeaderColor = new Color( 2.66f, 1.02f, 0.6f, 1.0f ); + + public readonly static int[] AvailableAutoCast = { 0, 1, 2, 3, 4 }; + public readonly static string[] AvailableAutoCastStr = { "Auto", "Locked To Texture 1D", "Locked To Texture 2D", "Locked To Texture 3D", "Locked To Cube" }; + + [SerializeField] + private int m_textureCoordSet = 0; + + [SerializeField] + private string m_normalMapUnpackMode; + + [SerializeField] + private bool m_autoUnpackNormals = false; + + [SerializeField] + private bool m_useSemantics; + + [SerializeField] + private string m_samplerType; + + [SerializeField] + private MipType m_mipMode = MipType.Auto; + + [SerializeField] + private TexReferenceType m_referenceType = TexReferenceType.Object; + + [SerializeField] + private int m_referenceArrayId = -1; + + [SerializeField] + private int m_referenceNodeId = -1; + + private SamplerNode m_referenceSampler = null; + + [SerializeField] + private GUIStyle m_referenceStyle = null; + + [SerializeField] + private GUIStyle m_referenceIconStyle = null; + + [SerializeField] + private GUIContent m_referenceContent = null; + + [SerializeField] + private float m_referenceWidth = -1; + + [SerializeField] + private SamplerStateAutoGenerator m_samplerStateAutoGenerator = new SamplerStateAutoGenerator(); + + private Vector4Node m_texCoordsHelper; + + private string m_previousAdditionalText = string.Empty; + + private int m_cachedUvsId = -1; + private int m_cachedUnpackId = -1; + private int m_cachedLodId = -1; + + private InputPort m_texPort; + private InputPort m_uvPort; + private InputPort m_lodPort; + private InputPort m_ddxPort; + private InputPort m_ddyPort; + private InputPort m_normalPort; + + private OutputPort m_colorPort; + + private TexturePropertyNode m_previewTextProp = null; + private ReferenceState m_state = ReferenceState.Self; + + private Rect m_iconPos; + + public SamplerNode() : base() { } + public SamplerNode( 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 ); + if( m_useSamplerArrayIdx < 0 ) + { + m_useSamplerArrayIdx = 0; + } + + m_defaultTextureValue = TexturePropertyValues.white; + AddInputPort( WirePortDataType.SAMPLER2D, false, "Tex" ); + m_inputPorts[ 0 ].CreatePortRestrictions( WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE, WirePortDataType.OBJECT ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ); + AddInputPort( WirePortDataType.FLOAT, false, "Level" ); + AddInputPort( WirePortDataType.FLOAT2, false, "DDX" ); + AddInputPort( WirePortDataType.FLOAT2, false, "DDY" ); + AddInputPort( WirePortDataType.FLOAT, false, NormalScaleStr ); + + m_texPort = m_inputPorts[ 0 ]; + m_uvPort = m_inputPorts[ 1 ]; + m_lodPort = m_inputPorts[ 2 ]; + m_ddxPort = m_inputPorts[ 3 ]; + m_ddyPort = m_inputPorts[ 4 ]; + m_normalPort = m_inputPorts[ 5 ]; + m_normalPort.AutoDrawInternalData = true; + m_lodPort.Visible = false; + m_ddxPort.Visible = false; + m_ddyPort.Visible = false; + m_normalPort.Visible = m_autoUnpackNormals; + m_normalPort.FloatInternalData = 1.0f; + + //Remove output port (sampler) + m_outputPortsDict.Remove( m_outputPorts[ 0 ].PortId ); + m_outputPorts.RemoveAt( 0 ); + + AddOutputColorPorts( "RGBA" ); + m_colorPort = m_outputPorts[ 0 ]; + m_currentParameterType = PropertyType.Property; + // m_useCustomPrefix = true; + m_customPrefix = "Texture Sample "; + m_referenceContent = new GUIContent( string.Empty ); + m_freeType = false; + m_useSemantics = true; + m_drawPicker = false; + ConfigTextureData( TextureType.Texture2D ); + m_selectedLocation = PreviewLocation.TopCenter; + m_previewShaderGUID = "7b4e86a89b70ae64993bf422eb406422"; + + m_errorMessageTooltip = "A texture object marked as normal map is connected to this sampler. Please consider turning on the Unpack Normal Map option"; + m_errorMessageTypeIsError = NodeMessageType.Warning; + m_textLabelWidth = 135; + m_customPrecision = false; + } + + public override void SetPreviewInputs() + { + //TODO: rewrite this to be faster + base.SetPreviewInputs(); + + if( m_cachedUvsId == -1 ) + m_cachedUvsId = Shader.PropertyToID( "_CustomUVs" ); + + PreviewMaterial.SetInt( m_cachedUvsId, ( m_uvPort.IsConnected ? 1 : 0 ) ); + + if( m_cachedUnpackId == -1 ) + m_cachedUnpackId = Shader.PropertyToID( "_Unpack" ); + + PreviewMaterial.SetInt( m_cachedUnpackId, m_autoUnpackNormals ? 1 : 0 ); + + if( m_cachedLodId == -1 ) + m_cachedLodId = Shader.PropertyToID( "_LodType" ); + + PreviewMaterial.SetInt( m_cachedLodId, ( m_mipMode == MipType.MipLevel ? 1 : ( m_mipMode == MipType.MipBias ? 2 : 0 ) ) ); + + if( m_typeId == -1 ) + m_typeId = Shader.PropertyToID( "_Type" ); + + bool usingTexture = false; + if( m_texPort.IsConnected ) + { + usingTexture = true; + SetPreviewTexture( m_texPort.InputPreviewTexture( ContainerGraph ) ); + } + else if( SoftValidReference && m_referenceSampler.TextureProperty != null ) + { + if( m_referenceSampler.TextureProperty.Value != null ) + { + usingTexture = true; + SetPreviewTexture( m_referenceSampler.TextureProperty.Value ); + } + else + { + usingTexture = true; + SetPreviewTexture( m_referenceSampler.PreviewTexture ); + } + } + else if( TextureProperty != null ) + { + if( TextureProperty.Value != null ) + { + usingTexture = true; + SetPreviewTexture( TextureProperty.Value ); + } + } + + if( m_defaultId == -1 ) + m_defaultId = Shader.PropertyToID( "_Default" ); + + if( usingTexture ) + { + PreviewMaterial.SetInt( m_defaultId, 0 ); + m_previewMaterialPassId = 1; + } + else + { + PreviewMaterial.SetInt( m_defaultId, ( (int)m_defaultTextureValue ) + 1 ); + m_previewMaterialPassId = 0; + } + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + if( m_referenceType == TexReferenceType.Object ) + { + UIUtils.RegisterSamplerNode( this ); + UIUtils.RegisterPropertyNode( this ); + } + m_textureProperty = this; + + if( UniqueId > -1 ) + ContainerGraph.SamplerNodes.OnReorderEventComplete += OnReorderEventComplete; + } + + private void OnReorderEventComplete() + { + if( m_referenceType == TexReferenceType.Instance && m_referenceSampler != null ) + { + m_referenceArrayId = ContainerGraph.SamplerNodes.GetNodeRegisterIdx( m_referenceSampler.UniqueId ); + } + } + + public void ConfigSampler() + { + switch( m_currentType ) + { + case TextureType.Texture1D: + m_samplerType = "tex1D"; + break; + case TextureType.ProceduralTexture: + case TextureType.Texture2D: + m_samplerType = "tex2D"; + break; + case TextureType.Texture3D: + m_samplerType = "tex3D"; + break; + case TextureType.Cube: + m_samplerType = "texCUBE"; + break; + } + } + + public override void DrawSubProperties() + { + ShowDefaults(); + + DrawSamplerOptions(); + + EditorGUI.BeginChangeCheck(); + Type currType = ( m_autocastMode == AutoCastType.Auto ) ? typeof( Texture ) : m_textureType; + m_defaultValue = EditorGUILayoutObjectField( Constants.DefaultValueLabel, m_defaultValue, currType, false ) as Texture; + if( EditorGUI.EndChangeCheck() ) + { + CheckTextureImporter( true ); + SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) ); + ConfigureInputPorts(); + ConfigureOutputPorts(); + //ResizeNodeToPreview(); + } + } + + public override void DrawMaterialProperties() + { + ShowDefaults(); + + DrawSamplerOptions(); + + EditorGUI.BeginChangeCheck(); + Type currType = ( m_autocastMode == AutoCastType.Auto ) ? typeof( Texture ) : m_textureType; + m_materialValue = EditorGUILayoutObjectField( Constants.MaterialValueLabel, m_materialValue, currType, false ) as Texture; + if( EditorGUI.EndChangeCheck() ) + { + CheckTextureImporter( true ); + SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) ); + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + } + + new void ShowDefaults() + { + m_defaultTextureValue = (TexturePropertyValues)EditorGUILayoutEnumPopup( DefaultTextureStr, m_defaultTextureValue ); + AutoCastType newAutoCast = (AutoCastType)EditorGUILayoutIntPopup( AutoCastModeStr, (int)m_autocastMode, AvailableAutoCastStr, AvailableAutoCast ); + //AutoCastType newAutoCast = (AutoCastType)EditorGUILayoutEnumPopup( AutoCastModeStr, m_autocastMode ); + if( newAutoCast != m_autocastMode ) + { + m_autocastMode = newAutoCast; + if( m_autocastMode != AutoCastType.Auto ) + { + ConfigTextureData( m_currentType ); + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + } + } + + public override void AdditionalCheck() + { + m_autoUnpackNormals = m_isNormalMap; + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + + + public override void OnConnectedOutputNodeChanges( int portId, int otherNodeId, int otherPortId, string name, WirePortDataType type ) + { + base.OnConnectedOutputNodeChanges( portId, otherNodeId, otherPortId, name, type ); + if( portId == m_texPort.PortId ) + { + m_textureProperty = m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode; + if( m_textureProperty != null ) + { + m_currentType = m_textureProperty.CurrentType; + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + } + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + + if( portId == m_texPort.PortId ) + { + m_textureProperty = m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode; + + if( m_textureProperty == null ) + { + m_textureProperty = this; + // This cast fails only from within shader functions if connected to a Sampler Input + // and in this case property is set by what is connected to that input + UIUtils.UnregisterPropertyNode( this ); + UIUtils.UnregisterTexturePropertyNode( this ); + } + else + { + //if( m_autocastMode == AutoCastType.Auto ) + //{ + m_currentType = m_textureProperty.CurrentType; + //} + + + //if ( m_textureProperty is VirtualTexturePropertyNode ) + //{ + // AutoUnpackNormals = ( m_textureProperty as VirtualTexturePropertyNode ).Channel == VirtualChannel.Normal; + //} + //else if( m_textureProperty.IsValid ) + //{ + + // AutoUnpackNormals = m_textureProperty.IsNormalMap; + //} + + UIUtils.UnregisterPropertyNode( this ); + UIUtils.UnregisterTexturePropertyNode( this ); + } + + ConfigureInputPorts(); + ConfigureOutputPorts(); + //ResizeNodeToPreview(); + } + + UpdateTitle(); + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + + if( portId == m_texPort.PortId ) + { + m_textureProperty = this; + + if( m_referenceType == TexReferenceType.Object ) + { + UIUtils.RegisterPropertyNode( this ); + UIUtils.RegisterTexturePropertyNode( this ); + } + + ConfigureOutputPorts(); + //ResizeNodeToPreview(); + } + + UpdateTitle(); + } + + private void ForceInputPortsChange() + { + m_texPort.ChangeType( WirePortDataType.SAMPLER2D, false ); + m_normalPort.ChangeType( WirePortDataType.FLOAT, false ); + switch( m_currentType ) + { + case TextureType.Texture1D: + m_uvPort.ChangeType( WirePortDataType.FLOAT, false ); + m_ddxPort.ChangeType( WirePortDataType.FLOAT, false ); + m_ddyPort.ChangeType( WirePortDataType.FLOAT, false ); + break; + case TextureType.ProceduralTexture: + case TextureType.Texture2D: + m_uvPort.ChangeType( WirePortDataType.FLOAT2, false ); + m_ddxPort.ChangeType( WirePortDataType.FLOAT2, false ); + m_ddyPort.ChangeType( WirePortDataType.FLOAT2, false ); + break; + case TextureType.Texture3D: + case TextureType.Cube: + m_uvPort.ChangeType( WirePortDataType.FLOAT3, false ); + m_ddxPort.ChangeType( WirePortDataType.FLOAT3, false ); + m_ddyPort.ChangeType( WirePortDataType.FLOAT3, false ); + break; + } + } + + public override void ConfigureInputPorts() + { + m_normalPort.Visible = AutoUnpackNormals; + + switch( m_mipMode ) + { + case MipType.Auto: + m_lodPort.Visible = false; + m_ddxPort.Visible = false; + m_ddyPort.Visible = false; + break; + case MipType.MipLevel: + m_lodPort.Name = "Level"; + m_lodPort.Visible = true; + m_ddxPort.Visible = false; + m_ddyPort.Visible = false; + break; + case MipType.MipBias: + m_lodPort.Name = "Bias"; + m_lodPort.Visible = true; + m_ddxPort.Visible = false; + m_ddyPort.Visible = false; + break; + case MipType.Derivative: + m_lodPort.Visible = false; + m_ddxPort.Visible = true; + m_ddyPort.Visible = true; + break; + } + + switch( m_currentType ) + { + case TextureType.Texture1D: + m_uvPort.ChangeType( WirePortDataType.FLOAT, false ); + m_ddxPort.ChangeType( WirePortDataType.FLOAT, false ); + m_ddyPort.ChangeType( WirePortDataType.FLOAT, false ); + break; + case TextureType.ProceduralTexture: + case TextureType.Texture2D: + m_uvPort.ChangeType( WirePortDataType.FLOAT2, false ); + m_ddxPort.ChangeType( WirePortDataType.FLOAT2, false ); + m_ddyPort.ChangeType( WirePortDataType.FLOAT2, false ); + break; + case TextureType.Texture3D: + case TextureType.Cube: + m_uvPort.ChangeType( WirePortDataType.FLOAT3, false ); + m_ddxPort.ChangeType( WirePortDataType.FLOAT3, false ); + m_ddyPort.ChangeType( WirePortDataType.FLOAT3, false ); + break; + } + + m_sizeIsDirty = true; + } + + public override void ConfigureOutputPorts() + { + m_outputPorts[ m_colorPort.PortId + 4 ].Visible = !AutoUnpackNormals; + + if( !AutoUnpackNormals ) + { + m_colorPort.ChangeProperties( "RGBA", WirePortDataType.COLOR, false ); + m_outputPorts[ m_colorPort.PortId + 1 ].ChangeProperties( "R", WirePortDataType.FLOAT, false ); + m_outputPorts[ m_colorPort.PortId + 2 ].ChangeProperties( "G", WirePortDataType.FLOAT, false ); + m_outputPorts[ m_colorPort.PortId + 3 ].ChangeProperties( "B", WirePortDataType.FLOAT, false ); + m_outputPorts[ m_colorPort.PortId + 4 ].ChangeProperties( "A", WirePortDataType.FLOAT, false ); + + } + else + { + m_colorPort.ChangeProperties( "XYZ", WirePortDataType.FLOAT3, false ); + m_outputPorts[ m_colorPort.PortId + 1 ].ChangeProperties( "X", WirePortDataType.FLOAT, false ); + m_outputPorts[ m_colorPort.PortId + 2 ].ChangeProperties( "Y", WirePortDataType.FLOAT, false ); + m_outputPorts[ m_colorPort.PortId + 3 ].ChangeProperties( "Z", WirePortDataType.FLOAT, false ); + } + + m_sizeIsDirty = true; + } + + void UpdateTitle() + { + if( m_referenceType == TexReferenceType.Object ) + { + SetTitleText( m_propertyInspectorName ); + SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) ); + } + + m_sizeIsDirty = true; + } + + public override void OnObjectDropped( UnityEngine.Object obj ) + { + base.OnObjectDropped( obj ); + ConfigFromObject( obj ); + } + + public override void SetupFromCastObject( UnityEngine.Object obj ) + { + base.SetupFromCastObject( obj ); + ConfigFromObject( obj ); + } + + void UpdateHeaderColor() + { + m_headerColorModifier = ( m_referenceType == TexReferenceType.Object ) ? Color.white : ReferenceHeaderColor; + } + + + + void ShowSamplerUI() + { + if( UIUtils.CurrentWindow.OutsideGraph.IsSRP ) + { + string[] contents = UIUtils.TexturePropertyNodeArr(); + string[] arr = new string[ contents.Length + 1 ]; + arr[ 0 ] = "<None>"; + for( int i = 1; i < contents.Length + 1; i++ ) + { + arr[ i ] = contents[ i - 1 ]; + } + m_useSamplerArrayIdx = EditorGUILayoutPopup( "Reference Sampler", m_useSamplerArrayIdx, arr ); + m_samplerStateAutoGenerator.Draw( this ); + } + } + + public void DrawSamplerOptions() + { + m_textureCoordSet = EditorGUILayoutIntPopup( Constants.AvailableUVSetsLabel, m_textureCoordSet, Constants.AvailableUVSetsStr, Constants.AvailableUVSets ); + + MipType newMipMode = (MipType)EditorGUILayoutEnumPopup( MipModeStr, m_mipMode ); + if( newMipMode != m_mipMode ) + { + m_mipMode = newMipMode; + ConfigureInputPorts(); + ConfigureOutputPorts(); + //ResizeNodeToPreview(); + } + + EditorGUI.BeginChangeCheck(); + m_autoUnpackNormals = EditorGUILayoutToggle( "Unpack Normal Map", m_autoUnpackNormals ); + if( m_autoUnpackNormals && !m_normalPort.IsConnected ) + { + m_normalPort.FloatInternalData = EditorGUILayoutFloatField( NormalScaleStr, m_normalPort.FloatInternalData ); + } + + if( EditorGUI.EndChangeCheck() ) + { + ConfigureInputPorts(); + ConfigureOutputPorts(); + //ResizeNodeToPreview(); + } + ShowSamplerUI(); + if( m_showErrorMessage ) + { + EditorGUILayout.HelpBox( m_errorMessageTooltip, MessageType.Warning ); + } + } + + public override void DrawMainPropertyBlock() + { + EditorGUI.BeginChangeCheck(); + m_referenceType = (TexReferenceType)EditorGUILayoutPopup( Constants.ReferenceTypeStr, (int)m_referenceType, Constants.ReferenceArrayLabels ); + if( EditorGUI.EndChangeCheck() ) + { + if( m_referenceType == TexReferenceType.Object ) + { + UIUtils.RegisterSamplerNode( this ); + UIUtils.RegisterPropertyNode( this ); + if( !m_texPort.IsConnected ) + UIUtils.RegisterTexturePropertyNode( this ); + + SetTitleText( m_propertyInspectorName ); + SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) ); + m_referenceArrayId = -1; + m_referenceNodeId = -1; + m_referenceSampler = null; + m_textureProperty = m_texPort.IsConnected ? m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode : this; + + } + else + { + UIUtils.UnregisterSamplerNode( this ); + UIUtils.UnregisterPropertyNode( this ); + if( !m_texPort.IsConnected ) + UIUtils.UnregisterTexturePropertyNode( this ); + } + UpdateHeaderColor(); + } + + if( m_referenceType == TexReferenceType.Object ) + { + EditorGUI.BeginChangeCheck(); + if( m_texPort.IsConnected ) + { + m_drawAttributes = false; + DrawSamplerOptions(); + } + else + { + m_drawAttributes = true; + base.DrawMainPropertyBlock(); + } + if( EditorGUI.EndChangeCheck() ) + { + OnPropertyNameChanged(); + } + } + else + { + m_drawAttributes = true; + string[] arr = UIUtils.SamplerNodeArr(); + bool guiEnabledBuffer = GUI.enabled; + if( arr != null && arr.Length > 0 ) + { + GUI.enabled = true; + } + else + { + m_referenceArrayId = -1; + GUI.enabled = false; + } + + EditorGUI.BeginChangeCheck(); + m_referenceArrayId = EditorGUILayoutPopup( Constants.AvailableReferenceStr, m_referenceArrayId, arr ); + if( EditorGUI.EndChangeCheck() ) + { + m_referenceSampler = ContainerGraph.SamplerNodes.GetNode( m_referenceArrayId ); + if( m_referenceSampler != null ) + { + m_referenceNodeId = m_referenceSampler.UniqueId; + } + else + { + m_referenceArrayId = -1; + m_referenceNodeId = -1; + } + } + GUI.enabled = guiEnabledBuffer; + + DrawSamplerOptions(); + } + } + + public override void OnPropertyNameChanged() + { + base.OnPropertyNameChanged(); + UIUtils.UpdateSamplerDataNode( UniqueId, PropertyName ); + UIUtils.UpdateTexturePropertyDataNode( UniqueId, PropertyName ); + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + base.DrawGUIControls( drawInfo ); + + if( m_state != ReferenceState.Self && drawInfo.CurrentEventType == EventType.MouseDown && m_previewRect.Contains( drawInfo.MousePosition ) && drawInfo.LeftMouseButtonPressed ) + { + UIUtils.FocusOnNode( m_previewTextProp, 1, true ); + Event.current.Use(); + } + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + CheckReference(); + + if( SoftValidReference ) + { + m_state = ReferenceState.Instance; + m_previewTextProp = m_referenceSampler.TextureProperty; + } + else if( m_texPort.IsConnected ) + { + m_state = ReferenceState.Connected; + m_previewTextProp = TextureProperty; + } + else + { + m_state = ReferenceState.Self; + } + + if( m_previewTextProp == null ) + m_previewTextProp = this; + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + base.OnNodeLayout( drawInfo ); + + if( m_drawPreview ) + { + m_iconPos = m_globalPosition; + m_iconPos.width = InstanceIconWidth * drawInfo.InvertedZoom; + m_iconPos.height = InstanceIconHeight * drawInfo.InvertedZoom; + + m_iconPos.y += 10 * drawInfo.InvertedZoom; + m_iconPos.x += m_globalPosition.width - m_iconPos.width - 5 * drawInfo.InvertedZoom; + } + } + + public override void OnNodeRepaint( DrawInfo drawInfo ) + { + base.OnNodeRepaint( drawInfo ); + + if( !m_isVisible ) + return; + + if( drawInfo.CurrentEventType != EventType.Repaint ) + return; + + switch( m_state ) + { + default: + case ReferenceState.Self: + { + m_drawPreview = false; + //SetTitleText( PropertyInspectorName /*m_propertyInspectorName*/ ); + //small optimization, string format or concat on every frame generates garbage + //string tempVal = GetPropertyValStr(); + //if ( !m_previousAdditionalText.Equals( tempVal ) ) + //{ + // m_previousAdditionalText = tempVal; + // m_additionalContent.text = string.Concat( "Value( ", tempVal, " )" ); + //} + + m_drawPicker = true; + } + break; + case ReferenceState.Connected: + { + m_drawPreview = true; + m_drawPicker = false; + + SetTitleText( m_previewTextProp.PropertyInspectorName + " (Input)" ); + m_previousAdditionalText = m_previewTextProp.AdditonalTitleContent.text; + SetAdditonalTitleText( m_previousAdditionalText ); + // Draw chain lock + GUI.Label( m_iconPos, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerTextureIcon ) ); + + // Draw frame around preview + GUI.Label( m_previewRect, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) ); + } + break; + case ReferenceState.Instance: + { + m_drawPreview = true; + m_drawPicker = false; + + //SetTitleText( m_previewTextProp.PropertyInspectorName + Constants.InstancePostfixStr ); + //m_previousAdditionalText = m_previewTextProp.AdditonalTitleContent.text; + //SetAdditonalTitleText( m_previousAdditionalText ); + + SetTitleTextOnCallback( m_previewTextProp.PropertyInspectorName, ( instance, newTitle ) => instance.TitleContent.text = newTitle + Constants.InstancePostfixStr ); + SetAdditonalTitleText( m_previewTextProp.AdditonalTitleContent.text ); + + // Draw chain lock + GUI.Label( m_iconPos, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerTextureIcon ) ); + + // Draw frame around preview + GUI.Label( m_previewRect, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) ); + } + break; + } + } + + void CheckReference() + { + if( m_referenceType != TexReferenceType.Instance ) + { + return; + } + + if( m_referenceArrayId > -1 ) + { + ParentNode newNode = ContainerGraph.SamplerNodes.GetNode( m_referenceArrayId ); + if( newNode == null || newNode.UniqueId != m_referenceNodeId ) + { + m_referenceSampler = null; + int count = ContainerGraph.SamplerNodes.NodesList.Count; + for( int i = 0; i < count; i++ ) + { + ParentNode node = ContainerGraph.SamplerNodes.GetNode( i ); + if( node.UniqueId == m_referenceNodeId ) + { + m_referenceSampler = node as SamplerNode; + m_referenceArrayId = i; + break; + } + } + } + else + { + // Set References Options + AutoCastType newAutoCast = m_referenceSampler.AutocastMode; + if( newAutoCast != m_autocastMode ) + { + m_autocastMode = newAutoCast; + if( m_autocastMode != AutoCastType.Auto ) + { + ConfigTextureData( m_currentType ); + ConfigureInputPorts(); + ConfigureOutputPorts(); + //ResizeNodeToPreview(); + } + } + } + } + + if( m_referenceSampler == null && m_referenceNodeId > -1 ) + { + m_referenceNodeId = -1; + m_referenceArrayId = -1; + } + } + + public void SetTitleTextDelay( string newText ) + { + if( !newText.Equals( m_content.text ) ) + { + m_content.text = newText; + BeginDelayedDirtyProperty(); + } + } + + public void SetAdditonalTitleTextDelay( string newText ) + { + if( !newText.Equals( m_additionalContent.text ) ) + { + m_additionalContent.text = newText; + BeginDelayedDirtyProperty(); + } + } + + private void DrawTexturePropertyPreview( DrawInfo drawInfo, bool instance ) + { + if( drawInfo.CurrentEventType != EventType.Repaint ) + return; + + Rect newPos = m_previewRect; + + TexturePropertyNode texProp = null; + if( instance ) + texProp = m_referenceSampler.TextureProperty; + else + texProp = TextureProperty; + + if( texProp == null ) + texProp = this; + + float previewSizeX = PreviewSizeX; + float previewSizeY = PreviewSizeY; + newPos.width = previewSizeX * drawInfo.InvertedZoom; + newPos.height = previewSizeY * drawInfo.InvertedZoom; + + SetTitleText( texProp.PropertyInspectorName + ( instance ? Constants.InstancePostfixStr : " (Input)" ) ); + SetAdditonalTitleText( texProp.AdditonalTitleContent.text ); + + if( m_referenceStyle == null ) + { + m_referenceStyle = UIUtils.GetCustomStyle( CustomStyle.SamplerTextureRef ); + } + + if( m_referenceIconStyle == null || m_referenceIconStyle.normal == null ) + { + m_referenceIconStyle = UIUtils.GetCustomStyle( CustomStyle.SamplerTextureIcon ); + if( m_referenceIconStyle != null && m_referenceIconStyle.normal != null && m_referenceIconStyle.normal.background != null ) + { + InstanceIconWidth = m_referenceIconStyle.normal.background.width; + InstanceIconHeight = m_referenceIconStyle.normal.background.height; + } + } + + Rect iconPos = m_globalPosition; + iconPos.width = InstanceIconWidth * drawInfo.InvertedZoom; + iconPos.height = InstanceIconHeight * drawInfo.InvertedZoom; + + iconPos.y += 10 * drawInfo.InvertedZoom; + iconPos.x += m_globalPosition.width - iconPos.width - 5 * drawInfo.InvertedZoom; + + //if ( GUI.Button( newPos, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerTextureRef )/* m_referenceStyle */) || + // GUI.Button( iconPos, string.Empty, m_referenceIconStyle ) + // ) + //{ + // UIUtils.FocusOnNode( texProp, 1, true ); + //} + + if( texProp.Value != null ) + { + DrawPreview( drawInfo, m_previewRect ); + GUI.Label( newPos, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) ); + //UIUtils.GetCustomStyle( CustomStyle.SamplerButton ).fontSize = ( int )Mathf.Round( 9 * drawInfo.InvertedZoom ); + } + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar ) + { + if( dataCollector.PortCategory == MasterNodePortCategory.Tessellation ) + { + UIUtils.ShowMessage( UniqueId, m_nodeAttribs.Name + " cannot be used on Master Node Tessellation port" ); + return "(-1)"; + } + + OnPropertyNameChanged(); + + ConfigSampler(); + + string portProperty = string.Empty; + if( m_texPort.IsConnected ) + portProperty = m_texPort.GenerateShaderForOutput( ref dataCollector, true ); + + if( SoftValidReference ) + { + OrderIndex = m_referenceSampler.RawOrderIndex; + if( m_referenceSampler.TexPort.IsConnected ) + { + portProperty = m_referenceSampler.TexPort.GeneratePortInstructions( ref dataCollector ); + } + else + { + m_referenceSampler.RegisterProperty( ref dataCollector ); + } + } + + if( m_autoUnpackNormals ) + { + bool isScaledNormal = false; + if( m_normalPort.IsConnected ) + { + isScaledNormal = true; + } + else + { + if( m_normalPort.FloatInternalData != 1 ) + { + isScaledNormal = true; + } + } + + string scaleValue = isScaledNormal ? m_normalPort.GeneratePortInstructions( ref dataCollector ) : "1.0f"; + m_normalMapUnpackMode = TemplateHelperFunctions.CreateUnpackNormalStr( dataCollector, isScaledNormal, scaleValue ); + + if( isScaledNormal ) + { + if( !( dataCollector.IsTemplate && dataCollector.IsSRP ) ) + { + dataCollector.AddToIncludes( UniqueId, Constants.UnityStandardUtilsLibFuncs ); + } + } + + } + if( IsObject && ( !m_texPort.IsConnected || portProperty == "0.0" ) ) + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalVar ); + + string valueName = SetFetchedData( ref dataCollector, ignoreLocalVar, outputId, portProperty ); + if( TextureProperty is VirtualTextureObject ) + { + return valueName; + } + else + { + + return GetOutputColorItem( 0, outputId, valueName ); + } + } + + public string SampleVirtualTexture( VirtualTextureObject node, string coord ) + { + string sampler = string.Empty; + switch( node.Channel ) + { + default: + case VirtualChannel.Albedo: + case VirtualChannel.Base: + sampler = "VTSampleAlbedo( " + coord + " )"; + break; + case VirtualChannel.Normal: + case VirtualChannel.Height: + case VirtualChannel.Occlusion: + case VirtualChannel.Displacement: + sampler = "VTSampleNormal( " + coord + " )"; + break; + case VirtualChannel.Specular: + case VirtualChannel.SpecMet: + case VirtualChannel.Material: + sampler = "VTSampleSpecular( " + coord + " )"; + break; + } + return sampler; + } + + public string SampleTexture( ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar, string portProperty, MipType currMipMode, string propertyName ) + { + string samplerValue = string.Empty; + string uvCoords = GetUVCoords( ref dataCollector, ignoreLocalVar, portProperty ); + bool useMacros = false; + + ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph; + + if( outsideGraph.SamplingThroughMacros ) + { + if( outsideGraph.IsSRP ) + { + useMacros = Constants.TexSampleSRPMacros.ContainsKey( m_currentType ); + } + else + { + useMacros = Constants.TexSampleStandardMacros.ContainsKey( m_currentType ); + } + } + + if( useMacros ) + { + string suffix = string.Empty; + if( m_lodPort.IsConnected ) + { + switch( currMipMode ) + { + default: + case MipType.Auto: break; + case MipType.MipLevel: suffix = "_LOD"; break; + case MipType.MipBias: suffix = "_BIAS"; break; + case MipType.Derivative: suffix = "_GRAD"; break; + } + } + else + { + switch( currMipMode ) + { + default: + case MipType.MipLevel: + case MipType.MipBias: + case MipType.Auto: break; + case MipType.Derivative: suffix = "_GRAD"; break; + } + } + string samplerToUse = string.Empty; + if( m_useSamplerArrayIdx > 0 ) + { + TexturePropertyNode samplerNode = UIUtils.GetTexturePropertyNode( m_useSamplerArrayIdx - 1 ); + if( samplerNode != null ) + { + if( samplerNode.IsConnected ) + { + samplerToUse = samplerNode.CurrentPropertyReference; + } + else + { + UIUtils.ShowMessage( UniqueId, string.Format( "{0} attempting to use sampler from unconnected {1} node. Reference Sampler nodes must be in use for their samplers to be created.", m_propertyName, samplerNode.PropertyName ), MessageSeverity.Warning ); + dataCollector.AddToUniforms( UniqueId, string.Format( Constants.SamplerDeclarationSRPMacros[ m_currentType ], propertyName ) ); + samplerToUse = propertyName; + } + } + else + { + UIUtils.ShowMessage( UniqueId, m_propertyName + " attempting to use sampler from invalid node.", MessageSeverity.Warning ); + dataCollector.AddToUniforms( UniqueId, string.Format( Constants.SamplerDeclarationSRPMacros[ m_currentType ], propertyName ) ); + samplerToUse = propertyName; + } + } + else + { + if( HasPropertyReference ) + dataCollector.AddToUniforms( UniqueId, string.Format( Constants.SamplerDeclarationSRPMacros[ m_currentType ], propertyName ) ); + + samplerToUse = propertyName; + } + + if( outsideGraph.IsSRP ) + { + samplerValue = string.Format( Constants.TexSampleSRPMacros[ m_currentType ], suffix, propertyName, samplerToUse, uvCoords ); + } + else + { + GeneratorUtils.AddCustomStandardSamplingMacros( ref dataCollector ); + + samplerValue = string.Format( Constants.TexSampleStandardMacros[ m_currentType ], suffix, propertyName, uvCoords ); + } + } + else + { + string mipType = ""; + if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ) + { + mipType = "lod"; + } + + if( m_lodPort.IsConnected ) + { + switch( currMipMode ) + { + case MipType.Auto: + break; + case MipType.MipLevel: + mipType = "lod"; + break; + case MipType.MipBias: + mipType = "bias"; + break; + case MipType.Derivative: + break; + } + } + samplerValue = m_samplerType + mipType + "( " + propertyName + ", " + uvCoords + " )"; + } + + return samplerValue; + } + + public string SetFetchedData( ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar, int outputId, string portProperty = null ) + { + m_precisionString = UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, m_colorPort.DataType ); + string propertyName = CurrentPropertyReference; + if( !string.IsNullOrEmpty( portProperty ) && portProperty != "0.0" ) + { + propertyName = portProperty; + } + MipType currMipMode = m_mipMode; + //string mipType = ""; + //if( m_lodPort.IsConnected ) + //{ + // switch( m_mipMode ) + // { + // case MipType.Auto: + // break; + // case MipType.MipLevel: + // mipType = "lod"; + // break; + // case MipType.MipBias: + // mipType = "bias"; + // break; + // case MipType.Derivative: + // break; + // } + //} + //string uvCoords = string.Empty; + //bool useMacros = false; + if( ignoreLocalVar ) + { + if( TextureProperty is VirtualTextureObject ) + Debug.Log( "TODO" ); + + if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ) + { + //mipType = "lod"; + currMipMode = MipType.MipLevel; + } + + string samplerValue = SampleTexture( ref dataCollector, ignoreLocalVar, portProperty, currMipMode, propertyName ); + //string samplerValue = string.Empty; + //uvCoords = GetUVCoords( ref dataCollector, ignoreLocalVar, portProperty ); + //useMacros = m_containerGraph.SamplingThroughMacros && !mipType.Equals( "bias" ) && Constants.TexSampleStandardMacros.ContainsKey( m_currentType ); + //if( useMacros ) + //{ + // bool addLodPrefix = mipType.Equals( "lod" ); + // samplerValue = string.Format( Constants.TexSampleStandardMacros[ m_currentType ], addLodPrefix ? Constants.TexSampleLODPrefix : string.Empty, propertyName, uvCoords ); + //} + //else + //{ + // samplerValue = m_samplerType + mipType + "( " + propertyName + ", " + uvCoords + " )"; + //} + AddNormalMapTag( ref samplerValue ); + return samplerValue; + } + + VirtualTextureObject vtex = ( TextureProperty as VirtualTextureObject ); + + if( vtex != null ) + { + string atPathname = AssetDatabase.GUIDToAssetPath( Constants.ATSharedLibGUID ); + if( string.IsNullOrEmpty( atPathname ) ) + { + UIUtils.ShowMessage( UniqueId, "Could not find Amplify Texture on your project folder. Please install it and re-compile the shader.", MessageSeverity.Error ); + } + else + { + //Need to see if the asset really exists because AssetDatabase.GUIDToAssetPath() can return a valid path if + // the asset was previously imported and deleted after that + UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>( atPathname ); + if( obj == null ) + { + UIUtils.ShowMessage( UniqueId, "Could not find Amplify Texture on your project folder. Please install it and re-compile the shader.", MessageSeverity.Error ); + } + else + { + if( m_colorPort.IsLocalValue( dataCollector.PortCategory ) ) + return m_colorPort.LocalValue( dataCollector.PortCategory ); + + //string remapPortR = ".r"; + //string remapPortG = ".g"; + //string remapPortB = ".b"; + //string remapPortA = ".a"; + + //if ( vtex.Channel == VirtualChannel.Occlusion ) + //{ + // remapPortR = ".r"; remapPortG = ".r"; remapPortB = ".r"; remapPortA = ".r"; + //} + //else if ( vtex.Channel == VirtualChannel.SpecMet && ( ContainerGraph.CurrentStandardSurface != null && ContainerGraph.CurrentStandardSurface.CurrentLightingModel == StandardShaderLightModel.Standard ) ) + //{ + // remapPortR = ".r"; remapPortG = ".r"; remapPortB = ".r"; + //} + //else if ( vtex.Channel == VirtualChannel.Height || vtex.Channel == VirtualChannel.Displacement ) + //{ + // remapPortR = ".b"; remapPortG = ".b"; remapPortB = ".b"; remapPortA = ".b"; + //} + + dataCollector.AddToPragmas( UniqueId, IOUtils.VirtualTexturePragmaHeader ); + dataCollector.AddToIncludes( UniqueId, atPathname ); + + string lodBias = string.Empty; + if( dataCollector.IsFragmentCategory ) + { + lodBias = m_mipMode == MipType.MipLevel ? "Lod" : m_mipMode == MipType.MipBias ? "Bias" : ""; + } + else + { + lodBias = "Lod"; + } + + int virtualCoordId = dataCollector.GetVirtualCoordinatesId( UniqueId, GetVirtualUVCoords( ref dataCollector, ignoreLocalVar, portProperty ), lodBias ); + string virtualSampler = SampleVirtualTexture( vtex, Constants.VirtualCoordNameStr + virtualCoordId ); + string virtualVariable = dataCollector.AddVirtualLocalVariable( UniqueId, "virtualNode" + OutputId, virtualSampler ); + + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT4, virtualVariable, virtualSampler ); + + AddNormalMapTag( ref virtualVariable ); + + switch( vtex.Channel ) + { + default: + case VirtualChannel.Albedo: + case VirtualChannel.Base: + case VirtualChannel.Normal: + case VirtualChannel.Specular: + case VirtualChannel.SpecMet: + case VirtualChannel.Material: + virtualVariable = GetOutputColorItem( 0, outputId, virtualVariable ); + break; + case VirtualChannel.Displacement: + case VirtualChannel.Height: + { + if( outputId > 0 ) + virtualVariable += ".b"; + else + { + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT4, "virtual_cast_" + OutputId, virtualVariable + ".b" ); + virtualVariable = "virtual_cast_" + OutputId; + } + //virtualVariable = UIUtils.CastPortType( dataCollector.PortCategory, m_currentPrecisionType, new NodeCastInfo( UniqueId, outputId ), virtualVariable, WirePortDataType.FLOAT, WirePortDataType.FLOAT4, virtualVariable ); + } + break; + case VirtualChannel.Occlusion: + { + if( outputId > 0 ) + virtualVariable += ".r"; + else + { + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT4, "virtual_cast_" + OutputId, virtualVariable + ".r" ); + virtualVariable = "virtual_cast_" + OutputId; + } + } + break; + } + + //for ( int i = 0; i < m_outputPorts.Count; i++ ) + //{ + // if ( m_outputPorts[ i ].IsConnected ) + // { + + // //TODO: make the sampler not generate local variables at all times + // m_textureFetchedValue = "virtualNode" + OutputId; + // m_isTextureFetched = true; + + // //dataCollector.AddToLocalVariables( m_uniqueId, m_precisionString + " " + m_textureFetchedValue + " = " + virtualSampler + ";" ); + // if ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ) + // dataCollector.AddToVertexLocalVariables( UniqueId, m_precisionString + " " + m_textureFetchedValue + " = " + virtualSampler + ";" ); + // else + // dataCollector.AddToLocalVariables( UniqueId, m_precisionString + " " + m_textureFetchedValue + " = " + virtualSampler + ";" ); + + // m_colorPort.SetLocalValue( m_textureFetchedValue ); + // m_outputPorts[ m_colorPort.PortId + 1 ].SetLocalValue( m_textureFetchedValue + remapPortR ); + // m_outputPorts[ m_colorPort.PortId + 2 ].SetLocalValue( m_textureFetchedValue + remapPortG ); + // m_outputPorts[ m_colorPort.PortId + 3 ].SetLocalValue( m_textureFetchedValue + remapPortB ); + // m_outputPorts[ m_colorPort.PortId + 4 ].SetLocalValue( m_textureFetchedValue + remapPortA ); + // return m_textureFetchedValue; + // } + //} + + return virtualVariable; + } + } + } + + if( m_colorPort.IsLocalValue( dataCollector.PortCategory ) ) + return m_colorPort.LocalValue( dataCollector.PortCategory ); + + if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ) + { + currMipMode = MipType.MipLevel; + //mipType = "lod"; + } + + string samplerOp = SampleTexture( ref dataCollector, ignoreLocalVar, portProperty, currMipMode, propertyName ); + //string samplerOp = string.Empty; + //uvCoords = GetUVCoords( ref dataCollector, ignoreLocalVar, portProperty ); + //useMacros = m_containerGraph.SamplingThroughMacros && !mipType.Equals( "bias" ) && Constants.TexSampleStandardMacros.ContainsKey( m_currentType ); + //if( useMacros ) + //{ + // bool addLodPrefix = mipType.Equals( "lod" ); + // samplerOp = string.Format( Constants.TexSampleStandardMacros[ m_currentType ], addLodPrefix ? Constants.TexSampleLODPrefix : string.Empty, propertyName, uvCoords ); + //} + //else + //{ + // samplerOp = m_samplerType + mipType + "( " + propertyName + ", " + uvCoords + " )"; + //} + + AddNormalMapTag( ref samplerOp ); + + int connectedPorts = 0; + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + if( m_outputPorts[ i ].IsConnected ) + { + connectedPorts += 1; + if( connectedPorts > 1 || m_outputPorts[ i ].ConnectionCount > 1 ) + { + // Create common local var and mark as fetched + string textureFetchedValue = m_samplerType + "Node" + OutputId; + + if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ) + dataCollector.AddToVertexLocalVariables( UniqueId, m_precisionString + " " + textureFetchedValue + " = " + samplerOp + ";" ); + else + dataCollector.AddToLocalVariables( UniqueId, m_precisionString + " " + textureFetchedValue + " = " + samplerOp + ";" ); + + + m_colorPort.SetLocalValue( textureFetchedValue, dataCollector.PortCategory ); + m_outputPorts[ m_colorPort.PortId + 1 ].SetLocalValue( textureFetchedValue + ".r", dataCollector.PortCategory ); + m_outputPorts[ m_colorPort.PortId + 2 ].SetLocalValue( textureFetchedValue + ".g", dataCollector.PortCategory ); + m_outputPorts[ m_colorPort.PortId + 3 ].SetLocalValue( textureFetchedValue + ".b", dataCollector.PortCategory ); + m_outputPorts[ m_colorPort.PortId + 4 ].SetLocalValue( textureFetchedValue + ".a", dataCollector.PortCategory ); + return textureFetchedValue; + } + } + } + return samplerOp; + } + + private void AddNormalMapTag( ref string value ) + { + if( m_autoUnpackNormals ) + { + value = string.Format( m_normalMapUnpackMode, value ); + } + } + + public override void ReadOutputDataFromString( ref string[] nodeParams ) + { + base.ReadOutputDataFromString( ref nodeParams ); + ConfigureOutputPorts(); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + string defaultTextureGUID = GetCurrentParam( ref nodeParams ); + if( UIUtils.CurrentShaderVersion() > 14101 ) + { + m_defaultValue = AssetDatabase.LoadAssetAtPath<Texture>( AssetDatabase.GUIDToAssetPath( defaultTextureGUID ) ); + string materialTextureGUID = GetCurrentParam( ref nodeParams ); + m_materialValue = AssetDatabase.LoadAssetAtPath<Texture>( AssetDatabase.GUIDToAssetPath( materialTextureGUID ) ); + } + else + { + m_defaultValue = AssetDatabase.LoadAssetAtPath<Texture>( defaultTextureGUID ); + } + m_useSemantics = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_textureCoordSet = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_isNormalMap = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_defaultTextureValue = (TexturePropertyValues)Enum.Parse( typeof( TexturePropertyValues ), GetCurrentParam( ref nodeParams ) ); + m_autocastMode = (AutoCastType)Enum.Parse( typeof( AutoCastType ), GetCurrentParam( ref nodeParams ) ); + m_autoUnpackNormals = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + + if( UIUtils.CurrentShaderVersion() > 12 ) + { + m_referenceType = (TexReferenceType)Enum.Parse( typeof( TexReferenceType ), GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > 22 ) + { + m_referenceNodeId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + else + { + m_referenceArrayId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + + if( m_referenceType == TexReferenceType.Instance ) + { + UIUtils.UnregisterSamplerNode( this ); + UIUtils.UnregisterPropertyNode( this ); + } + UpdateHeaderColor(); + } + if( UIUtils.CurrentShaderVersion() > 2406 ) + m_mipMode = (MipType)Enum.Parse( typeof( MipType ), GetCurrentParam( ref nodeParams ) ); + + + if( UIUtils.CurrentShaderVersion() > 3201 ) + m_currentType = (TextureType)Enum.Parse( typeof( TextureType ), GetCurrentParam( ref nodeParams ) ); + + if( m_defaultValue == null ) + { + ConfigureInputPorts(); + ConfigureOutputPorts(); + //ResizeNodeToPreview(); + } + else + { + if( m_materialValue == null ) + { + ConfigFromObject( m_defaultValue, false, false ); + } + else + { + CheckTextureImporter( false, false ); + } + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + + if( !m_isNodeBeingCopied && m_referenceType == TexReferenceType.Object ) + { + ContainerGraph.SamplerNodes.UpdateDataOnNode( UniqueId, DataToArray ); + } + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + ForceInputPortsChange(); + + if( m_useSamplerArrayIdx > -1 ) + { + m_useSamplerArrayIdx = UIUtils.GetTexturePropertyNodeRegisterId( m_useSamplerArrayIdx ) + 1; + } + else + { + m_useSamplerArrayIdx = 0; + } + + EditorGUI.BeginChangeCheck(); + if( m_referenceType == TexReferenceType.Instance ) + { + if( UIUtils.CurrentShaderVersion() > 22 ) + { + + + m_referenceSampler = ContainerGraph.GetNode( m_referenceNodeId ) as SamplerNode; + m_referenceArrayId = ContainerGraph.SamplerNodes.GetNodeRegisterIdx( m_referenceNodeId ); + } + else + { + m_referenceSampler = ContainerGraph.SamplerNodes.GetNode( m_referenceArrayId ); + if( m_referenceSampler != null ) + { + m_referenceNodeId = m_referenceSampler.UniqueId; + } + } + } + + if( EditorGUI.EndChangeCheck() ) + { + OnPropertyNameChanged(); + } + } + + public override void ReadAdditionalData( ref string[] nodeParams ) { } + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_defaultValue != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_defaultValue ) ) : Constants.NoStringValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_materialValue != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_materialValue ) ) : Constants.NoStringValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_useSemantics.ToString() ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_textureCoordSet.ToString() ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_isNormalMap.ToString() ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_defaultTextureValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autocastMode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autoUnpackNormals ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_referenceType ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( ( m_referenceSampler != null ) ? m_referenceSampler.UniqueId : -1 ) ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_mipMode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentType ); + } + + public override void WriteAdditionalToString( ref string nodeInfo, ref string connectionsInfo ) { } + + public string GetVirtualUVCoords( ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar, string portProperty ) + { + string bias = ""; + if( !dataCollector.IsFragmentCategory || m_mipMode == MipType.MipBias || m_mipMode == MipType.MipLevel ) + { + string lodLevel = m_lodPort.GeneratePortInstructions( ref dataCollector ); + bias += ", " + lodLevel; + } + + if( m_uvPort.IsConnected ) + { + string uvs = m_uvPort.GeneratePortInstructions( ref dataCollector ); + return uvs + bias; + } + else + { + string propertyName = CurrentPropertyReference; + if( !string.IsNullOrEmpty( portProperty ) ) + { + propertyName = portProperty; + } + string uvChannelName = IOUtils.GetUVChannelName( propertyName, m_textureCoordSet ); + + + string uvCoord = string.Empty; + if( dataCollector.IsTemplate ) + { + string uvName = string.Empty; + if( dataCollector.TemplateDataCollectorInstance.HasUV( m_textureCoordSet ) ) + { + uvName = dataCollector.TemplateDataCollectorInstance.GetUVName( m_textureCoordSet, m_uvPort.DataType ); + } + else + { + uvName = dataCollector.TemplateDataCollectorInstance.RegisterUV( m_textureCoordSet, m_uvPort.DataType ); + } + + string attr = GetPropertyValue(); + + if( attr.IndexOf( "[NoScaleOffset]" ) > -1 ) + { + dataCollector.AddLocalVariable( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvChannelName, uvName ); + } + else + { + dataCollector.AddToUniforms( UniqueId, "uniform float4 " + propertyName + "_ST;" ); + dataCollector.AddLocalVariable( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvChannelName, uvName + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw" ); + } + uvCoord = uvChannelName; + } + else + { + if( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ) + { + uvCoord = Constants.VertexShaderInputStr + ".texcoord"; + if( m_textureCoordSet > 0 ) + { + uvCoord += m_textureCoordSet.ToString(); + } + } + else + { + propertyName = CurrentPropertyReference; + if( !string.IsNullOrEmpty( portProperty ) && portProperty != "0.0" ) + { + propertyName = portProperty; + } + uvChannelName = IOUtils.GetUVChannelName( propertyName, m_textureCoordSet ); + + string dummyPropUV = "_texcoord" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ); + string dummyUV = "uv" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ) + dummyPropUV; + + dataCollector.AddToProperties( UniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 100 ); + dataCollector.AddToInput( UniqueId, dummyUV, WirePortDataType.FLOAT2 ); + + string attr = GetPropertyValue(); + + if( attr.IndexOf( "[NoScaleOffset]" ) > -1 ) + { + dataCollector.AddToLocalVariables( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvChannelName, Constants.InputVarStr + "." + dummyUV ); + } + else + { + dataCollector.AddToUniforms( UniqueId, "uniform float4 " + propertyName + "_ST;" ); + dataCollector.AddToLocalVariables( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvChannelName, Constants.InputVarStr + "." + dummyUV + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw" ); + } + uvCoord = uvChannelName; + } + } + return uvCoord + bias; + } + } + + public string GetUVCoords( ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar, string portProperty ) + { + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + + // make sure the final result is always a float4 with empty 0's in the middle + string uvAppendix = ", "; + int coordSize = 3; + if( m_uvPort.DataType == WirePortDataType.FLOAT2 ) + { + uvAppendix = ", 0, "; + coordSize = 2; + } + else if( m_uvPort.DataType == WirePortDataType.FLOAT ) + { + uvAppendix = ", 0, 0, "; + coordSize = 1; + } + + string uvs = m_uvPort.GeneratePortInstructions( ref dataCollector ); + + // generate automatic UVs if not connected + if( !m_uvPort.IsConnected ) + { + string propertyName = CurrentPropertyReference; + + // check for references + if( !string.IsNullOrEmpty( portProperty ) && portProperty != "0.0" ) + propertyName = portProperty; + + int coordSet = ( ( m_textureCoordSet < 0 ) ? 0 : m_textureCoordSet ); + string uvName = IOUtils.GetUVChannelName( propertyName, coordSet ); + string dummyPropUV = "_tex" + ( coordSize != 2 ? "" + coordSize : "" ) + "coord" + ( coordSet > 0 ? ( coordSet + 1 ).ToString() : "" ); + string dummyUV = "uv" + ( coordSet > 0 ? ( coordSet + 1 ).ToString() : "" ) + dummyPropUV; + + string attr = GetPropertyValue(); + bool scaleOffset = true; + if( attr.IndexOf( "[NoScaleOffset]" ) > -1 ) + scaleOffset = false; + + string texCoordsST = string.Empty; + if( scaleOffset ) + { + if( m_texCoordsHelper == null ) + { + m_texCoordsHelper = CreateInstance<Vector4Node>(); + m_texCoordsHelper.ContainerGraph = ContainerGraph; + m_texCoordsHelper.SetBaseUniqueId( UniqueId, true ); + m_texCoordsHelper.RegisterPropertyOnInstancing = false; + m_texCoordsHelper.AddGlobalToSRPBatcher = true; + } + + if( UIUtils.CurrentWindow.OutsideGraph.IsInstancedShader ) + { + m_texCoordsHelper.CurrentParameterType = PropertyType.InstancedProperty; + } + else + { + m_texCoordsHelper.CurrentParameterType = PropertyType.Global; + } + m_texCoordsHelper.ResetOutputLocals(); + m_texCoordsHelper.SetRawPropertyName( propertyName + "_ST" ); + texCoordsST = m_texCoordsHelper.GenerateShaderForOutput( 0, ref dataCollector, false ); + } + + string coordInput = string.Empty; + if( !dataCollector.IsTemplate && coordSet > 3 ) + { + coordInput = GeneratorUtils.GenerateAutoUVs( ref dataCollector, UniqueId, coordSet, null, WirePortDataType.FLOAT2 ); + } + else + { + dataCollector.AddToProperties( UniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 9999 ); + if( isVertex ) + { + coordInput = Constants.VertexShaderInputStr + ".texcoord"; + if( coordSet > 0 ) + coordInput += coordSet.ToString(); + } + else + { + coordInput = Constants.InputVarStr + "." + dummyUV; + dataCollector.AddToInput( UniqueId, dummyUV, m_uvPort.DataType ); + } + } + + if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template ) + { + if( dataCollector.TemplateDataCollectorInstance.HasUV( m_textureCoordSet ) ) + coordInput = dataCollector.TemplateDataCollectorInstance.GetUVName( m_textureCoordSet, m_uvPort.DataType ); + else + coordInput = dataCollector.TemplateDataCollectorInstance.RegisterUV( m_textureCoordSet, m_uvPort.DataType ); + } + + if( !scaleOffset ) + uvName += OutputId; + + if( coordSize > 2 ) + { + uvName += coordSize; + dataCollector.UsingHigherSizeTexcoords = true; + dataCollector.AddLocalVariable( UniqueId, "float" + coordSize + " " + uvName + " = " + coordInput + ";" ); + if( scaleOffset ) + dataCollector.AddLocalVariable( UniqueId, uvName + ".xy = " + coordInput + ".xy * " + texCoordsST + ".xy + " + texCoordsST + ".zw;" ); + } + else + { + if( coordSize == 1 ) + uvName += coordSize; + + if( scaleOffset ) + dataCollector.AddLocalVariable( UniqueId, PrecisionType.Float, m_uvPort.DataType, uvName, coordInput + " * " + texCoordsST + ".xy + " + texCoordsST + ".zw" ); + else + dataCollector.AddLocalVariable( UniqueId, PrecisionType.Float, m_uvPort.DataType, uvName, coordInput ); + } + + uvs = uvName; + } + + ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph; + if( isVertex ) + { + string lodLevel = m_lodPort.GeneratePortInstructions( ref dataCollector ); + if( outsideGraph.SamplingThroughMacros ) + return uvs + "," + lodLevel; + else + return UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT4 ) + "( " + uvs + uvAppendix + lodLevel + ")"; + } + else + { + if( ( m_mipMode == MipType.MipLevel || m_mipMode == MipType.MipBias ) && m_lodPort.IsConnected ) + { + string lodLevel = m_lodPort.GeneratePortInstructions( ref dataCollector ); + if( outsideGraph.SamplingThroughMacros ) + return uvs + "," + lodLevel; + else + return UIUtils.PrecisionWirePortToCgType( PrecisionType.Float, WirePortDataType.FLOAT4 ) + "( " + uvs + uvAppendix + lodLevel + ")"; + } + else if( m_mipMode == MipType.Derivative ) + { + string ddx = m_ddxPort.GeneratePortInstructions( ref dataCollector ); + string ddy = m_ddyPort.GeneratePortInstructions( ref dataCollector ); + + return uvs + ", " + ddx + ", " + ddy; + } + else + { + return uvs; + } + } + } + + + + public override int VersionConvertInputPortId( int portId ) + { + int newPort = portId; + //change normal scale port to last + if( UIUtils.CurrentShaderVersion() < 2407 ) + { + if( portId == 1 ) + newPort = 4; + } + + if( UIUtils.CurrentShaderVersion() < 2408 ) + { + newPort = newPort + 1; + } + + return newPort; + } + + public override void Destroy() + { + base.Destroy(); + + //Not calling m_texCoordsHelper.Destroy() on purpose so UIUtils does not incorrectly unregister stuff + if( m_texCoordsHelper != null ) + { + DestroyImmediate( m_texCoordsHelper ); + m_texCoordsHelper = null; + } + + m_samplerStateAutoGenerator.Destroy(); + m_samplerStateAutoGenerator = null; + m_defaultValue = null; + m_materialValue = null; + m_referenceSampler = null; + m_referenceStyle = null; + m_referenceContent = null; + m_texPort = null; + m_uvPort = null; + m_lodPort = null; + m_ddxPort = null; + m_ddyPort = null; + m_normalPort = null; + m_colorPort = null; + + if( m_referenceType == TexReferenceType.Object ) + { + UIUtils.UnregisterSamplerNode( this ); + UIUtils.UnregisterPropertyNode( this ); + } + if( UniqueId > -1 ) + ContainerGraph.SamplerNodes.OnReorderEventComplete -= OnReorderEventComplete; + } + + public override string GetPropertyValStr() + { + return m_materialMode ? ( m_materialValue != null ? m_materialValue.name : IOUtils.NO_TEXTURES ) : ( m_defaultValue != null ? m_defaultValue.name : IOUtils.NO_TEXTURES ); + } + + public TexturePropertyNode TextureProperty + { + get + { + if( m_referenceSampler != null ) + { + m_textureProperty = m_referenceSampler as TexturePropertyNode; + } + else if( m_texPort.IsConnected ) + { + m_textureProperty = m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode; + } + + if( m_textureProperty == null ) + return this; + + return m_textureProperty; + } + } + + public override string GetPropertyValue() + { + if( SoftValidReference ) + { + if( m_referenceSampler.TexPort.IsConnected ) + { + return string.Empty; + } + else + { + return m_referenceSampler.TextureProperty.GetPropertyValue(); + } + } + else + if( m_texPort.IsConnected && ( m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode ) != null ) + { + return TextureProperty.GetPropertyValue(); + } + + switch( m_currentType ) + { + case TextureType.Texture1D: + { + return PropertyAttributes + GetTexture1DPropertyValue(); + } + case TextureType.ProceduralTexture: + case TextureType.Texture2D: + { + return PropertyAttributes + GetTexture2DPropertyValue(); + } + case TextureType.Texture3D: + { + return PropertyAttributes + GetTexture3DPropertyValue(); + } + case TextureType.Cube: + { + return PropertyAttributes + GetCubePropertyValue(); + } + } + return string.Empty; + } + + public override string GetUniformValue() + { + + if( SoftValidReference ) + { + if( m_referenceSampler.TexPort.IsConnected ) + return string.Empty; + else + return m_referenceSampler.TextureProperty.GetUniformValue(); + } + else if( m_texPort.IsConnected && ( m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode ) != null ) + { + return TextureProperty.GetUniformValue(); + } + + return base.GetUniformValue(); + } + + public override bool GetUniformData( out string dataType, out string dataName, ref bool fullValue ) + { + if( SoftValidReference ) + { + if( m_referenceSampler.TexPort.IsConnected ) + { + base.GetUniformData( out dataType, out dataName, ref fullValue ); + return false; + } + else + return m_referenceSampler.TextureProperty.GetUniformData( out dataType, out dataName, ref fullValue ); + } + else if( m_texPort.IsConnected && ( m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode ) != null ) + { + return TextureProperty.GetUniformData( out dataType, out dataName, ref fullValue ); + + } + + return base.GetUniformData( out dataType, out dataName, ref fullValue ); + } + + public string UVCoordsName { get { return Constants.InputVarStr + "." + IOUtils.GetUVChannelName( CurrentPropertyReference, m_textureCoordSet ); } } + public bool HasPropertyReference + { + get + { + if( m_referenceType == TexReferenceType.Instance && m_referenceArrayId > -1 ) + { + SamplerNode node = ContainerGraph.SamplerNodes.GetNode( m_referenceArrayId ); + if( node != null ) + return true; + } + + if( m_texPort.IsConnected ) + { + return true; + } + + return false; + } + } + + public override string CurrentPropertyReference + { + get + { + string propertyName = string.Empty; + if( m_referenceType == TexReferenceType.Instance && m_referenceArrayId > -1 ) + { + SamplerNode node = ContainerGraph.SamplerNodes.GetNode( m_referenceArrayId ); + propertyName = ( node != null ) ? node.TextureProperty.PropertyName : PropertyName; + } + else if( m_texPort.IsConnected && ( m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode ) != null ) + { + propertyName = TextureProperty.PropertyName; + } + else + { + propertyName = PropertyName; + } + return propertyName; + } + } + + public bool SoftValidReference + { + get + { + if( m_referenceType == TexReferenceType.Instance && m_referenceArrayId > -1 ) + { + m_referenceSampler = ContainerGraph.SamplerNodes.GetNode( m_referenceArrayId ); + + m_texPort.Locked = true; + + if( m_referenceContent == null ) + m_referenceContent = new GUIContent(); + + + if( m_referenceSampler != null ) + { + m_referenceContent.image = m_referenceSampler.Value; + if( m_referenceWidth != m_referenceSampler.Position.width ) + { + m_referenceWidth = m_referenceSampler.Position.width; + m_sizeIsDirty = true; + } + } + else + { + m_referenceArrayId = -1; + m_referenceWidth = -1; + } + + return m_referenceSampler != null; + } + m_texPort.Locked = false; + return false; + } + } + public override void ForceUpdateFromMaterial( Material material ) + { + if( UIUtils.IsProperty( m_currentParameterType ) && material.HasProperty( PropertyName ) ) + { + m_materialValue = material.GetTexture( PropertyName ); + CheckTextureImporter( true ); + PreviewIsDirty = true; + } + + } + public override void SetContainerGraph( ParentGraph newgraph ) + { + base.SetContainerGraph( newgraph ); + m_textureProperty = m_texPort.GetOutputNodeWhichIsNotRelay( 0 ) as TexturePropertyNode; + if( m_textureProperty == null ) + { + m_textureProperty = this; + } + } + + public bool AutoUnpackNormals + { + get { return m_autoUnpackNormals; } + set + { + if( value != m_autoUnpackNormals ) + { + m_autoUnpackNormals = value; + if( !UIUtils.IsLoading ) + { + m_defaultTextureValue = value ? TexturePropertyValues.bump : TexturePropertyValues.white; + } + } + } + } + + public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + { + base.PropagateNodeData( nodeData, ref dataCollector ); + if( dataCollector.IsTemplate ) + { + if( !m_texPort.IsConnected ) + dataCollector.TemplateDataCollectorInstance.SetUVUsage( m_textureCoordSet, m_uvPort.DataType ); + } + else if( m_textureCoordSet > 3 ) + { + dataCollector.AddCustomAppData( string.Format( TemplateHelperFunctions.TexUVFullSemantic, m_textureCoordSet ) ); + } + } + + private InputPort TexPort { get { return m_texPort; } } + public bool IsObject { get { return ( m_referenceType == TexReferenceType.Object ) || ( m_referenceSampler == null ); } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SamplerNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SamplerNode.cs.meta new file mode 100644 index 00000000..87957e47 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SamplerNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 057d23b232d9c044cbf3f1d0b1a06909 +timeCreated: 1481126953 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs new file mode 100644 index 00000000..cc93bf0e --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs @@ -0,0 +1,1330 @@ +// 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; +#if !UNITY_2018_1_OR_NEWER +namespace AmplifyShaderEditor +{ + // Disabling Substance Deprecated warning +#pragma warning disable 0618 + [Serializable] + [NodeAttributes( "Substance Sample", "Textures", "Samples a procedural material", KeyCode.None, true, 0, int.MaxValue, typeof( SubstanceArchive ), typeof( ProceduralMaterial ) )] + public sealed class SubstanceSamplerNode : PropertyNode + { + private const string GlobalVarDecStr = "uniform sampler2D {0};"; + private const string PropertyDecStr = "{0}(\"{0}\", 2D) = \"white\""; + + private const string AutoNormalStr = "Auto-Normal"; + private const string SubstanceStr = "Substance"; + + private float TexturePreviewSizeX = 128; + private float TexturePreviewSizeY = 128; + + private float PickerPreviewWidthAdjust = 18; + + private bool m_editing; + + private CacheNodeConnections m_cacheNodeConnections; + + [SerializeField] + private int m_firstOutputConnected = 0; + + [SerializeField] + private ProceduralMaterial m_proceduralMaterial; + + [SerializeField] + private int m_textureCoordSet = 0; + + [SerializeField] + private ProceduralOutputType[] m_textureTypes; + + [SerializeField] + private bool m_autoNormal = true; + + private System.Type m_type; + + private Texture[] m_textures = new Texture[] { }; + + private List<int> m_outputConns = new List<int>(); + + private Rect m_previewArea; + + private Rect m_pickerArea; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ); + AddOutputPort( WirePortDataType.COLOR, Constants.EmptyPortValue ); + m_insideSize.Set( TexturePreviewSizeX + PickerPreviewWidthAdjust, TexturePreviewSizeY + 10 ); + m_type = typeof( ProceduralMaterial ); + m_currentParameterType = PropertyType.Property; + m_freeType = false; + m_freeName = false; + m_autoWrapProperties = true; + m_customPrefix = "Substance Sample "; + m_drawPrecisionUI = false; + m_showPreview = true; + m_drawPreviewExpander = false; + m_selectedLocation = PreviewLocation.TopCenter; + m_cacheNodeConnections = new CacheNodeConnections(); + m_previewShaderGUID = "6f322c1da33f1e744941aafcb0ad1a2d"; + m_showAutoRegisterUI = false; + } + + public override void RenderNodePreview() + { + //Runs at least one time + if( !m_initialized ) + { + // nodes with no preview don't update at all + PreviewIsDirty = false; + return; + } + + if( !PreviewIsDirty ) + return; + + SetPreviewInputs(); + + PreviewMaterial.SetInt( "_CustomUVs", m_inputPorts[ 0 ].IsConnected ? 1 : 0 ); + + if( m_proceduralMaterial == null ) + return; + + Texture[] texs = m_proceduralMaterial.GetGeneratedTextures(); + int count = m_outputPorts.Count; + for( int i = 0; i < count; i++ ) + { + RenderTexture temp = RenderTexture.active; + RenderTexture.active = m_outputPorts[ i ].OutputPreviewTexture; + + PreviewMaterial.SetTexture( "_GenTex", texs[ i ] ); + + if( m_autoNormal && m_textureTypes[ i ] == ProceduralOutputType.Normal ) + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, 1 ); + else + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, 0 ); + RenderTexture.active = temp; + } + + PreviewIsDirty = m_continuousPreviewRefresh; + } + + public override void OnOutputPortConnected( int portId, int otherNodeId, int otherPortId ) + { + base.OnOutputPortConnected( portId, otherNodeId, otherPortId ); + m_firstOutputConnected = -1; + } + + public override void OnOutputPortDisconnected( int portId ) + { + base.OnOutputPortDisconnected( portId ); + m_firstOutputConnected = -1; + } + + void CalculateFirstOutputConnected() + { + m_outputConns.Clear(); + int count = m_outputPorts.Count; + bool connectionsAvailable = false; + for( int i = 0; i < count; i++ ) + { + if( m_outputPorts[ i ].IsConnected ) + { + connectionsAvailable = true; + } + } + + for( int i = 0; i < count; i++ ) + { + if( connectionsAvailable ) + { + if( m_outputPorts[ i ].IsConnected ) + { + if( m_firstOutputConnected < 0 ) + m_firstOutputConnected = i; + + m_outputConns.Add( i ); + } + } + else + { + m_outputConns.Add( i ); + } + } + + if( m_firstOutputConnected < 0 ) + m_firstOutputConnected = 0; + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + base.OnNodeLayout( drawInfo ); + + m_previewArea = m_remainingBox; + m_previewArea.width = TexturePreviewSizeX * drawInfo.InvertedZoom; + m_previewArea.height = TexturePreviewSizeY * drawInfo.InvertedZoom; + m_previewArea.x += 0.5f * m_remainingBox.width - 0.5f * m_previewArea.width; + m_pickerArea = m_previewArea; + m_pickerArea.width = 40 * drawInfo.InvertedZoom; + m_pickerArea.x = m_previewArea.xMax - m_pickerArea.width - 2; + m_pickerArea.height = 14 * drawInfo.InvertedZoom; + m_pickerArea.y = m_previewArea.yMax - m_pickerArea.height - 2; + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + base.DrawGUIControls( drawInfo ); + + if( !( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp || drawInfo.CurrentEventType == EventType.ExecuteCommand || drawInfo.CurrentEventType == EventType.DragPerform ) ) + return; + + bool insideBox = m_previewArea.Contains( drawInfo.MousePosition ); + + if( insideBox ) + { + m_editing = true; + } + else if( m_editing && !insideBox && drawInfo.CurrentEventType != EventType.ExecuteCommand ) + { + GUI.FocusControl( null ); + m_editing = false; + } + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + if( m_editing ) + { + m_textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + if( GUI.Button( m_pickerArea, string.Empty, GUIStyle.none ) ) + { + int controlID = EditorGUIUtility.GetControlID( FocusType.Passive ); + EditorGUIUtility.ShowObjectPicker<ProceduralMaterial>( m_proceduralMaterial, false, "", controlID ); + } + + string commandName = Event.current.commandName; + UnityEngine.Object newValue = null; + if( commandName == "ObjectSelectorUpdated" ) + { + newValue = EditorGUIUtility.GetObjectPickerObject(); + if( newValue != (UnityEngine.Object)m_proceduralMaterial ) + { + PreviewIsDirty = true; + UndoRecordObject( "Changing value EditorGUIObjectField on node Substance Sample" ); + + m_proceduralMaterial = newValue != null ? (ProceduralMaterial)newValue : null; + m_textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + OnNewSubstanceSelected( m_textures ); + } + } + else if( commandName == "ObjectSelectorClosed" ) + { + newValue = EditorGUIUtility.GetObjectPickerObject(); + if( newValue != (UnityEngine.Object)m_proceduralMaterial ) + { + PreviewIsDirty = true; + UndoRecordObject( "Changing value EditorGUIObjectField on node Substance Sample" ); + + m_proceduralMaterial = newValue != null ? (ProceduralMaterial)newValue : null; + m_textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + OnNewSubstanceSelected( m_textures ); + } + m_editing = false; + } + + if( GUI.Button( m_previewArea, string.Empty, GUIStyle.none ) ) + { + if( m_proceduralMaterial != null ) + { + Selection.activeObject = m_proceduralMaterial; + EditorGUIUtility.PingObject( Selection.activeObject ); + } + m_editing = false; + } + } + + if( drawInfo.CurrentEventType == EventType.Repaint ) + { + if( !m_editing ) + m_textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + + if( m_textures != null ) + { + if( m_firstOutputConnected < 0 ) + { + CalculateFirstOutputConnected(); + } + else if( m_textures.Length != m_textureTypes.Length ) + { + OnNewSubstanceSelected( m_textures ); + } + + int texCount = m_outputConns.Count; + Rect individuals = m_previewArea; + individuals.height /= texCount; + + for( int i = 0; i < texCount; i++ ) + { + EditorGUI.DrawPreviewTexture( individuals, m_textures[ m_outputConns[ i ] ], null, ScaleMode.ScaleAndCrop ); + individuals.y += individuals.height; + } + } + else + { + GUI.Label( m_previewArea, string.Empty, UIUtils.ObjectFieldThumb ); + } + + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 ) + { + Rect smallButton = m_previewArea; + smallButton.height = 14 * drawInfo.InvertedZoom; + smallButton.y = m_previewArea.yMax - smallButton.height - 2; + smallButton.width = 40 * drawInfo.InvertedZoom; + smallButton.x = m_previewArea.xMax - smallButton.width - 2; + if( m_textures == null ) + { + GUI.Label( m_previewArea, "None (Procedural Material)", UIUtils.ObjectFieldThumbOverlay ); + } + GUI.Label( m_pickerArea, "Select", UIUtils.GetCustomStyle( CustomStyle.SamplerButton ) ); + } + + GUI.Label( m_previewArea, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) ); + } + } + + void OnNewSubstanceSelected( Texture[] textures ) + { + CacheCurrentSettings(); + ConfigPortsFromMaterial( true, textures ); + ConnectFromCache(); + m_requireMaterialUpdate = true; + CalculateFirstOutputConnected(); + ContainerGraph.ParentWindow.RequestRepaint(); + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUI.BeginChangeCheck(); + m_proceduralMaterial = EditorGUILayoutObjectField( SubstanceStr, m_proceduralMaterial, m_type, false ) as ProceduralMaterial; + if( EditorGUI.EndChangeCheck() ) + { + Texture[] textures = m_proceduralMaterial != null ? m_proceduralMaterial.GetGeneratedTextures() : null; + if( textures != null ) + { + OnNewSubstanceSelected( textures ); + } + } + + m_textureCoordSet = EditorGUILayoutIntPopup( Constants.AvailableUVSetsLabel, m_textureCoordSet, Constants.AvailableUVSetsStr, Constants.AvailableUVSets ); + EditorGUI.BeginChangeCheck(); + m_autoNormal = EditorGUILayoutToggle( AutoNormalStr, m_autoNormal ); + if( EditorGUI.EndChangeCheck() ) + { + for( int i = 0; i < m_textureTypes.Length; i++ ) + { + WirePortDataType portType = ( m_autoNormal && m_textureTypes[ i ] == ProceduralOutputType.Normal ) ? WirePortDataType.FLOAT3 : WirePortDataType.COLOR; + if( m_outputPorts[ i ].DataType != portType ) + { + m_outputPorts[ i ].ChangeType( portType, false ); + } + } + } + } + + private void CacheCurrentSettings() + { + m_cacheNodeConnections.Clear(); + for( int portId = 0; portId < m_outputPorts.Count; portId++ ) + { + if( m_outputPorts[ portId ].IsConnected ) + { + int connCount = m_outputPorts[ portId ].ConnectionCount; + for( int connIdx = 0; connIdx < connCount; connIdx++ ) + { + WireReference connection = m_outputPorts[ portId ].GetConnection( connIdx ); + m_cacheNodeConnections.Add( m_outputPorts[ portId ].Name, new NodeCache( connection.NodeId, connection.PortId ) ); + } + } + } + } + + private void ConnectFromCache() + { + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + List<NodeCache> connections = m_cacheNodeConnections.GetList( m_outputPorts[ i ].Name ); + if( connections != null ) + { + int count = connections.Count; + for( int connIdx = 0; connIdx < count; connIdx++ ) + { + UIUtils.SetConnection( connections[ connIdx ].TargetNodeId, connections[ connIdx ].TargetPortId, UniqueId, i ); + } + } + } + } + + + private void ConfigPortsFromMaterial( bool invalidateConnections = false, Texture[] newTextures = null ) + { + SetAdditonalTitleText( ( m_proceduralMaterial != null ) ? string.Format( Constants.PropertyValueLabel, m_proceduralMaterial.name ) : "Value( <None> )" ); + + Texture[] textures = newTextures != null ? newTextures : ( ( m_proceduralMaterial != null ) ? m_proceduralMaterial.GetGeneratedTextures() : null ); + if( textures != null ) + { + m_firstOutputConnected = -1; + string nameToRemove = m_proceduralMaterial.name + "_"; + m_textureTypes = new ProceduralOutputType[ textures.Length ]; + for( int i = 0; i < textures.Length; i++ ) + { + ProceduralTexture procTex = textures[ i ] as ProceduralTexture; + m_textureTypes[ i ] = procTex.GetProceduralOutputType(); + + WirePortDataType portType = ( m_autoNormal && m_textureTypes[ i ] == ProceduralOutputType.Normal ) ? WirePortDataType.FLOAT3 : WirePortDataType.COLOR; + string newName = textures[ i ].name.Replace( nameToRemove, string.Empty ); + char firstLetter = Char.ToUpper( newName[ 0 ] ); + newName = firstLetter.ToString() + newName.Substring( 1 ); + if( i < m_outputPorts.Count ) + { + m_outputPorts[ i ].ChangeProperties( newName, portType, false ); + if( invalidateConnections ) + { + m_outputPorts[ i ].FullDeleteConnections(); + } + } + else + { + AddOutputPort( portType, newName ); + } + } + + if( textures.Length < m_outputPorts.Count ) + { + int itemsToRemove = m_outputPorts.Count - textures.Length; + for( int i = 0; i < itemsToRemove; i++ ) + { + int idx = m_outputPorts.Count - 1; + if( m_outputPorts[ idx ].IsConnected ) + { + m_outputPorts[ idx ].ForceClearConnection(); + } + RemoveOutputPort( idx ); + } + } + } + else + { + int itemsToRemove = m_outputPorts.Count - 1; + m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.COLOR, false ); + m_outputPorts[ 0 ].ForceClearConnection(); + + for( int i = 0; i < itemsToRemove; i++ ) + { + int idx = m_outputPorts.Count - 1; + if( m_outputPorts[ idx ].IsConnected ) + { + m_outputPorts[ idx ].ForceClearConnection(); + } + RemoveOutputPort( idx ); + } + } + + m_sizeIsDirty = true; + m_isDirty = true; + } + + private void ConfigFromObject( UnityEngine.Object obj ) + { + ProceduralMaterial newMat = AssetDatabase.LoadAssetAtPath<ProceduralMaterial>( AssetDatabase.GetAssetPath( obj ) ); + if( newMat != null ) + { + m_proceduralMaterial = newMat; + ConfigPortsFromMaterial(); + } + } + + public override void OnObjectDropped( UnityEngine.Object obj ) + { + ConfigFromObject( obj ); + } + + public override void SetupFromCastObject( UnityEngine.Object obj ) + { + ConfigFromObject( obj ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_proceduralMaterial == null ) + { + return "(0).xxxx"; + } + + if( m_outputPorts[ outputId ].IsLocalValue( dataCollector.PortCategory ) ) + { + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + Texture[] textures = m_proceduralMaterial.GetGeneratedTextures(); + + string uvPropertyName = string.Empty; + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + if( m_outputPorts[ i ].HasConnectedNode ) + { + uvPropertyName = textures[ i ].name; + break; + } + } + + string name = textures[ outputId ].name + OutputId; + dataCollector.AddToUniforms( UniqueId, string.Format( GlobalVarDecStr, textures[ outputId ].name ) ); + dataCollector.AddToProperties( UniqueId, string.Format( PropertyDecStr, textures[ outputId ].name ) + "{}", -1 ); + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + string value = string.Format( "tex2D{0}({1}, {2})", ( isVertex ? "lod" : string.Empty ), textures[ outputId ].name, GetUVCoords( ref dataCollector, ignoreLocalvar, uvPropertyName ) ); + if( m_autoNormal && m_textureTypes[ outputId ] == ProceduralOutputType.Normal ) + { + value = string.Format( TemplateHelperFunctions.CreateUnpackNormalStr( dataCollector,false,"1.0"), value ); + } + + dataCollector.AddPropertyNode( this ); + RegisterLocalVariable( outputId, value, ref dataCollector, name ); + + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + public string GetUVCoords( ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar, string propertyName ) + { + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + if( m_inputPorts[ 0 ].IsConnected ) + { + return m_inputPorts[ 0 ].GenerateShaderForOutput( ref dataCollector, isVertex ? WirePortDataType.FLOAT4 : WirePortDataType.FLOAT2, ignoreLocalVar, true ); + } + else + { + string uvChannelName = IOUtils.GetUVChannelName( propertyName, m_textureCoordSet ); + + if( dataCollector.IsTemplate ) + { + string propertyHelperVar = propertyName + "_ST"; + dataCollector.AddToUniforms( UniqueId, "float4", propertyHelperVar, dataCollector.IsSRP ); + string uvName = string.Empty; + if( dataCollector.TemplateDataCollectorInstance.HasUV( m_textureCoordSet ) ) + { + uvName = dataCollector.TemplateDataCollectorInstance.GetUVName( m_textureCoordSet ); + } + else + { + uvName = dataCollector.TemplateDataCollectorInstance.RegisterUV( m_textureCoordSet ); + } + + uvChannelName = "uv" + propertyName; + if( isVertex ) + { + string value = string.Format( Constants.TilingOffsetFormat, uvName, propertyHelperVar + ".xy", propertyHelperVar + ".zw" ); + string lodLevel = "0"; + + value = "float4( " + value + ", 0 , " + lodLevel + " )"; + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT4, uvChannelName, value ); + } + else + { + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT2, uvChannelName, string.Format( Constants.TilingOffsetFormat, uvName, propertyHelperVar + ".xy", propertyHelperVar + ".zw" ) ); + } + } + else + { + string vertexCoords = Constants.VertexShaderInputStr + ".texcoord"; + if( m_textureCoordSet > 0 ) + { + vertexCoords += m_textureCoordSet.ToString(); + } + + + string dummyPropUV = "_texcoord" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ); + string dummyUV = "uv" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ) + dummyPropUV; + + dataCollector.AddToUniforms( UniqueId, "uniform float4 " + propertyName + "_ST;" ); + dataCollector.AddToProperties( UniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 100 ); + dataCollector.AddToInput( UniqueId, dummyUV, WirePortDataType.FLOAT2 ); + + if( isVertex ) + { + dataCollector.AddToVertexLocalVariables( UniqueId, "float4 " + uvChannelName + " = float4(" + vertexCoords + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw, 0 ,0);" ); + return uvChannelName; + } + else + dataCollector.AddToLocalVariables( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvChannelName, Constants.InputVarStr + "." + dummyUV + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw" ); + + } + + return uvChannelName; + } + } + + public override void UpdateMaterial( Material mat ) + { + base.UpdateMaterial( mat ); + if( m_proceduralMaterial != null ) + { + Texture[] textures = m_proceduralMaterial.GetGeneratedTextures(); + for( int i = 0; i < textures.Length; i++ ) + { + if( mat.HasProperty( textures[ i ].name ) && !InsideShaderFunction ) + { + mat.SetTexture( textures[ i ].name, textures[ i ] ); + } + } + } + } + + public override bool UpdateShaderDefaults( ref Shader shader, ref TextureDefaultsDataColector defaultCol ) + { + if( m_proceduralMaterial != null ) + { + Texture[] textures = m_proceduralMaterial.GetGeneratedTextures(); + for( int i = 0; i < textures.Length; i++ ) + { + defaultCol.AddValue( textures[ i ].name, textures[ i ] ); + } + } + return true; + } + + public override void Destroy() + { + base.Destroy(); + m_textures = null; + m_proceduralMaterial = null; + m_cacheNodeConnections.Clear(); + m_cacheNodeConnections = null; + m_outputConns.Clear(); + m_outputConns = null; + } + + public override string GetPropertyValStr() + { + return m_proceduralMaterial ? m_proceduralMaterial.name : string.Empty; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + string guid = GetCurrentParam( ref nodeParams ); + m_textureCoordSet = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_autoNormal = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + if( guid.Length > 1 ) + { + m_proceduralMaterial = AssetDatabase.LoadAssetAtPath<ProceduralMaterial>( AssetDatabase.GUIDToAssetPath( guid ) ); + if( m_proceduralMaterial != null ) + { + ConfigPortsFromMaterial(); + } + else + { + UIUtils.ShowMessage( UniqueId, "Substance not found ", MessageSeverity.Error ); + } + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + string guid = ( m_proceduralMaterial != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_proceduralMaterial ) ) : "0"; + IOUtils.AddFieldValueToString( ref nodeInfo, guid ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_textureCoordSet ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autoNormal ); + } + + } +#pragma warning restore 0618 +} +#elif SUBSTANCE_PLUGIN_ENABLED + +using Substance.Game; + +namespace AmplifyShaderEditor +{ + public enum ASEProceduralOutputType + { + Color, + Normal, + } + // Disabling Substance Deprecated warning +#pragma warning disable 0618 + [Serializable] + [NodeAttributes( "Substance Sample", "Textures", "Samples a procedural material", KeyCode.None, true, 0, int.MaxValue, typeof( SubstanceGraph ), typeof( Substance.Game.Substance ) )] + public sealed class SubstanceSamplerNode : PropertyNode + { + private const string NormalMapCheck = "_normal"; + private const string GlobalVarDecStr = "uniform sampler2D {0};"; + private const string PropertyDecStr = "{0}(\"{1}\", 2D) = \"white\""; + + private const string AutoNormalStr = "Auto-Normal"; + private const string SubstanceStr = "Substance"; + + private float TexturePreviewSizeX = 128; + private float TexturePreviewSizeY = 128; + + private float PickerPreviewWidthAdjust = 18; + + private bool m_editing; + + private CacheNodeConnections m_cacheNodeConnections; + + [SerializeField] + private int m_firstOutputConnected = 0; + + [SerializeField] + private Substance.Game.SubstanceGraph m_substanceGraph; + [SerializeField] + private string m_substanceGUID = string.Empty; + + [SerializeField] + private int m_textureCoordSet = 0; + + [SerializeField] + private ASEProceduralOutputType[] m_textureTypes; + + [SerializeField] + private bool m_autoNormal = true; + + private System.Type m_type; + + private List<Texture2D> m_textures = new List<Texture2D>(); + + private List<int> m_outputConns = new List<int>(); + + private Rect m_previewArea; + + private Rect m_pickerArea; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ); + AddOutputPort( WirePortDataType.COLOR, Constants.EmptyPortValue ); + m_insideSize.Set( TexturePreviewSizeX + PickerPreviewWidthAdjust, TexturePreviewSizeY + 10 ); + m_type = typeof( Substance.Game.Substance ); + m_currentParameterType = PropertyType.Property; + m_freeType = false; + m_freeName = false; + m_autoWrapProperties = true; + m_customPrefix = "Substance Sample "; + m_drawPrecisionUI = false; + m_showPreview = true; + m_drawPreviewExpander = false; + m_selectedLocation = PreviewLocation.TopCenter; + m_cacheNodeConnections = new CacheNodeConnections(); + m_previewShaderGUID = "6f322c1da33f1e744941aafcb0ad1a2d"; + m_showAutoRegisterUI = false; + } + + public override void RenderNodePreview() + { + if( !m_initialized ) + return; + + SetPreviewInputs(); + PreviewMaterial.SetInt( "_CustomUVs", m_inputPorts[ 0 ].IsConnected ? 1 : 0 ); + + if( m_substanceGraph == null ) + return; + + List<Texture2D> texs = m_substanceGraph.generatedTextures; + int count = m_outputPorts.Count; + for( int i = 0; i < count; i++ ) + { + RenderTexture temp = RenderTexture.active; + RenderTexture.active = m_outputPorts[ i ].OutputPreviewTexture; + + PreviewMaterial.SetTexture( "_GenTex", texs[ i ] ); + + if( m_autoNormal && m_textureTypes[ i ] == ASEProceduralOutputType.Normal ) + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, 1 ); + else + Graphics.Blit( null, m_outputPorts[ i ].OutputPreviewTexture, PreviewMaterial, 0 ); + RenderTexture.active = temp; + } + } + + public override void OnOutputPortConnected( int portId, int otherNodeId, int otherPortId ) + { + base.OnOutputPortConnected( portId, otherNodeId, otherPortId ); + m_firstOutputConnected = -1; + } + + public override void OnOutputPortDisconnected( int portId ) + { + base.OnOutputPortDisconnected( portId ); + m_firstOutputConnected = -1; + } + + void CalculateFirstOutputConnected() + { + m_outputConns.Clear(); + int count = m_outputPorts.Count; + bool connectionsAvailable = false; + for( int i = 0; i < count; i++ ) + { + if( m_outputPorts[ i ].IsConnected ) + { + connectionsAvailable = true; + } + } + + for( int i = 0; i < count; i++ ) + { + if( connectionsAvailable ) + { + if( m_outputPorts[ i ].IsConnected ) + { + if( m_firstOutputConnected < 0 ) + m_firstOutputConnected = i; + + m_outputConns.Add( i ); + } + } + else + { + m_outputConns.Add( i ); + } + } + + if( m_firstOutputConnected < 0 ) + m_firstOutputConnected = 0; + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + base.OnNodeLayout( drawInfo ); + + m_previewArea = m_remainingBox; + m_previewArea.width = TexturePreviewSizeX * drawInfo.InvertedZoom; + m_previewArea.height = TexturePreviewSizeY * drawInfo.InvertedZoom; + m_previewArea.x += 0.5f * m_remainingBox.width - 0.5f * m_previewArea.width; + m_pickerArea = m_previewArea; + m_pickerArea.width = 40 * drawInfo.InvertedZoom; + m_pickerArea.x = m_previewArea.xMax - m_pickerArea.width - 2; + m_pickerArea.height = 14 * drawInfo.InvertedZoom; + m_pickerArea.y = m_previewArea.yMax - m_pickerArea.height - 2; + } + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + base.DrawGUIControls( drawInfo ); + + if( !( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp || drawInfo.CurrentEventType == EventType.ExecuteCommand || drawInfo.CurrentEventType == EventType.DragPerform ) ) + return; + + bool insideBox = m_previewArea.Contains( drawInfo.MousePosition ); + + if( insideBox ) + { + m_editing = true; + } + else if( m_editing && !insideBox && drawInfo.CurrentEventType != EventType.ExecuteCommand ) + { + GUI.FocusControl( null ); + m_editing = false; + } + } + + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + if( m_editing ) + { + m_textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + if( GUI.Button( m_pickerArea, string.Empty, GUIStyle.none ) ) + { + int controlID = EditorGUIUtility.GetControlID( FocusType.Passive ); + EditorGUIUtility.ShowObjectPicker<SubstanceGraph>( m_substanceGraph, false, "", controlID ); + } + + string commandName = Event.current.commandName; + UnityEngine.Object newValue = null; + if( commandName == "ObjectSelectorUpdated" ) + { + newValue = EditorGUIUtility.GetObjectPickerObject(); + if( newValue != (UnityEngine.Object)m_substanceGraph ) + { + UndoRecordObject( "Changing value EditorGUIObjectField on node Substance Sample" ); + + SubstanceGraph = newValue != null ? (SubstanceGraph)newValue : null; + m_textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + OnNewSubstanceSelected( m_textures ); + } + } + else if( commandName == "ObjectSelectorClosed" ) + { + newValue = EditorGUIUtility.GetObjectPickerObject(); + if( newValue != (UnityEngine.Object)m_substanceGraph ) + { + UndoRecordObject( "Changing value EditorGUIObjectField on node Substance Sample" ); + + SubstanceGraph = newValue != null ? (SubstanceGraph)newValue : null; + m_textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + OnNewSubstanceSelected( m_textures ); + } + m_editing = false; + } + + if( GUI.Button( m_previewArea, string.Empty, GUIStyle.none ) ) + { + if( m_substanceGraph != null ) + { + Selection.activeObject = m_substanceGraph; + EditorGUIUtility.PingObject( Selection.activeObject ); + } + m_editing = false; + } + } + + if( drawInfo.CurrentEventType == EventType.Repaint ) + { + if( !m_editing ) + m_textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + + if( m_textures != null ) + { + if( m_firstOutputConnected < 0 ) + { + CalculateFirstOutputConnected(); + } + else if( m_textures.Count != m_textureTypes.Length ) + { + OnNewSubstanceSelected( m_textures ); + } + + int texCount = m_outputConns.Count; + Rect individuals = m_previewArea; + individuals.height /= texCount; + + for( int i = 0; i < texCount; i++ ) + { + EditorGUI.DrawPreviewTexture( individuals, m_textures[ m_outputConns[ i ] ], null, ScaleMode.ScaleAndCrop ); + individuals.y += individuals.height; + } + } + else + { + GUI.Label( m_previewArea, string.Empty, UIUtils.ObjectFieldThumb ); + } + + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 ) + { + Rect smallButton = m_previewArea; + smallButton.height = 14 * drawInfo.InvertedZoom; + smallButton.y = m_previewArea.yMax - smallButton.height - 2; + smallButton.width = 40 * drawInfo.InvertedZoom; + smallButton.x = m_previewArea.xMax - smallButton.width - 2; + if( m_textures == null ) + { + GUI.Label( m_previewArea, "None (Procedural Material)", UIUtils.ObjectFieldThumbOverlay ); + } + GUI.Label( m_pickerArea, "Select", UIUtils.GetCustomStyle( CustomStyle.SamplerButton ) ); + } + + GUI.Label( m_previewArea, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) ); + } + } + + void OnNewSubstanceSelected( List<Texture2D> textures ) + { + CacheCurrentSettings(); + ConfigPortsFromMaterial( true, textures ); + ConnectFromCache(); + m_requireMaterialUpdate = true; + CalculateFirstOutputConnected(); + ContainerGraph.ParentWindow.RequestRepaint(); + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUI.BeginChangeCheck(); + SubstanceGraph = EditorGUILayoutObjectField( SubstanceStr, m_substanceGraph, m_type, false ) as SubstanceGraph; + if( EditorGUI.EndChangeCheck() ) + { + List<Texture2D> textures = m_substanceGraph != null ? m_substanceGraph.generatedTextures : null; + if( textures != null ) + { + OnNewSubstanceSelected( textures ); + } + } + + m_textureCoordSet = EditorGUILayoutIntPopup( Constants.AvailableUVSetsLabel, m_textureCoordSet, Constants.AvailableUVSetsStr, Constants.AvailableUVSets ); + EditorGUI.BeginChangeCheck(); + m_autoNormal = EditorGUILayoutToggle( AutoNormalStr, m_autoNormal ); + if( EditorGUI.EndChangeCheck() ) + { + for( int i = 0; i < m_textureTypes.Length; i++ ) + { + WirePortDataType portType = ( m_autoNormal && m_textureTypes[ i ] == ASEProceduralOutputType.Normal ) ? WirePortDataType.FLOAT3 : WirePortDataType.COLOR; + if( m_outputPorts[ i ].DataType != portType ) + { + m_outputPorts[ i ].ChangeType( portType, false ); + } + } + } + } + + private void CacheCurrentSettings() + { + m_cacheNodeConnections.Clear(); + for( int portId = 0; portId < m_outputPorts.Count; portId++ ) + { + if( m_outputPorts[ portId ].IsConnected ) + { + int connCount = m_outputPorts[ portId ].ConnectionCount; + for( int connIdx = 0; connIdx < connCount; connIdx++ ) + { + WireReference connection = m_outputPorts[ portId ].GetConnection( connIdx ); + m_cacheNodeConnections.Add( m_outputPorts[ portId ].Name, new NodeCache( connection.NodeId, connection.PortId ) ); + } + } + } + } + + private void ConnectFromCache() + { + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + List<NodeCache> connections = m_cacheNodeConnections.GetList( m_outputPorts[ i ].Name ); + if( connections != null ) + { + int count = connections.Count; + for( int connIdx = 0; connIdx < count; connIdx++ ) + { + UIUtils.SetConnection( connections[ connIdx ].TargetNodeId, connections[ connIdx ].TargetPortId, UniqueId, i ); + } + } + } + } + + + private void ConfigPortsFromMaterial( bool invalidateConnections = false, List<Texture2D> newTextures = null ) + { + SetAdditonalTitleText( ( m_substanceGraph != null ) ? string.Format( Constants.PropertyValueLabel, m_substanceGraph.name ) : "Value( <None> )" ); + + List<Texture2D> textures = newTextures != null ? newTextures : ( ( m_substanceGraph != null ) ? m_substanceGraph.generatedTextures : null ); + if( textures != null ) + { + m_firstOutputConnected = -1; + string nameToRemove = m_substanceGraph.graphLabel + "_"; + m_textureTypes = new ASEProceduralOutputType[ textures.Count ]; + for( int i = 0; i < textures.Count; i++ ) + { + //TODO: Replace for a more efficient test as soon as Laurent gives more infos + m_textureTypes[ i ] = textures[ i ].name.EndsWith( NormalMapCheck )?ASEProceduralOutputType.Normal:ASEProceduralOutputType.Color; + + WirePortDataType portType = ( m_autoNormal && m_textureTypes[ i ] == ASEProceduralOutputType.Normal ) ? WirePortDataType.FLOAT3 : WirePortDataType.COLOR; + string newName = textures[ i ].name.Replace( nameToRemove, string.Empty ); + char firstLetter = Char.ToUpper( newName[ 0 ] ); + newName = firstLetter.ToString() + newName.Substring( 1 ); + if( i < m_outputPorts.Count ) + { + m_outputPorts[ i ].ChangeProperties( newName, portType, false ); + if( invalidateConnections ) + { + m_outputPorts[ i ].FullDeleteConnections(); + } + } + else + { + AddOutputPort( portType, newName ); + } + } + + if( textures.Count < m_outputPorts.Count ) + { + int itemsToRemove = m_outputPorts.Count - textures.Count; + for( int i = 0; i < itemsToRemove; i++ ) + { + int idx = m_outputPorts.Count - 1; + if( m_outputPorts[ idx ].IsConnected ) + { + m_outputPorts[ idx ].ForceClearConnection(); + } + RemoveOutputPort( idx ); + } + } + } + else + { + int itemsToRemove = m_outputPorts.Count - 1; + m_outputPorts[ 0 ].ChangeProperties( Constants.EmptyPortValue, WirePortDataType.COLOR, false ); + m_outputPorts[ 0 ].ForceClearConnection(); + + for( int i = 0; i < itemsToRemove; i++ ) + { + int idx = m_outputPorts.Count - 1; + if( m_outputPorts[ idx ].IsConnected ) + { + m_outputPorts[ idx ].ForceClearConnection(); + } + RemoveOutputPort( idx ); + } + } + + m_sizeIsDirty = true; + m_isDirty = true; + } + + private void ConfigFromObject( UnityEngine.Object obj ) + { + SubstanceGraph newGraph = obj as SubstanceGraph;// AssetDatabase.LoadAssetAtPath<SubstanceGraph>( AssetDatabase.GetAssetPath( obj ) ); + if( newGraph != null ) + { + SubstanceGraph = newGraph; + ConfigPortsFromMaterial(); + } + + Substance.Game.Substance newSubstance = obj as Substance.Game.Substance;// AssetDatabase.LoadAssetAtPath<SubstanceGraph>( AssetDatabase.GetAssetPath( obj ) ); + if( newSubstance != null && newSubstance.graphs.Count > 0 ) + { + SubstanceGraph = newSubstance.graphs[0]; + ConfigPortsFromMaterial(); + } + + } + + public override void OnObjectDropped( UnityEngine.Object obj ) + { + ConfigFromObject( obj ); + } + + public override void SetupFromCastObject( UnityEngine.Object obj ) + { + ConfigFromObject( obj ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( m_substanceGraph == null ) + { + return "(0).xxxx"; + } + + if( m_outputPorts[ outputId ].IsLocalValue( dataCollector.PortCategory ) ) + { + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + List<Texture2D> textures = m_substanceGraph.generatedTextures; + + string uvPropertyName = string.Empty; + for( int i = 0; i < m_outputPorts.Count; i++ ) + { + if( m_outputPorts[ i ].HasConnectedNode ) + { + uvPropertyName = UIUtils.GeneratePropertyName( textures[ i ].name , PropertyType.Property ); + break; + } + } + + string propertyName = UIUtils.GeneratePropertyName( textures[ outputId ].name, PropertyType.Property ); + string name = propertyName + OutputId; + dataCollector.AddToUniforms( UniqueId, string.Format( GlobalVarDecStr, propertyName ) ); + dataCollector.AddToProperties( UniqueId, string.Format( PropertyDecStr, propertyName, textures[ outputId ].name ) + "{}", -1 ); + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + string value = string.Format( "tex2D{0}({1}, {2})", ( isVertex ? "lod" : string.Empty ), propertyName, GetUVCoords( ref dataCollector, ignoreLocalvar, uvPropertyName ) ); + if( m_autoNormal && m_textureTypes[ outputId ] == ASEProceduralOutputType.Normal ) + { + value = string.Format( TemplateHelperFunctions.CreateUnpackNormalStr( dataCollector, false, "1.0" ), value ); + } + + dataCollector.AddPropertyNode( this ); + RegisterLocalVariable( outputId, value, ref dataCollector, name ); + + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + public string GetUVCoords( ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar, string propertyName ) + { + bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + if( m_inputPorts[ 0 ].IsConnected ) + { + return m_inputPorts[ 0 ].GenerateShaderForOutput( ref dataCollector, isVertex ? WirePortDataType.FLOAT4 : WirePortDataType.FLOAT2, ignoreLocalVar, true ); + } + else + { + string uvChannelName = IOUtils.GetUVChannelName( propertyName, m_textureCoordSet ); + + if( dataCollector.IsTemplate ) + { + string propertyHelperVar = propertyName + "_ST"; + dataCollector.AddToUniforms( UniqueId, "float4", propertyHelperVar, dataCollector.IsSRP ); + string uvName = string.Empty; + if( dataCollector.TemplateDataCollectorInstance.HasUV( m_textureCoordSet ) ) + { + uvName = dataCollector.TemplateDataCollectorInstance.GetUVName( m_textureCoordSet ); + } + else + { + uvName = dataCollector.TemplateDataCollectorInstance.RegisterUV( m_textureCoordSet ); + } + + uvChannelName = "uv" + propertyName; + if( isVertex ) + { + string value = string.Format( Constants.TilingOffsetFormat, uvName, propertyHelperVar + ".xy", propertyHelperVar + ".zw" ); + string lodLevel = "0"; + + value = "float4( " + value + ", 0 , " + lodLevel + " )"; + dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, WirePortDataType.FLOAT4, uvChannelName, value ); + } + else + { + dataCollector.AddLocalVariable( UniqueId, m_currentPrecisionType, WirePortDataType.FLOAT2, uvChannelName, string.Format( Constants.TilingOffsetFormat, uvName, propertyHelperVar + ".xy", propertyHelperVar + ".zw" ) ); + } + } + else + { + string vertexCoords = Constants.VertexShaderInputStr + ".texcoord"; + if( m_textureCoordSet > 0 ) + { + vertexCoords += m_textureCoordSet.ToString(); + } + + + string dummyPropUV = "_texcoord" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ); + string dummyUV = "uv" + ( m_textureCoordSet > 0 ? ( m_textureCoordSet + 1 ).ToString() : "" ) + dummyPropUV; + + dataCollector.AddToUniforms( UniqueId, "uniform float4 " + propertyName + "_ST;" ); + dataCollector.AddToProperties( UniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 100 ); + dataCollector.AddToInput( UniqueId, dummyUV, WirePortDataType.FLOAT2 ); + + if( isVertex ) + { + dataCollector.AddToVertexLocalVariables( UniqueId, "float4 " + uvChannelName + " = float4(" + vertexCoords + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw, 0 ,0);" ); + return uvChannelName; + } + else + dataCollector.AddToLocalVariables( UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvChannelName, Constants.InputVarStr + "." + dummyUV + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw" ); + + } + + return uvChannelName; + } + } + + public override void UpdateMaterial( Material mat ) + { + base.UpdateMaterial( mat ); + if( m_substanceGraph != null ) + { + List<Texture2D> textures = m_substanceGraph.generatedTextures; + for( int i = 0; i < textures.Count; i++ ) + { + string textureName = UIUtils.GeneratePropertyName( textures[ i ].name, PropertyType.Property ); + if( mat.HasProperty( textureName ) && !InsideShaderFunction ) + { + mat.SetTexture( textureName, textures[ i ] ); + } + } + } + } + + public override bool UpdateShaderDefaults( ref Shader shader, ref TextureDefaultsDataColector defaultCol ) + { + if( m_substanceGraph != null ) + { + List<Texture2D> textures = m_substanceGraph.generatedTextures; + for( int i = 0; i < textures.Count; i++ ) + { + defaultCol.AddValue( UIUtils.GeneratePropertyName( textures[ i ].name, PropertyType.Property ), textures[ i ] ); + } + } + return true; + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + if( m_substanceGraph == null && !string.IsNullOrEmpty( m_substanceGUID ) ) + { + SubstanceGraph = AssetDatabase.LoadAssetAtPath<SubstanceGraph>( AssetDatabase.GUIDToAssetPath( m_substanceGUID ) ); + if( m_substanceGraph == null ) + { + m_substanceGUID = string.Empty; + } + } + } + + public override void Destroy() + { + base.Destroy(); + m_textures = null; + m_substanceGraph = null; + m_substanceGUID = string.Empty; + m_cacheNodeConnections.Clear(); + m_cacheNodeConnections = null; + m_outputConns.Clear(); + m_outputConns = null; + } + + public override string GetPropertyValStr() + { + return m_substanceGraph ? m_substanceGraph.name : string.Empty; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + string guid = GetCurrentParam( ref nodeParams ); + m_textureCoordSet = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + m_autoNormal = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + if( guid.Length > 1 ) + { + SubstanceGraph = AssetDatabase.LoadAssetAtPath<SubstanceGraph>( AssetDatabase.GUIDToAssetPath( guid ) ); + if( m_substanceGraph != null ) + { + ConfigPortsFromMaterial(); + } + else + { + UIUtils.ShowMessage( "Substance not found ", MessageSeverity.Error ); + } + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + string guid = ( m_substanceGraph != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_substanceGraph ) ) : "0"; + IOUtils.AddFieldValueToString( ref nodeInfo, guid ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_textureCoordSet ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autoNormal ); + } + + public SubstanceGraph SubstanceGraph + { + set + { + m_substanceGraph = value; + if( value != null ) + { + m_substanceGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( value ) ); + } + else + { + m_substanceGUID = string.Empty; + } + } + get { return m_substanceGraph; } + } + } +#pragma warning restore 0618 +} +#endif diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs.meta new file mode 100644 index 00000000..02886b0f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/SubstanceSamplerNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 7323b6020278e034b9e4c670cbc61361 +timeCreated: 1486640033 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCFlipBookUVAnimation.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCFlipBookUVAnimation.cs new file mode 100644 index 00000000..3735c3ad --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCFlipBookUVAnimation.cs @@ -0,0 +1,238 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +// +// Custom Node Flipbook UV Animation +// Donated by The Four Headed Cat - @fourheadedcat + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + + [Serializable] + [NodeAttributes( "Flipbook UV Animation", "UV Coordinates", "Animate a Flipbook Texture Modifying UV Coordinates.", null, KeyCode.None, true, false, null, null, "The Four Headed Cat - @fourheadedcat" )] + public sealed class TFHCFlipBookUVAnimation : ParentNode + + { + + private const string TextureVerticalDirectionStr = "Texture Direction"; + private const string NegativeSpeedBehaviorStr = "If Negative Speed"; + + [SerializeField] + private int m_selectedTextureVerticalDirection = 0; + + [SerializeField] + private int m_negativeSpeedBehavior = 0; + + [SerializeField] + private readonly string[] m_textureVerticalDirectionValues = { "Top To Bottom", "Bottom To Top" }; + + [SerializeField] + private readonly string[] m_negativeSpeedBehaviorValues = { "Switch to Positive", "Reverse Animation" }; + + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, false, "UV" ); + AddInputPort( WirePortDataType.FLOAT, false, "Columns" ); + AddInputPort( WirePortDataType.FLOAT, false, "Rows" ); + AddInputPort( WirePortDataType.FLOAT, false, "Speed" ); + AddInputPort( WirePortDataType.FLOAT, false, "Start Frame" ); + AddInputPort( WirePortDataType.FLOAT, false, "Time" ); + + AddOutputVectorPorts( WirePortDataType.FLOAT2, "UV" ); + m_outputPorts[ 1 ].Name = "U"; + m_outputPorts[ 2 ].Name = "V"; + m_textLabelWidth = 125; + m_useInternalPortData = true; + m_autoWrapProperties = true; + m_previewShaderGUID = "04fe24be792bfd5428b92132d7cf0f7d"; + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + if( portId == 5 ) + { + m_previewMaterialPassId = 1; + } + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + if( portId == 5 ) + { + m_previewMaterialPassId = 0; + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUILayout.BeginVertical(); + m_selectedTextureVerticalDirection = EditorGUILayoutPopup( TextureVerticalDirectionStr, m_selectedTextureVerticalDirection, m_textureVerticalDirectionValues ); + m_negativeSpeedBehavior = EditorGUILayoutPopup( NegativeSpeedBehaviorStr, m_negativeSpeedBehavior, m_negativeSpeedBehaviorValues ); + EditorGUILayout.EndVertical(); + EditorGUILayout.HelpBox( "Flipbook UV Animation:\n\n - UV: Texture Coordinates to Flipbook.\n - Columns: number of Columns (X) of the Flipbook Texture.\n - Rows: number of Rows (Y) of the Flipbook Textures.\n - Speed: speed of the animation.\n - Texture Direction: set the vertical order of the texture tiles.\n - If Negative Speed: set the behavior when speed is negative.\n\n - Out: UV Coordinates.", MessageType.None ); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_selectedTextureVerticalDirection = ( int ) int.Parse( GetCurrentParam( ref nodeParams ) ); + m_negativeSpeedBehavior = ( int ) int.Parse( GetCurrentParam( ref nodeParams ) ); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedTextureVerticalDirection ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_negativeSpeedBehavior ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + // OPTIMIZATION NOTES + // + // round( fmod( x, y ) ) can be replaced with a faster + // floor( frac( x / y ) * y + 0.5 ) => div can be muls with 1/y, almost always static/constant + // + if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + + string uv = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string columns = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ); + + if ( !m_inputPorts[ 1 ].IsConnected ) + columns = ( float.Parse( columns ) == 0f ? "1" : columns ); + + string rows = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + if ( !m_inputPorts[ 2 ].IsConnected ) + rows = ( float.Parse( rows ) == 0f ? "1" : rows ); + + string speed = m_inputPorts[ 3 ].GeneratePortInstructions( ref dataCollector ); + string startframe = m_inputPorts[ 4 ].GeneratePortInstructions( ref dataCollector ); + string timer = m_inputPorts[ 5 ].IsConnected ? m_inputPorts[ 5 ].GeneratePortInstructions( ref dataCollector ) : "_Time[ 1 ]"; + + string vcomment1 = "// *** BEGIN Flipbook UV Animation vars ***"; + string vcomment2 = "// Total tiles of Flipbook Texture"; + string vtotaltiles = "float fbtotaltiles" + OutputId + " = " + columns + " * " + rows + ";"; + string vcomment3 = "// Offsets for cols and rows of Flipbook Texture"; + string vcolsoffset = "float fbcolsoffset" + OutputId + " = 1.0f / " + columns + ";"; + string vrowssoffset = "float fbrowsoffset" + OutputId + " = 1.0f / " + rows + ";"; + string vcomment4 = "// Speed of animation"; + + string vspeed = string.Format( "float fbspeed{0} = {1} * {2};", OutputId,timer,speed); + string vcomment5 = "// UV Tiling (col and row offset)"; + string vtiling = "float2 fbtiling" + OutputId + " = float2(fbcolsoffset" + OutputId + ", fbrowsoffset" + OutputId + ");"; + string vcomment6 = "// UV Offset - calculate current tile linear index, and convert it to (X * coloffset, Y * rowoffset)"; + string vcomment7 = "// Calculate current tile linear index"; + //float fbcurrenttileindex1 = round( fmod( fbspeed1 + _Float0, fbtotaltiles1 ) ); + string vcurrenttileindex = "float fbcurrenttileindex" + OutputId + " = round( fmod( fbspeed" + OutputId + " + " + startframe + ", fbtotaltiles" + OutputId + ") );"; + string vcurrenttileindex1 = "fbcurrenttileindex" + OutputId + " += ( fbcurrenttileindex" + OutputId + " < 0) ? fbtotaltiles" + OutputId + " : 0;"; + //fbcurrenttileindex1 += ( fbcurrenttileindex1 < 0 ) ? fbtotaltiles1 : 0; + //string vcurrenttileindex = "int fbcurrenttileindex" + m_uniqueId + " = (int)fmod( fbspeed" + m_uniqueId + ", fbtotaltiles" + m_uniqueId + ") + " + startframe + ";"; + string vcomment8 = "// Obtain Offset X coordinate from current tile linear index"; + + //float fblinearindextox1 = round( fmod( fbcurrenttileindex1, 5.0 ) ); + //string voffsetx1 = "int fblinearindextox" + m_uniqueId + " = fbcurrenttileindex" + m_uniqueId + " % (int)" + columns + ";"; + string voffsetx1 = "float fblinearindextox" + OutputId + " = round ( fmod ( fbcurrenttileindex" + OutputId + ", " + columns + " ) );"; + string vcomment9 = String.Empty; + string voffsetx2 = String.Empty; + if ( m_negativeSpeedBehavior != 0 ) + { + vcomment9 = "// Reverse X animation if speed is negative"; + voffsetx2 = "fblinearindextox" + OutputId + " = (" + speed + " > 0 ? fblinearindextox" + OutputId + " : (int)" + columns + " - fblinearindextox" + OutputId + ");"; + } + string vcomment10 = "// Multiply Offset X by coloffset"; + string voffsetx3 = "float fboffsetx" + OutputId + " = fblinearindextox" + OutputId + " * fbcolsoffset" + OutputId + ";"; + string vcomment11 = "// Obtain Offset Y coordinate from current tile linear index"; + //float fblinearindextoy1 = round( fmod( ( fbcurrenttileindex1 - fblinearindextox1 ) / 5.0, 5.0 ) ); + string voffsety1 = "float fblinearindextoy" + OutputId + " = round( fmod( ( fbcurrenttileindex" + OutputId + " - fblinearindextox" + OutputId + " ) / " + columns + ", " + rows + " ) );"; + //string voffsety1 = "int fblinearindextoy" + m_uniqueId + " = (int)( ( fbcurrenttileindex" + m_uniqueId + " - fblinearindextox" + m_uniqueId + " ) / " + columns + " ) % (int)" + rows + ";"; + //string vcomment10 = "// Reverse Y to get from Top to Bottom"; + //string voffsety2 = "fblinearindextoy" + m_uniqueId + " = (int)" + rows + " - fblinearindextoy" + m_uniqueId + ";"; + string vcomment12 = String.Empty; + string voffsety2 = String.Empty; + if ( m_negativeSpeedBehavior == 0 ) + { + if ( m_selectedTextureVerticalDirection == 0 ) + { + vcomment12 = "// Reverse Y to get tiles from Top to Bottom"; + voffsety2 = "fblinearindextoy" + OutputId + " = (int)(" + rows + "-1) - fblinearindextoy" + OutputId + ";"; + } + } + else + { + string reverseanimationoperator = String.Empty; + if ( m_selectedTextureVerticalDirection == 0 ) + { + vcomment12 = "// Reverse Y to get tiles from Top to Bottom and Reverse Y animation if speed is negative"; + reverseanimationoperator = " < "; + } + else + { + vcomment12 = "// Reverse Y animation if speed is negative"; + reverseanimationoperator = " > "; + } + voffsety2 = "fblinearindextoy" + OutputId + " = (" + speed + reverseanimationoperator + " 0 ? fblinearindextoy" + OutputId + " : (int)" + rows + " - fblinearindextoy" + OutputId + ");"; + } + string vcomment13 = "// Multiply Offset Y by rowoffset"; + string voffsety3 = "float fboffsety" + OutputId + " = fblinearindextoy" + OutputId + " * fbrowsoffset" + OutputId + ";"; + string vcomment14 = "// UV Offset"; + string voffset = "float2 fboffset" + OutputId + " = float2(fboffsetx" + OutputId + ", fboffsety" + OutputId + ");"; + //string voffset = "float2 fboffset" + m_uniqueId + " = float2( ( ( (int)fmod( fbspeed" + m_uniqueId + " , fbtotaltiles" + m_uniqueId + ") % (int)" + columns + " ) * fbcolsoffset" + m_OutputId + " ) , ( ( (int)" + rows + " - ( (int)( ( (int)fmod( fbspeed" + m_uniqueId + " , fbtotaltiles" + m_uniqueId + " ) - ( (int)fmod( fbspeed" + m_uniqueId + " , fbtotaltiles" + m_uniqueId + " ) % (int)" + columns + " ) ) / " + columns + " ) % (int)" + rows + " ) ) * fbrowsoffset" + m_uniqueId + " ) );"; + string vcomment15 = "// Flipbook UV"; + string vfbuv = "half2 fbuv" + OutputId + " = " + uv + " * fbtiling" + OutputId + " + fboffset" + OutputId + ";"; + string vcomment16 = "// *** END Flipbook UV Animation vars ***"; + string result = "fbuv" + OutputId; + + dataCollector.AddLocalVariable( UniqueId, vcomment1 ); + dataCollector.AddLocalVariable( UniqueId, vcomment2 ); + dataCollector.AddLocalVariable( UniqueId, vtotaltiles ); + dataCollector.AddLocalVariable( UniqueId, vcomment3 ); + dataCollector.AddLocalVariable( UniqueId, vcolsoffset ); + dataCollector.AddLocalVariable( UniqueId, vrowssoffset ); + dataCollector.AddLocalVariable( UniqueId, vcomment4 ); + dataCollector.AddLocalVariable( UniqueId, vspeed ); + dataCollector.AddLocalVariable( UniqueId, vcomment5 ); + dataCollector.AddLocalVariable( UniqueId, vtiling ); + dataCollector.AddLocalVariable( UniqueId, vcomment6 ); + dataCollector.AddLocalVariable( UniqueId, vcomment7 ); + dataCollector.AddLocalVariable( UniqueId, vcurrenttileindex ); + dataCollector.AddLocalVariable( UniqueId, vcurrenttileindex1 ); + dataCollector.AddLocalVariable( UniqueId, vcomment8 ); + dataCollector.AddLocalVariable( UniqueId, voffsetx1 ); + if ( m_negativeSpeedBehavior != 0 ) + { + dataCollector.AddLocalVariable( UniqueId, vcomment9 ); + dataCollector.AddLocalVariable( UniqueId, voffsetx2 ); + } + dataCollector.AddLocalVariable( UniqueId, vcomment10 ); + dataCollector.AddLocalVariable( UniqueId, voffsetx3 ); + dataCollector.AddLocalVariable( UniqueId, vcomment11 ); + dataCollector.AddLocalVariable( UniqueId, voffsety1 ); + if ( m_selectedTextureVerticalDirection == 0 || m_negativeSpeedBehavior != 0 ) + { + dataCollector.AddLocalVariable( UniqueId, vcomment12 ); + dataCollector.AddLocalVariable( UniqueId, voffsety2 ); + } + dataCollector.AddLocalVariable( UniqueId, vcomment13 ); + dataCollector.AddLocalVariable( UniqueId, voffsety3 ); + dataCollector.AddLocalVariable( UniqueId, vcomment14 ); + dataCollector.AddLocalVariable( UniqueId, voffset ); + dataCollector.AddLocalVariable( UniqueId, vcomment15 ); + dataCollector.AddLocalVariable( UniqueId, vfbuv ); + dataCollector.AddLocalVariable( UniqueId, vcomment16 ); + + m_outputPorts[ 0 ].SetLocalValue( result, dataCollector.PortCategory ); + + return GetOutputVectorItem( 0, outputId, result ); + + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCFlipBookUVAnimation.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCFlipBookUVAnimation.cs.meta new file mode 100644 index 00000000..cf165fe3 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCFlipBookUVAnimation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 38b8c76e7f2dc294581195a669942706 +timeCreated: 1481126954 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCPixelate.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCPixelate.cs new file mode 100644 index 00000000..3d778d9c --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCPixelate.cs @@ -0,0 +1,54 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> +// +// Custom Node Pixelate UV +// Donated by The Four Headed Cat - @fourheadedcat + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Pixelate UV", "UV Coordinates", "Pixelate Texture Modifying UV.", null, KeyCode.None, true, false, null, null, "The Four Headed Cat - @fourheadedcat" )] + public sealed class TFHCPixelate : ParentNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT2, true, "UV" ); + AddInputPort( WirePortDataType.FLOAT, false, "Pixels X" ); + AddInputPort( WirePortDataType.FLOAT, false, "Pixels Y" ); + AddOutputPort( WirePortDataType.FLOAT2, "Out" ); + m_useInternalPortData = true; + m_previewShaderGUID = "e2f7e3c513ed18340868b8cbd0d85cfb"; + } + + public override void DrawProperties() + { + base.DrawProperties (); + EditorGUILayout.HelpBox ("Pixelate UV.\n\n - UV is the Texture Coordinates to pixelate.\n - Pixels X is the number of horizontal pixels\n - Pixels Y is the number of vertical pixels.", MessageType.None); + + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + string uv = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + string PixelCount_X = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ); + string PixelCount_Y = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector ); + + string pixelWidth = "float pixelWidth" + OutputId + " = 1.0f / " + PixelCount_X + ";"; + string pixelHeight = "float pixelHeight" + OutputId + " = 1.0f / " + PixelCount_Y + ";"; + string pixelatedUV = "half2 pixelateduv" + OutputId + " = half2((int)(" + uv + ".x / pixelWidth" + OutputId + ") * pixelWidth" + OutputId + ", (int)(" + uv + ".y / pixelHeight" + OutputId + ") * pixelHeight" + OutputId + ");"; + string result = "pixelateduv" + OutputId; + + dataCollector.AddLocalVariable( UniqueId, pixelWidth ); + dataCollector.AddLocalVariable( UniqueId, pixelHeight ); + dataCollector.AddLocalVariable( UniqueId, pixelatedUV ); + + return GetOutputVectorItem( 0, outputId, result); + + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCPixelate.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCPixelate.cs.meta new file mode 100644 index 00000000..fc01dd0a --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TFHCPixelate.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 72a1a810ace8ea440ba20d4a4f9086ce +timeCreated: 1481126956 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureCoordinatesNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureCoordinatesNode.cs new file mode 100644 index 00000000..fc7b1801 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureCoordinatesNode.cs @@ -0,0 +1,588 @@ +// 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( "Texture Coordinates", "UV Coordinates", "Texture UV coordinates set, if <b>Tex</b> is connected to a texture object it will use that texture scale factors, otherwise uses <b>Tilling</b> and <b>Offset</b> port values", null, KeyCode.U, tags: "uv" )] + public sealed class TextureCoordinatesNode : ParentNode + { + + private const string DummyPropertyDec = "[HideInInspector] _DummyTex{0}( \"\", 2D ) = \"white\""; + private const string DummyUniformDec = "uniform sampler2D _DummyTex{0};"; + private const string DummyTexCoordDef = "uv{0}_DummyTex{0}"; + private const string DummyTexCoordSurfDef = "float2 texCoordDummy{0} = {1}.uv{2}_DummyTex{2}*{3} + {4};"; + private const string DummyTexCoordSurfVar = "texCoordDummy{0}"; + + private readonly string[] Dummy = { string.Empty }; + + private const string TilingStr = "Tiling"; + private const string OffsetStr = "Offset"; + private const string TexCoordStr = "texcoord_"; + + [SerializeField] + private int m_referenceArrayId = -1; + + [SerializeField] + private int m_referenceNodeId = -1; + + [SerializeField] + private int m_textureCoordChannel = 0; + + //[SerializeField] + //private int m_texcoordId = -1; + + [SerializeField] + private int m_texcoordSize = 2; + + [SerializeField] + private string m_surfaceTexcoordName = string.Empty; + + [SerializeField] + private TexturePropertyNode m_inputReferenceNode = null; + + private Vector4Node m_texCoordsHelper; + + private TexturePropertyNode m_referenceNode = null; + + private InputPort m_texPort = null; + private InputPort m_tilingPort = null; + private InputPort m_offsetPort = null; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.SAMPLER2D, false, "Tex", -1, MasterNodePortCategory.Fragment, 2 ); + m_texPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_texPort.CreatePortRestrictions( WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE, WirePortDataType.OBJECT ); + + AddInputPort( WirePortDataType.FLOAT2, false, "Tiling", -1, MasterNodePortCategory.Fragment, 0 ); + m_tilingPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + m_tilingPort.Vector2InternalData = new Vector2( 1, 1 ); + AddInputPort( WirePortDataType.FLOAT2, false, "Offset", -1, MasterNodePortCategory.Fragment, 1 ); + m_offsetPort = m_inputPorts[ m_inputPorts.Count - 1 ]; + + + AddOutputVectorPorts( WirePortDataType.FLOAT2, "UV" ); + m_outputPorts[ 1 ].Name = "U"; + m_outputPorts[ 2 ].Name = "V"; + AddOutputPort( WirePortDataType.FLOAT, "W" ); + AddOutputPort( WirePortDataType.FLOAT, "T" ); + m_textLabelWidth = 90; + m_useInternalPortData = true; + m_autoWrapProperties = true; + m_tilingPort.Category = MasterNodePortCategory.Vertex; + m_offsetPort.Category = MasterNodePortCategory.Vertex; + UpdateOutput(); + m_previewShaderGUID = "085e462b2de441a42949be0e666cf5d2"; + } + + public override void Reset() + { + m_surfaceTexcoordName = string.Empty; + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + if( portId == 2 ) + { + m_inputReferenceNode = m_texPort.GetOutputNodeWhichIsNotRelay() as TexturePropertyNode; + UpdatePorts(); + } + UpdateTitle(); + } + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + if( portId == 2 ) + { + m_inputReferenceNode = null; + UpdatePorts(); + } + UpdateTitle(); + } + + void UpdateTitle() + { + if( m_inputReferenceNode != null ) + { + m_additionalContent.text = string.Format( "Value( {0} )", m_inputReferenceNode.PropertyInspectorName ); + } + else if( m_referenceArrayId > -1 && m_referenceNode != null ) + { + m_additionalContent.text = string.Format( "Value( {0} )", m_referenceNode.PropertyInspectorName ); + } + else + { + m_additionalContent.text = string.Empty; + } + m_sizeIsDirty = true; + } + + void UpdatePorts() + { + if( m_inputReferenceNode != null || m_texPort.IsConnected ) + { + m_tilingPort.Locked = true; + m_offsetPort.Locked = true; + } + else if( m_referenceArrayId > -1 ) + { + m_tilingPort.Locked = true; + m_offsetPort.Locked = true; + } + else + { + m_tilingPort.Locked = false; + m_offsetPort.Locked = false; + } + } + + public override void DrawProperties() + { + bool guiEnabledBuffer = GUI.enabled; + + EditorGUI.BeginChangeCheck(); + List<string> arr = new List<string>( UIUtils.TexturePropertyNodeArr() ); + if( arr != null && arr.Count > 0 ) + { + arr.Insert( 0, "None" ); + GUI.enabled = true && ( !m_texPort.IsConnected ); + m_referenceArrayId = EditorGUILayoutPopup( Constants.AvailableReferenceStr, m_referenceArrayId + 1, arr.ToArray() ) - 1; + } + else + { + m_referenceArrayId = -1; + GUI.enabled = false; + EditorGUILayoutPopup( Constants.AvailableReferenceStr, 0, Dummy ); + } + + GUI.enabled = guiEnabledBuffer; + if( EditorGUI.EndChangeCheck() ) + { + m_referenceNode = UIUtils.GetTexturePropertyNode( m_referenceArrayId ); + if( m_referenceNode != null ) + { + m_referenceNodeId = m_referenceNode.UniqueId; + } + else + { + m_referenceNodeId = -1; + m_referenceArrayId = -1; + } + + UpdateTitle(); + UpdatePorts(); + } + + EditorGUI.BeginChangeCheck(); + m_texcoordSize = EditorGUILayoutIntPopup( Constants.AvailableUVSizesLabel, m_texcoordSize, Constants.AvailableUVSizesStr, Constants.AvailableUVSizes ); + if( EditorGUI.EndChangeCheck() ) + { + UpdateOutput(); + } + + m_textureCoordChannel = EditorGUILayoutIntPopup( Constants.AvailableUVSetsLabel, m_textureCoordChannel, Constants.AvailableUVSetsStr, Constants.AvailableUVSets ); + + + if( m_referenceArrayId > -1 ) + GUI.enabled = false; + + base.DrawProperties(); + + GUI.enabled = guiEnabledBuffer; + } + + private void UpdateOutput() + { + if( m_texcoordSize == 3 ) + { + m_outputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT3, false ); + m_outputPorts[ 0 ].Name = "UVW"; + m_outputPorts[ 3 ].Visible = true; + m_outputPorts[ 4 ].Visible = false; + } + else if( m_texcoordSize == 4 ) + { + m_outputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT4, false ); + m_outputPorts[ 0 ].Name = "UVWT"; + m_outputPorts[ 3 ].Visible = true; + m_outputPorts[ 4 ].Visible = true; + } + else + { + m_outputPorts[ 0 ].ChangeType( WirePortDataType.FLOAT2, false ); + m_outputPorts[ 0 ].Name = "UV"; + m_outputPorts[ 3 ].Visible = false; + m_outputPorts[ 4 ].Visible = false; + } + m_sizeIsDirty = true; + } + + public override void OnNodeLogicUpdate( DrawInfo drawInfo ) + { + base.OnNodeLogicUpdate( drawInfo ); + CheckReference(); + } + + //public override void Draw( DrawInfo drawInfo ) + //{ + // base.Draw( drawInfo ); + // //CheckReference(); + //} + + void CheckReference() + { + if( m_referenceArrayId > -1 ) + { + ParentNode newNode = UIUtils.GetTexturePropertyNode( m_referenceArrayId ); + if( newNode == null || newNode.UniqueId != m_referenceNodeId ) + { + m_referenceNode = null; + int count = UIUtils.GetTexturePropertyNodeAmount(); + for( int i = 0; i < count; i++ ) + { + ParentNode node = UIUtils.GetTexturePropertyNode( i ); + if( node.UniqueId == m_referenceNodeId ) + { + m_referenceNode = node as TexturePropertyNode; + m_referenceArrayId = i; + break; + } + } + } + } + + if( m_referenceNode == null && m_referenceNodeId > -1 ) + { + m_referenceNodeId = -1; + m_referenceArrayId = -1; + UpdateTitle(); + UpdatePorts(); + } + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_textureCoordChannel = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > 2402 ) + { + if( UIUtils.CurrentShaderVersion() > 2404 ) + { + m_referenceNodeId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + else + { + m_referenceArrayId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + } + + if( UIUtils.CurrentShaderVersion() > 5001 ) + { + m_texcoordSize = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + UpdateOutput(); + } + } + + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + if( UIUtils.CurrentShaderVersion() > 2402 ) + { + if( UIUtils.CurrentShaderVersion() > 2404 ) + { + m_referenceNode = UIUtils.GetNode( m_referenceNodeId ) as TexturePropertyNode; + if( m_referenceNodeId > -1 ) + m_referenceArrayId = UIUtils.GetTexturePropertyNodeRegisterId( m_referenceNodeId ); + } + else + { + m_referenceNode = UIUtils.GetTexturePropertyNode( m_referenceArrayId ); + if( m_referenceNode != null ) + { + m_referenceNodeId = m_referenceNode.UniqueId; + } + } + UpdateTitle(); + UpdatePorts(); + } + } + + public override void PropagateNodeData( NodeData nodeData, ref MasterNodeDataCollector dataCollector ) + { + if( dataCollector != null && dataCollector.TesselationActive ) + { + base.PropagateNodeData( nodeData, ref dataCollector ); + return; + } + + if( dataCollector.IsTemplate ) + { + dataCollector.TemplateDataCollectorInstance.SetUVUsage( m_textureCoordChannel, m_texcoordSize ); + } + else if( m_textureCoordChannel > 3 ) + { + dataCollector.AddCustomAppData( string.Format( TemplateHelperFunctions.TexUVFullSemantic, m_textureCoordChannel ) ); + } + UIUtils.SetCategoryInBitArray( ref m_category, nodeData.Category ); + + MasterNodePortCategory propagateCategory = ( nodeData.Category != MasterNodePortCategory.Vertex && nodeData.Category != MasterNodePortCategory.Tessellation ) ? MasterNodePortCategory.Vertex : nodeData.Category; + nodeData.Category = propagateCategory; + nodeData.GraphDepth += 1; + if( nodeData.GraphDepth > m_graphDepth ) + { + m_graphDepth = nodeData.GraphDepth; + } + + int count = m_inputPorts.Count; + for( int i = 0; i < count; i++ ) + { + if( m_inputPorts[ i ].IsConnected ) + { + //m_inputPorts[ i ].GetOutputNode().PropagateNodeCategory( category ); + m_inputPorts[ i ].GetOutputNode().PropagateNodeData( nodeData, ref dataCollector ); + } + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_textureCoordChannel ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( ( m_referenceNode != null ) ? m_referenceNode.UniqueId : -1 ) ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_texcoordSize ); + } + + string GetValidPropertyName() + { + string propertyName = string.Empty; + if( m_inputReferenceNode != null ) + { + propertyName = m_inputReferenceNode.PropertyName; + } + else if( m_referenceArrayId > -1 ) + { + m_referenceNode = UIUtils.GetTexturePropertyNode( m_referenceArrayId ); + if( m_referenceNode != null ) + { + propertyName = m_referenceNode.PropertyName; + } + } + + return propertyName; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar ) + { + if( dataCollector.PortCategory == MasterNodePortCategory.Tessellation ) + { + UIUtils.ShowMessage( UniqueId, m_nodeAttribs.Name + " cannot be used on Master Node Tessellation port" ); + return "-1"; + } + + //bool isVertex = ( dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation ); + + string tiling = string.Empty; + string offset = string.Empty; + + string portProperty = string.Empty; + if( m_texPort.IsConnected ) + { + portProperty = m_texPort.GeneratePortInstructions( ref dataCollector ); + } + else if( m_referenceArrayId > -1 ) + { + TexturePropertyNode temp = UIUtils.GetTexturePropertyNode( m_referenceArrayId ); + if( temp != null ) + { + portProperty = temp.BaseGenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalVar ); + } + } + + //TEMPLATES + if( dataCollector.MasterNodeCategory == AvailableShaderTypes.Template ) + { + if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + + string uvName = string.Empty; + if( dataCollector.TemplateDataCollectorInstance.HasUV( m_textureCoordChannel ) ) + { + uvName = dataCollector.TemplateDataCollectorInstance.GetUVName( m_textureCoordChannel, m_outputPorts[ 0 ].DataType ); + } + else + { + uvName = dataCollector.TemplateDataCollectorInstance.RegisterUV( m_textureCoordChannel, m_outputPorts[ 0 ].DataType ); + } + string currPropertyName = GetValidPropertyName(); + if( !string.IsNullOrEmpty( portProperty ) && portProperty != "0.0" ) + { + currPropertyName = portProperty; + } + if( !string.IsNullOrEmpty( currPropertyName ) ) + { + string finalTexCoordName = "uv" + m_textureCoordChannel + currPropertyName; + string dummyPropertyTexcoords = currPropertyName + "_ST"; + + if( m_texCoordsHelper == null ) + { + m_texCoordsHelper = CreateInstance<Vector4Node>(); + m_texCoordsHelper.ContainerGraph = ContainerGraph; + m_texCoordsHelper.SetBaseUniqueId( UniqueId, true ); + m_texCoordsHelper.RegisterPropertyOnInstancing = false; + m_texCoordsHelper.AddGlobalToSRPBatcher = true; + } + + if( UIUtils.CurrentWindow.OutsideGraph.IsInstancedShader ) + { + m_texCoordsHelper.CurrentParameterType = PropertyType.InstancedProperty; + } + else + { + m_texCoordsHelper.CurrentParameterType = PropertyType.Global; + } + m_texCoordsHelper.ResetOutputLocals(); + m_texCoordsHelper.SetRawPropertyName( dummyPropertyTexcoords ); + dummyPropertyTexcoords = m_texCoordsHelper.GenerateShaderForOutput( 0, ref dataCollector, false ); + + if( m_texcoordSize > 2 ) + { + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_outputPorts[ 0 ].DataType, finalTexCoordName, uvName ); + dataCollector.AddLocalVariable( UniqueId, finalTexCoordName + ".xy", string.Format( Constants.TilingOffsetFormat, uvName + ".xy", dummyPropertyTexcoords + ".xy", dummyPropertyTexcoords + ".zw" ) + ";" ); + m_outputPorts[ 0 ].SetLocalValue( finalTexCoordName, dataCollector.PortCategory ); + } + else + { + RegisterLocalVariable( 0, string.Format( Constants.TilingOffsetFormat, uvName, dummyPropertyTexcoords + ".xy", dummyPropertyTexcoords + ".zw" ), ref dataCollector, finalTexCoordName ); + } + //RegisterLocalVariable( 0, string.Format( Constants.TilingOffsetFormat, uvName, dummyPropertyTexcoords+".xy", dummyPropertyTexcoords+".zw" ), ref dataCollector, finalTexCoordName ); + } + else + { + string finalTexCoordName = "uv" + m_textureCoordChannel + OutputId; + tiling = m_tilingPort.GeneratePortInstructions( ref dataCollector ); + offset = m_offsetPort.GeneratePortInstructions( ref dataCollector ); + + if( m_texcoordSize > 2 ) + { + dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_outputPorts[ 0 ].DataType, finalTexCoordName, uvName ); + dataCollector.AddLocalVariable( UniqueId, finalTexCoordName + ".xy", string.Format( Constants.TilingOffsetFormat, uvName + ".xy", tiling, offset ) + ";" ); + m_outputPorts[ 0 ].SetLocalValue( finalTexCoordName, dataCollector.PortCategory ); + } + else + { + RegisterLocalVariable( 0, string.Format( Constants.TilingOffsetFormat, uvName, tiling, offset ), ref dataCollector, finalTexCoordName ); + } + //RegisterLocalVariable( 0, string.Format( Constants.TilingOffsetFormat, uvName, tiling, offset ), ref dataCollector, finalTexCoordName ); + } + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + } + + //SURFACE + string propertyName = GetValidPropertyName(); + if( !string.IsNullOrEmpty( portProperty ) && portProperty != "0.0" ) + { + propertyName = portProperty; + } + + if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + + if( !m_tilingPort.IsConnected && m_tilingPort.Vector2InternalData == Vector2.one ) + tiling = null; + else + tiling = m_tilingPort.GeneratePortInstructions( ref dataCollector ); + + if( !m_offsetPort.IsConnected && m_offsetPort.Vector2InternalData == Vector2.zero ) + offset = null; + else + offset = m_offsetPort.GeneratePortInstructions( ref dataCollector ); + + if( !string.IsNullOrEmpty( propertyName ) /*m_referenceArrayId > -1*/ ) + { + m_surfaceTexcoordName = GeneratorUtils.GenerateAutoUVs( ref dataCollector, UniqueId, m_textureCoordChannel, propertyName, m_outputPorts[ 0 ].DataType, tiling, offset, OutputId ); + } + else + { + m_surfaceTexcoordName = GeneratorUtils.GenerateAutoUVs( ref dataCollector, UniqueId, m_textureCoordChannel, null, m_outputPorts[ 0 ].DataType, tiling, offset, OutputId ); + } + + m_outputPorts[ 0 ].SetLocalValue( m_surfaceTexcoordName, dataCollector.PortCategory ); + return GetOutputVectorItem( 0, outputId, m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory ) ); + } + + public override void ReadInputDataFromString( ref string[] nodeParams ) + { + if( UIUtils.CurrentShaderVersion() > 7003 ) + { + base.ReadInputDataFromString( ref nodeParams ); + } + else + { + for( int i = 0; i < 2 && i < nodeParams.Length && m_currentReadParamIdx < nodeParams.Length; i++ ) + { + if( UIUtils.CurrentShaderVersion() < 5003 ) + { + int newId = VersionConvertInputPortId( i ) + 1; + if( UIUtils.CurrentShaderVersion() > 23 ) + { + m_inputPorts[ newId ].DataType = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), nodeParams[ m_currentReadParamIdx++ ] ); + } + + m_inputPorts[ newId ].InternalData = nodeParams[ m_currentReadParamIdx++ ]; + if( m_inputPorts[ newId ].IsEditable && UIUtils.CurrentShaderVersion() >= 3100 && m_currentReadParamIdx < nodeParams.Length ) + { + m_inputPorts[ newId ].Name = nodeParams[ m_currentReadParamIdx++ ]; + } + } + else + { + int portId = Convert.ToInt32( nodeParams[ m_currentReadParamIdx++ ] ); + WirePortDataType DataType = (WirePortDataType)Enum.Parse( typeof( WirePortDataType ), nodeParams[ m_currentReadParamIdx++ ] ); + string InternalData = nodeParams[ m_currentReadParamIdx++ ]; + bool isEditable = Convert.ToBoolean( nodeParams[ m_currentReadParamIdx++ ] ); + string Name = string.Empty; + if( isEditable && m_currentReadParamIdx < nodeParams.Length ) + { + Name = nodeParams[ m_currentReadParamIdx++ ]; + } + + InputPort inputPort = GetInputPortByUniqueId( portId ); + if( inputPort != null ) + { + inputPort.DataType = DataType; + inputPort.InternalData = InternalData; + if( !string.IsNullOrEmpty( Name ) ) + { + inputPort.Name = Name; + } + } + } + } + } + } + + public override void Destroy() + { + base.Destroy(); + m_referenceNode = null; + + if( m_texCoordsHelper != null ) + { + //Not calling m_texCoordsHelper.Destroy() on purpose so UIUtils does not incorrectly unregister stuff + DestroyImmediate( m_texCoordsHelper ); + m_texCoordsHelper = null; + } + } + + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureCoordinatesNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureCoordinatesNode.cs.meta new file mode 100644 index 00000000..be9e1184 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureCoordinatesNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 872b1da17041cd64482c826cbfd9c8c6 +timeCreated: 1481126957 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TexturePropertyNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TexturePropertyNode.cs new file mode 100644 index 00000000..6f3e1016 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TexturePropertyNode.cs @@ -0,0 +1,1175 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + public enum TexturePropertyValues + { + white, + black, + gray, + bump + } + + public enum TextureType + { + Texture1D, + Texture2D, + Texture3D, + Cube, + Texture2DArray, + ProceduralTexture + } + + public enum AutoCastType + { + Auto = 0, + LockedToTexture1D, + LockedToTexture2D, + LockedToTexture3D, + LockedToCube, + LockedToTexture2DArray + } + + + [Serializable] + [NodeAttributes( "Texture Object", "Textures", "Represents a Texture Asset. Can be used in samplers <b>Tex</b> inputs or shader function inputs to reuse the same texture multiple times.", SortOrderPriority = 1 )] + public class TexturePropertyNode : PropertyNode + { + private const string ObjectSelectorCmdStr = "ObjectSelectorClosed"; + + protected readonly string[] AvailablePropertyTypeLabels = { PropertyType.Property.ToString(), PropertyType.Global.ToString() }; + protected readonly int[] AvailablePropertyTypeValues = { (int)PropertyType.Property, (int)PropertyType.Global }; + + protected const int OriginalFontSizeUpper = 9; + protected const int OriginalFontSizeLower = 9; + + protected const string DefaultTextureStr = "Default Texture"; + protected const string AutoCastModeStr = "Auto-Cast Mode"; + + protected const string AutoUnpackNormalsStr = "Normal"; + + [SerializeField] + protected Texture m_defaultValue; + + [SerializeField] + protected Texture m_materialValue; + + [SerializeField] + protected TexturePropertyValues m_defaultTextureValue; + + [SerializeField] + protected bool m_isNormalMap; + + [SerializeField] + protected System.Type m_textureType = typeof( Texture2D ); + + [SerializeField] + protected int m_useSamplerArrayIdx = -1; + + //[SerializeField] + //protected bool m_isTextureFetched; + + //[SerializeField] + //protected string m_textureFetchedValue; + + [SerializeField] + protected TextureType m_currentType = TextureType.Texture2D; + + [SerializeField] + protected AutoCastType m_autocastMode = AutoCastType.Auto; + + protected int PreviewSizeX = 128; + protected int PreviewSizeY = 128; + + protected bool m_linearTexture; + + protected TexturePropertyNode m_textureProperty = null; + + protected bool m_drawPicker; + + protected bool m_drawAutocast = true; + + protected int m_cachedSamplerId = -1; + protected int m_cachedSamplerIdArray = -1; + protected int m_cachedSamplerIdCube = -1; + protected int m_cachedSamplerId3D = -1; + protected int m_defaultId = -1; + protected int m_typeId = -1; + + private TextureType m_previousType = TextureType.Texture2D; + private string m_labelText = "None (Texture2D)"; + + protected bool m_isEditingPicker; + + public TexturePropertyNode() : base() { } + public TexturePropertyNode( 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 ); + GlobalTypeWarningText = string.Format( GlobalTypeWarningText, "Texture" ); + m_defaultTextureValue = TexturePropertyValues.white; + m_insideSize.Set( PreviewSizeX, PreviewSizeY + 5 ); + AddOutputPort( WirePortDataType.SAMPLER2D, "Tex" ); + m_outputPorts[ 0 ].CreatePortRestrictions( WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE, WirePortDataType.OBJECT ); + m_currentParameterType = PropertyType.Property; + m_customPrefix = "Texture "; + m_drawPrecisionUI = false; + m_showVariableMode = true; + m_freeType = false; + m_drawPicker = true; + m_hasLeftDropdown = true; + m_textLabelWidth = 115; + m_longNameSize = 225; + m_availableAttribs.Add( new PropertyAttributes( "No Scale Offset", "[NoScaleOffset]" ) ); + m_availableAttribs.Add( new PropertyAttributes( "Normal", "[Normal]" ) ); + m_availableAttribs.Add( new PropertyAttributes( "Single Line Texture", "[SingleLineTexture]" ) ); + m_showPreview = true; + m_drawPreviewExpander = false; + m_drawPreview = false; + m_drawPreviewMaskButtons = false; + m_previewShaderGUID = "e53988745ec6e034694ee2640cd3d372"; + } + + public override void AfterCommonInit() + { + base.AfterCommonInit(); + m_hasLeftDropdown = true; + } + + protected void SetPreviewTexture( Texture newValue ) + { + if( newValue is Cubemap ) + { + PreviewMaterial.SetInt( m_typeId, 3 ); + + if( m_cachedSamplerIdCube == -1 ) + m_cachedSamplerIdCube = Shader.PropertyToID( "_Cube" ); + + PreviewMaterial.SetTexture( m_cachedSamplerIdCube, newValue as Cubemap ); + } + else if( newValue is Texture2DArray ) + { + PreviewMaterial.SetInt( m_typeId, 4 ); + + if( m_cachedSamplerIdArray == -1 ) + m_cachedSamplerIdArray = Shader.PropertyToID( "_Array" ); + + PreviewMaterial.SetTexture( m_cachedSamplerIdArray, newValue as Texture2DArray ); + } + else if( newValue is Texture3D ) + { + PreviewMaterial.SetInt( m_typeId, 2 ); + + if( m_cachedSamplerId3D == -1 ) + m_cachedSamplerId3D = Shader.PropertyToID( "_Sampler3D" ); + + PreviewMaterial.SetTexture( m_cachedSamplerId3D, newValue as Texture3D ); + } + else + { + PreviewMaterial.SetInt( m_typeId, 1 ); + + if( m_cachedSamplerId == -1 ) + m_cachedSamplerId = Shader.PropertyToID( "_Sampler" ); + + PreviewMaterial.SetTexture( m_cachedSamplerId, newValue ); + } + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + + if( Value == null ) + { + if( m_defaultId == -1 ) + m_defaultId = Shader.PropertyToID( "_Default" ); + + PreviewMaterial.SetInt( m_defaultId, ( (int)m_defaultTextureValue ) + 1 ); + m_previewMaterialPassId = 0; + } + else + { + if( m_defaultId == -1 ) + m_defaultId = Shader.PropertyToID( "_Default" ); + + PreviewMaterial.SetInt( m_defaultId, 0 ); + + if( m_typeId == -1 ) + m_typeId = Shader.PropertyToID( "_Type" ); + + m_previewMaterialPassId = 1; + SetPreviewTexture( Value ); + //if( Value is Cubemap ) + //{ + // PreviewMaterial.SetInt( m_typeId, 3 ); + + // if( m_cachedSamplerIdCube == -1 ) + // m_cachedSamplerIdCube = Shader.PropertyToID( "_Cube" ); + + // PreviewMaterial.SetTexture( m_cachedSamplerIdCube, Value as Cubemap ); + //} + //else if( Value is Texture2DArray ) + //{ + // PreviewMaterial.SetInt( m_typeId, 4 ); + + // if( m_cachedSamplerIdArray == -1 ) + // m_cachedSamplerIdArray = Shader.PropertyToID( "_Array" ); + + // PreviewMaterial.SetTexture( m_cachedSamplerIdArray, Value as Texture2DArray ); + //} + //else if( Value is Texture3D ) + //{ + // PreviewMaterial.SetInt( m_typeId, 2 ); + + // if( m_cachedSamplerId3D == -1 ) + // m_cachedSamplerId3D = Shader.PropertyToID( "_Sampler3D" ); + + // PreviewMaterial.SetTexture( m_cachedSamplerId3D, Value as Texture3D ); + //} + //else + //{ + // PreviewMaterial.SetInt( m_typeId, 1 ); + + // if( m_cachedSamplerId == -1 ) + // m_cachedSamplerId = Shader.PropertyToID( "_Sampler" ); + + // PreviewMaterial.SetTexture( m_cachedSamplerId, Value ); + //} + } + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + m_textureProperty = this; + UIUtils.RegisterPropertyNode( this ); + UIUtils.RegisterTexturePropertyNode( this ); + } + + protected void ConfigTextureData( TextureType type ) + { + switch( m_autocastMode ) + { + case AutoCastType.Auto: + { + m_currentType = type; + } + break; + case AutoCastType.LockedToTexture1D: + { + m_currentType = TextureType.Texture1D; + } + break; + case AutoCastType.LockedToTexture2DArray: + { + m_currentType = TextureType.Texture2DArray; + } + break; + case AutoCastType.LockedToTexture2D: + { + m_currentType = TextureType.Texture2D; + } + break; + case AutoCastType.LockedToTexture3D: + { + m_currentType = TextureType.Texture3D; + } + break; + case AutoCastType.LockedToCube: + { + m_currentType = TextureType.Cube; + } + break; + } + + ConfigTextureType(); + } + + protected void ConfigTextureType() + { + switch( m_currentType ) + { + case TextureType.Texture1D: + { + m_textureType = typeof( Texture ); + } + break; + case TextureType.Texture2DArray: + { + m_textureType = typeof( Texture2DArray ); + } + break; + case TextureType.Texture2D: + { + m_textureType = typeof( Texture2D ); + } + break; + case TextureType.Texture3D: + { + m_textureType = typeof( Texture3D ); + } + break; + case TextureType.Cube: + { + m_textureType = typeof( Cubemap ); + } + break; +#if !UNITY_2018_1_OR_NEWER + // Disabling Substance Deprecated warning +#pragma warning disable 0618 + case TextureType.ProceduralTexture: + { + m_textureType = typeof( ProceduralTexture ); + } + break; +#pragma warning restore 0618 +#endif + + } + } + + protected void DrawTexturePropertyType() + { + PropertyType parameterType = (PropertyType)EditorGUILayoutIntPopup( ParameterTypeStr, (int)m_currentParameterType, AvailablePropertyTypeLabels, AvailablePropertyTypeValues ); + if( parameterType != m_currentParameterType ) + { + ChangeParameterType( parameterType ); + } + } + + // Texture1D + public string GetTexture1DPropertyValue() + { + return PropertyName + "(\"" + m_propertyInspectorName + "\", 2D) = \"" + m_defaultTextureValue + "\" {}"; + } + + public string GetTexture1DUniformValue() + { + return "uniform sampler1D " + PropertyName + ";"; + } + + // Texture2D + public string GetTexture2DPropertyValue() + { + return PropertyName + "(\"" + m_propertyInspectorName + "\", 2D) = \"" + m_defaultTextureValue + "\" {}"; + } + + public string GetTexture2DUniformValue() + { + ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph; + if( outsideGraph.SamplingThroughMacros ) + { + if( outsideGraph.IsSRP ) + { + if( m_useSamplerArrayIdx == 0 ) + return string.Format( Constants.TexDeclarationSRPMacros[ TextureType.Texture2D ], PropertyName ); + else + return string.Format( Constants.TexDeclarationNoSamplerSRPMacros[ TextureType.Texture2D ], PropertyName ); + } + else + { + if( m_useSamplerArrayIdx == 0 ) + return string.Format( Constants.TexDeclarationStandardMacros[ TextureType.Texture2D ], PropertyName ); + else + return string.Format( Constants.TexDeclarationNoSamplerStandardMacros[ TextureType.Texture2D ], PropertyName ); + } + + } + + if( PropertyName == "_CameraDepthTexture" ) + return Constants.CameraDepthTextureValue; + else + return "uniform sampler2D " + PropertyName + ";"; + } + + //Texture3D + public string GetTexture3DPropertyValue() + { + return PropertyName + "(\"" + m_propertyInspectorName + "\", 3D) = \"" + m_defaultTextureValue + "\" {}"; + } + + public string GetTexture3DUniformValue() + { + ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph; + if( outsideGraph.SamplingThroughMacros ) + { + if( outsideGraph.IsSRP ) + { + if( m_useSamplerArrayIdx == 0 ) + return string.Format( Constants.TexDeclarationSRPMacros[ TextureType.Texture3D ], PropertyName ); + else + return string.Format( Constants.TexDeclarationNoSamplerSRPMacros[ TextureType.Texture3D ], PropertyName ); + } + else + { + if( m_useSamplerArrayIdx == 0 ) + return string.Format( Constants.TexDeclarationStandardMacros[ TextureType.Texture3D ], PropertyName ); + else + return string.Format( Constants.TexDeclarationNoSamplerStandardMacros[ TextureType.Texture3D ], PropertyName ); + } + } + return "uniform sampler3D " + PropertyName + ";"; + } + + // Cube + public string GetCubePropertyValue() + { + return PropertyName + "(\"" + m_propertyInspectorName + "\", CUBE) = \"" + m_defaultTextureValue + "\" {}"; + } + + public string GetCubeUniformValue() + { + ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph; + if( outsideGraph.SamplingThroughMacros ) + { + if( outsideGraph.IsSRP ) + { + if( m_useSamplerArrayIdx == 0 ) + return string.Format( Constants.TexDeclarationSRPMacros[ TextureType.Cube ], PropertyName ); + else + return string.Format( Constants.TexDeclarationNoSamplerSRPMacros[ TextureType.Cube ], PropertyName ); + } + else + { + if( m_useSamplerArrayIdx == 0 ) + return string.Format( Constants.TexDeclarationStandardMacros[ TextureType.Cube ], PropertyName ); + else + return string.Format( Constants.TexDeclarationNoSamplerStandardMacros[ TextureType.Cube ], PropertyName ); + } + } + + return "uniform samplerCUBE " + PropertyName + ";"; + } + + // Texture2DArray + public string GetTexture2DArrayPropertyValue() + { + return PropertyName + "(\"" + m_propertyInspectorName + "\", 2DArray) = \"" + m_defaultTextureValue + "\" {}"; + } + + public string GetTexture2DArrayUniformValue() + { + ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph; + if( outsideGraph.SamplingThroughMacros ) + { + if( outsideGraph.IsSRP ) + { + if( m_useSamplerArrayIdx == 0 ) + return string.Format( Constants.TexDeclarationSRPMacros[ TextureType.Texture2DArray ], PropertyName ); + else + return string.Format( Constants.TexDeclarationNoSamplerSRPMacros[ TextureType.Texture2DArray ], PropertyName ); + } + else + { + if( m_useSamplerArrayIdx == 0 ) + return string.Format( Constants.TexDeclarationStandardMacros[ TextureType.Texture2DArray ], PropertyName ); + else + return string.Format( Constants.TexDeclarationNoSamplerStandardMacros[ TextureType.Texture2DArray ], PropertyName ); + } + } + + return "uniform TEXTURE2D_ARRAY( " + PropertyName + " );" + "\nuniform SAMPLER( sampler" + PropertyName + " );"; + } + + public override void DrawMainPropertyBlock() + { + DrawTexturePropertyType(); + base.DrawMainPropertyBlock(); + } + + public override void DrawSubProperties() + { + ShowDefaults(); + + + EditorGUI.BeginChangeCheck(); + Type currType = ( m_autocastMode == AutoCastType.Auto ) ? typeof( Texture ) : m_textureType; + m_defaultValue = EditorGUILayoutObjectField( Constants.DefaultValueLabel, m_defaultValue, currType, false ) as Texture; + if( EditorGUI.EndChangeCheck() ) + { + CheckTextureImporter( true ); + SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) ); + } + } + + public override void DrawMaterialProperties() + { + ShowDefaults(); + + EditorGUI.BeginChangeCheck(); + Type currType = ( m_autocastMode == AutoCastType.Auto ) ? typeof( Texture ) : m_textureType; + m_materialValue = EditorGUILayoutObjectField( Constants.MaterialValueLabel, m_materialValue, currType, false ) as Texture; + if( EditorGUI.EndChangeCheck() ) + { + CheckTextureImporter( true ); + SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) ); + } + } + + new void ShowDefaults() + { + m_defaultTextureValue = (TexturePropertyValues)EditorGUILayoutEnumPopup( DefaultTextureStr, m_defaultTextureValue ); + + if( !m_drawAutocast ) + return; + + AutoCastType newAutoCast = (AutoCastType)EditorGUILayoutEnumPopup( AutoCastModeStr, m_autocastMode ); + if( newAutoCast != m_autocastMode ) + { + m_autocastMode = newAutoCast; + if( m_autocastMode != AutoCastType.Auto ) + { + ConfigTextureData( m_currentType ); + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + } + } + + private void ConfigurePortsFromReference() + { + m_sizeIsDirty = true; + } + + public virtual void ConfigureOutputPorts() + { + switch( m_currentType ) + { + case TextureType.Texture1D: + m_outputPorts[ 0 ].ChangeType( WirePortDataType.SAMPLER1D, false ); + break; + case TextureType.ProceduralTexture: + case TextureType.Texture2D: + m_outputPorts[ 0 ].ChangeType( WirePortDataType.SAMPLER2D, false ); + break; + case TextureType.Texture3D: + m_outputPorts[ 0 ].ChangeType( WirePortDataType.SAMPLER3D, false ); + break; + case TextureType.Cube: + m_outputPorts[ 0 ].ChangeType( WirePortDataType.SAMPLERCUBE, false ); + break; + case TextureType.Texture2DArray: + m_outputPorts[ 0 ].ChangeType( WirePortDataType.SAMPLER2D, false ); + break; + } + + m_sizeIsDirty = true; + } + + public virtual void ConfigureInputPorts() + { + } + + public virtual void AdditionalCheck() + { + } + + public virtual void CheckTextureImporter( bool additionalCheck, bool writeDefault = true ) + { + m_requireMaterialUpdate = true; + Texture texture = m_materialMode ? m_materialValue : m_defaultValue; + TextureImporter importer = AssetImporter.GetAtPath( AssetDatabase.GetAssetPath( texture ) ) as TextureImporter; + if( importer != null ) + { + +#if UNITY_5_5_OR_NEWER + m_isNormalMap = importer.textureType == TextureImporterType.NormalMap; +#else + m_isNormalMap = importer.normalmap; +#endif + if( writeDefault && !UIUtils.IsLoading ) + { + if( m_defaultTextureValue == TexturePropertyValues.bump && !m_isNormalMap ) + m_defaultTextureValue = TexturePropertyValues.white; + else if( m_isNormalMap ) + m_defaultTextureValue = TexturePropertyValues.bump; + } + + if( additionalCheck ) + AdditionalCheck(); + m_linearTexture = !importer.sRGBTexture; + } + + if( ( texture as Texture2DArray ) != null ) + { + ConfigTextureData( TextureType.Texture2DArray ); + } + else if( ( texture as Texture2D ) != null ) + { + ConfigTextureData( TextureType.Texture2D ); + } + else if( ( texture as Texture3D ) != null ) + { + ConfigTextureData( TextureType.Texture3D ); + } + else if( ( texture as Cubemap ) != null ) + { + ConfigTextureData( TextureType.Cube ); + } +#if !UNITY_2018_1_OR_NEWER + // Disabling Substance Deprecated warning +#pragma warning disable 0618 + else if( ( texture as ProceduralTexture ) != null ) + { + ConfigTextureData( TextureType.ProceduralTexture ); + } +#pragma warning restore 0618 +#endif + + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + + public override void OnObjectDropped( UnityEngine.Object obj ) + { + base.OnObjectDropped( obj ); + ConfigFromObject( obj ); + } + + public override void SetupFromCastObject( UnityEngine.Object obj ) + { + base.SetupFromCastObject( obj ); + ConfigFromObject( obj ); + } + + protected void ConfigFromObject( UnityEngine.Object obj, bool writeDefault = true, bool additionalCheck = true ) + { + Texture texture = obj as Texture; + if( texture ) + { + m_materialValue = texture; + m_defaultValue = texture; + CheckTextureImporter( additionalCheck, writeDefault ); + } + } + + + + public override void DrawGUIControls( DrawInfo drawInfo ) + { + base.DrawGUIControls( drawInfo ); + + if( !( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp || drawInfo.CurrentEventType == EventType.ExecuteCommand || drawInfo.CurrentEventType == EventType.DragPerform ) ) + return; + + bool insideBox = m_previewRect.Contains( drawInfo.MousePosition ); + + bool closePicker = false; + if( insideBox ) + { + m_isEditingPicker = true; + } + else if( m_isEditingPicker && !insideBox && drawInfo.CurrentEventType != EventType.ExecuteCommand ) + { + closePicker = true; + } + + if( m_isEditingPicker && drawInfo.CurrentEventType == EventType.ExecuteCommand && + Event.current.commandName.Equals( ObjectSelectorCmdStr ) ) + { + closePicker = true; + } + + if( closePicker ) + { + GUI.FocusControl( null ); + m_isEditingPicker = false; + } + + } + + public override void OnNodeLayout( DrawInfo drawInfo ) + { + base.OnNodeLayout( drawInfo ); + ConfigTextureType(); + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + if( m_dropdownEditing ) + { + PropertyType parameterType = (PropertyType)EditorGUIIntPopup( m_dropdownRect, (int)m_currentParameterType, AvailablePropertyTypeLabels, AvailablePropertyTypeValues, UIUtils.PropertyPopUp ); + if( parameterType != m_currentParameterType ) + { + ChangeParameterType( parameterType ); + DropdownEditing = false; + } + } + + if( m_isEditingPicker && m_drawPicker && m_currentParameterType != PropertyType.Global ) + { + Rect hitRect = m_previewRect; + hitRect.height = 14 * drawInfo.InvertedZoom; + hitRect.y = m_previewRect.yMax - hitRect.height; + hitRect.width = 4 * 14 * drawInfo.InvertedZoom; + + bool restoreMouse = false; + if( Event.current.type == EventType.MouseDown && hitRect.Contains( drawInfo.MousePosition ) ) + { + restoreMouse = true; + Event.current.type = EventType.Ignore; + } + + EditorGUI.BeginChangeCheck(); + m_colorBuffer = GUI.color; + GUI.color = Color.clear; + Type currType = ( m_autocastMode == AutoCastType.Auto ) ? typeof( Texture ) : m_textureType; + if( m_materialMode ) + { + m_materialValue = EditorGUIObjectField( m_previewRect, m_materialValue, currType, false ) as Texture; + } + else + { + m_defaultValue = EditorGUIObjectField( m_previewRect, m_defaultValue, currType, false ) as Texture; + } + GUI.color = m_colorBuffer; + + if( EditorGUI.EndChangeCheck() ) + { + CheckTextureImporter( true ); + SetTitleText( m_propertyInspectorName ); + SetAdditonalTitleText( string.Format( Constants.PropertyValueLabel, GetPropertyValStr() ) ); + ConfigureInputPorts(); + ConfigureOutputPorts(); + BeginDelayedDirtyProperty(); + PreviewIsDirty = true; + } + //else if( drawInfo.CurrentEventType == EventType.ExecuteCommand ) + //{ + // GUI.FocusControl( null ); + // m_isEditingPicker = false; + //} + + if( restoreMouse ) + { + Event.current.type = EventType.MouseDown; + } + + if( ( drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp ) ) + DrawPreviewMaskButtonsLayout( drawInfo, m_previewRect ); + } + + if( !m_drawPicker ) + return; + + if( drawInfo.CurrentEventType == EventType.Repaint ) + { + DrawTexturePicker( drawInfo ); + } + } + + + + protected void DrawTexturePicker( DrawInfo drawInfo ) + { + Rect newRect = m_previewRect; + Texture currentValue = m_materialMode ? m_materialValue : m_defaultValue; + + //??? + //m_showPreview = true; + bool showButtons = m_currentParameterType != PropertyType.Global; + + if( currentValue == null ) + GUI.Label( newRect, string.Empty, UIUtils.ObjectFieldThumb ); + else + DrawPreview( drawInfo, m_previewRect ); + + if( ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2 ) + { + Rect butRect = m_previewRect; + butRect.y -= 1; + butRect.x += 1; + + Rect smallButton = newRect; + smallButton.height = 14 * drawInfo.InvertedZoom; + smallButton.y = newRect.yMax - smallButton.height - 2; + smallButton.width = 40 * drawInfo.InvertedZoom; + smallButton.x = newRect.xMax - smallButton.width - 2; + if( currentValue == null ) + { + if( m_previousType != m_currentType ) + { + m_previousType = m_currentType; + m_labelText = "None (" + m_currentType.ToString() + ")"; + } + + GUI.Label( newRect, m_labelText, UIUtils.ObjectFieldThumbOverlay ); + } + else if( showButtons ) + { + DrawPreviewMaskButtonsRepaint( drawInfo, butRect ); + } + + if( showButtons ) + GUI.Label( smallButton, "Select", UIUtils.GetCustomStyle( CustomStyle.SamplerButton ) ); + } + + GUI.Label( newRect, string.Empty, UIUtils.GetCustomStyle( CustomStyle.SamplerFrame ) ); + } + + public string BaseGenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalVar ); + return PropertyName; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar ) + { + return BaseGenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalVar ); + } + + public override void UpdateMaterial( Material mat ) + { + base.UpdateMaterial( mat ); + if( UIUtils.IsProperty( m_currentParameterType ) && !InsideShaderFunction ) + { + OnPropertyNameChanged(); + if( mat.HasProperty( PropertyName ) ) + { + mat.SetTexture( PropertyName, m_materialValue ); + } + } + } + + public override void SetMaterialMode( Material mat, bool fetchMaterialValues ) + { + base.SetMaterialMode( mat, fetchMaterialValues ); + if( fetchMaterialValues && m_materialMode && UIUtils.IsProperty( m_currentParameterType ) ) + { + if( mat.HasProperty( PropertyName ) ) + { + m_materialValue = mat.GetTexture( PropertyName ); + CheckTextureImporter( false, false ); + } + } + } + + public override void ForceUpdateFromMaterial( Material material ) + { + if( UIUtils.IsProperty( m_currentParameterType ) && material.HasProperty( PropertyName ) ) + { + m_materialValue = material.GetTexture( PropertyName ); + CheckTextureImporter( false, false ); + PreviewIsDirty = true; + } + } + + public override bool UpdateShaderDefaults( ref Shader shader, ref TextureDefaultsDataColector defaultCol/* ref string metaStr */) + { + if( m_defaultValue != null ) + { + defaultCol.AddValue( PropertyName, m_defaultValue ); + } + + return true; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + ReadAdditionalData( ref nodeParams ); + if( UIUtils.CurrentShaderVersion() > 17101 ) + { + m_useSamplerArrayIdx = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + } + } + + public virtual void ReadAdditionalData( ref string[] nodeParams ) + { + string defaultTextureGUID = GetCurrentParam( ref nodeParams ); + //m_defaultValue = AssetDatabase.LoadAssetAtPath<Texture>( textureName ); + if( UIUtils.CurrentShaderVersion() > 14101 ) + { + m_defaultValue = AssetDatabase.LoadAssetAtPath<Texture>( AssetDatabase.GUIDToAssetPath( defaultTextureGUID ) ); + string materialTextureGUID = GetCurrentParam( ref nodeParams ); + m_materialValue = AssetDatabase.LoadAssetAtPath<Texture>( AssetDatabase.GUIDToAssetPath( materialTextureGUID ) ); + } + else + { + m_defaultValue = AssetDatabase.LoadAssetAtPath<Texture>( defaultTextureGUID ); + } + + m_isNormalMap = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_defaultTextureValue = (TexturePropertyValues)Enum.Parse( typeof( TexturePropertyValues ), GetCurrentParam( ref nodeParams ) ); + m_autocastMode = (AutoCastType)Enum.Parse( typeof( AutoCastType ), GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > 15306 ) + { + m_currentType = (TextureType)Enum.Parse( typeof( TextureType ), GetCurrentParam( ref nodeParams ) ); + } + else + { + m_currentType = TextureType.Texture2D; + } + + ConfigTextureData( m_currentType ); + + //ConfigFromObject( m_defaultValue ); + if( m_materialValue == null ) + { + ConfigFromObject( m_defaultValue ); + } + else + { + CheckTextureImporter( true, true ); + } + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + + public override void ReadAdditionalClipboardData( ref string[] nodeParams ) + { + base.ReadAdditionalClipboardData( ref nodeParams ); + string textureName = GetCurrentParam( ref nodeParams ); + m_materialValue = AssetDatabase.LoadAssetAtPath<Texture>( textureName ); + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + WriteAdditionalToString( ref nodeInfo, ref connectionsInfo ); + if( m_useSamplerArrayIdx > 0 ) + { + TexturePropertyNode samplerNode = UIUtils.GetTexturePropertyNode( m_useSamplerArrayIdx - 1 ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( samplerNode != null ? samplerNode.UniqueId : -1 ) ); + } + else + { + IOUtils.AddFieldValueToString( ref nodeInfo, -1 ); + } + } + + public virtual void WriteAdditionalToString( ref string nodeInfo, ref string connectionsInfo ) + { + //IOUtils.AddFieldValueToString( ref nodeInfo, ( m_defaultValue != null ) ? AssetDatabase.GetAssetPath( m_defaultValue ) : Constants.NoStringValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_defaultValue != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_defaultValue ) ) : Constants.NoStringValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_materialValue != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_materialValue ) ) : Constants.NoStringValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_isNormalMap.ToString() ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_defaultTextureValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autocastMode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_currentType ); + } + + public override void WriteAdditionalClipboardData( ref string nodeInfo ) + { + base.WriteAdditionalClipboardData( ref nodeInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_materialValue != null ) ? AssetDatabase.GetAssetPath( m_materialValue ) : Constants.NoStringValue ); + } + + public override void Destroy() + { + base.Destroy(); + m_defaultValue = null; + m_materialValue = null; + m_textureProperty = null; + UIUtils.UnregisterPropertyNode( this ); + UIUtils.UnregisterTexturePropertyNode( this ); + } + + public override string GetPropertyValStr() + { + return m_materialMode ? ( m_materialValue != null ? m_materialValue.name : IOUtils.NO_TEXTURES ) : ( m_defaultValue != null ? m_defaultValue.name : IOUtils.NO_TEXTURES ); + } + + public override string GetPropertyValue() + { + switch( m_currentType ) + { + case TextureType.Texture1D: + { + return PropertyAttributes + GetTexture1DPropertyValue(); + } + case TextureType.ProceduralTexture: + case TextureType.Texture2D: + { + return PropertyAttributes + GetTexture2DPropertyValue(); + } + case TextureType.Texture3D: + { + return PropertyAttributes + GetTexture3DPropertyValue(); + } + case TextureType.Cube: + { + return PropertyAttributes + GetCubePropertyValue(); + } + case TextureType.Texture2DArray: + { + return PropertyAttributes + GetTexture2DArrayPropertyValue(); + } + } + return string.Empty; + } + + public override string GetUniformValue() + { + switch( m_currentType ) + { + case TextureType.Texture1D: + { + return GetTexture1DUniformValue(); + } + case TextureType.ProceduralTexture: + case TextureType.Texture2D: + { + return GetTexture2DUniformValue(); + } + case TextureType.Texture3D: + { + return GetTexture3DUniformValue(); + } + case TextureType.Cube: + { + return GetCubeUniformValue(); + } + case TextureType.Texture2DArray: + { + return GetTexture2DArrayUniformValue(); + } + } + + return string.Empty; + } + + public override bool GetUniformData( out string dataType, out string dataName, ref bool fullValue ) + { + m_excludeUniform = false; + ParentGraph outsideGraph = UIUtils.CurrentWindow.OutsideGraph; + if( outsideGraph.SamplingThroughMacros ) + { + if( outsideGraph.IsSRP ) + { + if( Constants.TexDeclarationSRPMacros.ContainsKey( m_currentType ) ) + { + if( m_useSamplerArrayIdx == 0 ) + dataName = string.Format( Constants.TexDeclarationSRPMacros[ m_currentType ], PropertyName ); + else + dataName = string.Format( Constants.TexDeclarationNoSamplerSRPMacros[ m_currentType ], PropertyName ); + dataType = string.Empty; + fullValue = true; + return true; + } + } + else if( Constants.TexDeclarationStandardMacros.ContainsKey( m_currentType ) ) + { + if( m_useSamplerArrayIdx == 0 ) + dataName = string.Format( Constants.TexDeclarationStandardMacros[ m_currentType ], PropertyName ); + else + dataName = string.Format( Constants.TexDeclarationNoSamplerStandardMacros[ m_currentType ], PropertyName ); + dataType = string.Empty; + fullValue = true; + return true; + } + } + + if( PropertyName == "_CameraDepthTexture" ) + { + m_excludeUniform = true; + dataType = "UNITY_DECLARE_DEPTH_TEXTURE("; + dataName = m_propertyName + " )"; + return true; + } + + if( m_currentType == TextureType.Texture2DArray ) + { + MasterNode masterNode = UIUtils.CurrentWindow.OutsideGraph.CurrentMasterNode; + if( masterNode.CurrentDataCollector.IsTemplate && masterNode.CurrentDataCollector.IsSRP ) + { + dataType = "TEXTURE2D_ARRAY( " + PropertyName + ""; + dataName = ");\nuniform SAMPLER( sampler" + PropertyName + " )"; + return true; + } + dataType = "UNITY_DECLARE_TEX2DARRAY("; + dataName = m_propertyName + " )"; + return true; + } + + + dataType = UIUtils.TextureTypeToCgType( m_currentType ); + dataName = m_propertyName; + return true; + } + + public virtual string CurrentPropertyReference + { + get + { + string propertyName = string.Empty; + propertyName = PropertyName; + return propertyName; + } + } + + public Texture Value + { + get { return m_materialMode ? m_materialValue : m_defaultValue; } + set + { + if( m_materialMode ) + m_materialValue = value; + else + m_defaultValue = value; + } + } + + public Texture MaterialValue + { + get { return m_materialValue; } + set { m_materialValue = value; } + } + + public Texture DefaultValue + { + get { return m_defaultValue; } + set { m_defaultValue = value; } + } + + public void SetInspectorName( string newName ) + { + m_propertyInspectorName = newName; + } + + public void SetPropertyName( string newName ) + { + m_propertyName = newName; + } + + public bool IsValid { get { return m_materialMode ? ( m_materialValue != null ) : ( m_defaultValue != null ); } } + + public virtual bool IsNormalMap { get { return m_isNormalMap; } } + public bool IsLinearTexture { get { return m_linearTexture; } } + + public override void OnPropertyNameChanged() + { + base.OnPropertyNameChanged(); + UIUtils.UpdateTexturePropertyDataNode( UniqueId, PropertyName ); + } + + public override void SetGlobalValue() { Shader.SetGlobalTexture( m_propertyName, m_defaultValue ); } + public override void FetchGlobalValue() { m_materialValue = Shader.GetGlobalTexture( m_propertyName ); } + public override string DataToArray { get { return PropertyName; } } + public TextureType CurrentType { get { return m_currentType; } } + + public bool DrawAutocast + { + get { return m_drawAutocast; } + set { m_drawAutocast = value; } + } + + public TexturePropertyValues DefaultTextureValue + { + get { return m_defaultTextureValue; } + set { m_defaultTextureValue = value; } + } + + public AutoCastType AutocastMode + { + get { return m_autocastMode; } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TexturePropertyNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TexturePropertyNode.cs.meta new file mode 100644 index 00000000..721cc6df --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TexturePropertyNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c1210b3dd22dafe418c5a998df2c3443 +timeCreated: 1481126959 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureTransformNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureTransformNode.cs new file mode 100644 index 00000000..c35e550d --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureTransformNode.cs @@ -0,0 +1,355 @@ +using UnityEngine; +using UnityEditor; +using System; +using System.Collections.Generic; + +namespace AmplifyShaderEditor +{ + [Serializable] + [NodeAttributes( "Texture Transform", "Textures", "Gives access to texture tiling and offset as set on the material inspector" )] + public sealed class TextureTransformNode : ParentNode + { + private readonly string[] Dummy = { string.Empty }; + private const string InstancedLabelStr = "Instanced"; + + [SerializeField] + private bool m_instanced = false; + + [SerializeField] + private int m_referenceSamplerId = -1; + + [SerializeField] + private int m_referenceNodeId = -1; + + [SerializeField] + private TexturePropertyNode m_inputReferenceNode = null; + + private TexturePropertyNode m_referenceNode = null; + + private Vector4Node m_texCoordsHelper; + + private UpperLeftWidgetHelper m_upperLeftWidget = new UpperLeftWidgetHelper(); + + private int m_cachedSamplerId = -1; + private int m_cachedSamplerIdArray = -1; + private int m_cachedSamplerIdCube = -1; + private int m_cachedSamplerId3D = -1; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.SAMPLER2D, false, "Tex" ); + m_inputPorts[ 0 ].CreatePortRestrictions( WirePortDataType.SAMPLER1D, WirePortDataType.SAMPLER2D, WirePortDataType.SAMPLER3D, WirePortDataType.SAMPLERCUBE, WirePortDataType.OBJECT ); + AddOutputPort( WirePortDataType.FLOAT2, "Tiling" ); + AddOutputPort( WirePortDataType.FLOAT2, "Offset" ); + m_textLabelWidth = 80; + m_autoWrapProperties = true; + m_hasLeftDropdown = true; + m_previewShaderGUID = "25ba2903568b00343ae06788994cab54"; + } + + public override void AfterCommonInit() + { + base.AfterCommonInit(); + + if( PaddingTitleLeft == 0 ) + { + PaddingTitleLeft = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin; + if( PaddingTitleRight == 0 ) + PaddingTitleRight = Constants.PropertyPickerWidth + Constants.IconsLeftRightMargin; + } + } + + public override void RenderNodePreview() + { + //Runs at least one time + if( !m_initialized ) + { + // nodes with no preview don't update at all + PreviewIsDirty = false; + return; + } + + if( !PreviewIsDirty ) + return; + + SetPreviewInputs(); + + RenderTexture temp = RenderTexture.active; + + RenderTexture.active = m_outputPorts[ 0 ].OutputPreviewTexture; + PreviewMaterial.SetInt( "_PreviewID", 0 ); + Graphics.Blit( null, m_outputPorts[ 0 ].OutputPreviewTexture, PreviewMaterial, m_previewMaterialPassId ); + + RenderTexture.active = m_outputPorts[ 1 ].OutputPreviewTexture; + PreviewMaterial.SetInt( "_PreviewID", 1 ); + Graphics.Blit( null, m_outputPorts[ 1 ].OutputPreviewTexture, PreviewMaterial, m_previewMaterialPassId ); + RenderTexture.active = temp; + + PreviewIsDirty = m_continuousPreviewRefresh; + + FinishPreviewRender = true; + } + + void SetPreviewTexture( Texture newValue ) + { + if( newValue is Cubemap ) + { + m_previewMaterialPassId = 3; + if( m_cachedSamplerIdCube == -1 ) + m_cachedSamplerIdCube = Shader.PropertyToID( "_Cube" ); + + PreviewMaterial.SetTexture( m_cachedSamplerIdCube, newValue as Cubemap ); + } + else if( newValue is Texture2DArray ) + { + + m_previewMaterialPassId = 2; + if( m_cachedSamplerIdArray == -1 ) + m_cachedSamplerIdArray = Shader.PropertyToID( "_Array" ); + + PreviewMaterial.SetTexture( m_cachedSamplerIdArray, newValue as Texture2DArray ); + } + else if( newValue is Texture3D ) + { + m_previewMaterialPassId = 1; + if( m_cachedSamplerId3D == -1 ) + m_cachedSamplerId3D = Shader.PropertyToID( "_Sampler3D" ); + + PreviewMaterial.SetTexture( m_cachedSamplerId3D, newValue as Texture3D ); + } + else + { + m_previewMaterialPassId = 0; + if( m_cachedSamplerId == -1 ) + m_cachedSamplerId = Shader.PropertyToID( "_Sampler" ); + + PreviewMaterial.SetTexture( m_cachedSamplerId, newValue ); + } + } + + public override void SetPreviewInputs() + { + base.SetPreviewInputs(); + if( m_inputPorts[ 0 ].IsConnected ) + { + SetPreviewTexture( m_inputPorts[ 0 ].InputPreviewTexture( ContainerGraph ) ); + } + else if( m_referenceNode != null ) + { + if( m_referenceNode.Value != null ) + { + SetPreviewTexture( m_referenceNode.Value ); + } + else + { + SetPreviewTexture( m_referenceNode.PreviewTexture ); + } + } + } + + public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true ) + { + base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode ); + m_inputReferenceNode = m_inputPorts[ 0 ].GetOutputNodeWhichIsNotRelay() as TexturePropertyNode; + UpdateTitle(); + + } + + + public override void OnInputPortDisconnected( int portId ) + { + base.OnInputPortDisconnected( portId ); + m_inputReferenceNode = null; + UpdateTitle(); + } + + + void UpdateTitle() + { + if( m_inputReferenceNode != null ) + { + m_additionalContent.text = string.Format( Constants.PropertyValueLabel, m_inputReferenceNode.PropertyInspectorName ); + } + else if( m_referenceSamplerId > -1 && m_referenceNode != null ) + { + m_additionalContent.text = string.Format( Constants.PropertyValueLabel, m_referenceNode.PropertyInspectorName ); + } + else + { + m_additionalContent.text = string.Empty; + } + m_sizeIsDirty = true; + } + + public override void DrawProperties() + { + base.DrawProperties(); + bool guiEnabledBuffer = GUI.enabled; + EditorGUI.BeginChangeCheck(); + List<string> arr = new List<string>( UIUtils.TexturePropertyNodeArr() ); + + if( arr != null && arr.Count > 0 ) + { + arr.Insert( 0, "None" ); + GUI.enabled = true && ( !m_inputPorts[ 0 ].IsConnected ); + m_referenceSamplerId = EditorGUILayoutPopup( Constants.AvailableReferenceStr, m_referenceSamplerId + 1, arr.ToArray() ) - 1; + } + else + { + m_referenceSamplerId = -1; + GUI.enabled = false; + EditorGUILayoutPopup( Constants.AvailableReferenceStr, m_referenceSamplerId, Dummy ); + } + + GUI.enabled = guiEnabledBuffer; + if( EditorGUI.EndChangeCheck() ) + { + m_referenceNode = UIUtils.GetTexturePropertyNode( m_referenceSamplerId ); + if( m_referenceNode != null ) + { + m_referenceNodeId = m_referenceNode.UniqueId; + } + else + { + m_referenceNodeId = -1; + m_referenceSamplerId = -1; + } + UpdateTitle(); + } + + m_instanced = EditorGUILayoutToggle( InstancedLabelStr, m_instanced ); + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + if( !m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + string texTransform = string.Empty; + + if( m_inputPorts[ 0 ].IsConnected ) + { + texTransform = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ) + "_ST"; + } + else if( m_referenceNode != null ) + { + m_referenceNode.BaseGenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); + texTransform = m_referenceNode.PropertyName + "_ST"; + } + else + { + texTransform = "_ST"; + UIUtils.ShowMessage( UniqueId, "Please specify a texture sample on the Texture Transform Size node", MessageSeverity.Warning ); + } + + //bool excludeUniformKeyword = UIUtils.CurrentWindow.OutsideGraph.IsInstancedShader || UIUtils.CurrentWindow.OutsideGraph.IsSRP; + //string uniformRegister = UIUtils.GenerateUniformName( excludeUniformKeyword, WirePortDataType.FLOAT4, texTransform ); + //dataCollector.AddToUniforms( UniqueId, uniformRegister, true ); + if( m_texCoordsHelper == null ) + { + m_texCoordsHelper = CreateInstance<Vector4Node>(); + m_texCoordsHelper.ContainerGraph = ContainerGraph; + m_texCoordsHelper.SetBaseUniqueId( UniqueId, true ); + m_texCoordsHelper.RegisterPropertyOnInstancing = false; + m_texCoordsHelper.AddGlobalToSRPBatcher = true; + } + + if( m_instanced ) + { + m_texCoordsHelper.CurrentParameterType = PropertyType.InstancedProperty; + } + else + { + m_texCoordsHelper.CurrentParameterType = PropertyType.Global; + } + m_texCoordsHelper.ResetOutputLocals(); + m_texCoordsHelper.SetRawPropertyName( texTransform ); + texTransform = m_texCoordsHelper.GenerateShaderForOutput( 0, ref dataCollector, false ); + + m_outputPorts[ 0 ].SetLocalValue( texTransform+ ".xy", dataCollector.PortCategory ); + m_outputPorts[ 1 ].SetLocalValue( texTransform + ".zw", dataCollector.PortCategory ); + } + + return m_outputPorts[ outputId ].LocalValue( dataCollector.PortCategory ); + } + + public override void Draw( DrawInfo drawInfo ) + { + base.Draw( drawInfo ); + + EditorGUI.BeginChangeCheck(); + { + List<string> arr = new List<string>( UIUtils.TexturePropertyNodeArr() ); + bool guiEnabledBuffer = GUI.enabled; + + if( arr != null && arr.Count > 0 ) + { + arr.Insert( 0, "None" ); + GUI.enabled = true && ( !m_inputPorts[ 0 ].IsConnected ); + m_referenceSamplerId = m_upperLeftWidget.DrawWidget( this, m_referenceSamplerId + 1, arr.ToArray() ) - 1; + } + else + { + m_referenceSamplerId = -1; + GUI.enabled = false; + m_upperLeftWidget.DrawWidget( this, m_referenceSamplerId, Dummy ); + } + GUI.enabled = guiEnabledBuffer; + } + if( EditorGUI.EndChangeCheck() ) + { + m_referenceNode = UIUtils.GetTexturePropertyNode( m_referenceSamplerId ); + if( m_referenceNode != null ) + { + m_referenceNodeId = m_referenceNode.UniqueId; + } + else + { + m_referenceNodeId = -1; + m_referenceSamplerId = -1; + } + UpdateTitle(); + } + } + + public override void RefreshExternalReferences() + { + base.RefreshExternalReferences(); + m_referenceNode = UIUtils.GetNode( m_referenceNodeId ) as TexturePropertyNode; + m_referenceSamplerId = UIUtils.GetTexturePropertyNodeRegisterId( m_referenceNodeId ); + UpdateTitle(); + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + m_referenceNodeId = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + if( UIUtils.CurrentShaderVersion() > 17200 ) + { + m_instanced = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + } + } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_referenceNodeId ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_instanced ); + } + + public override void Destroy() + { + base.Destroy(); + m_referenceNode = null; + m_inputReferenceNode = null; + m_upperLeftWidget = null; + if( m_texCoordsHelper != null ) + { + //Not calling m_texCoordsHelper.Destroy() on purpose so UIUtils does not incorrectly unregister stuff + DestroyImmediate( m_texCoordsHelper ); + m_texCoordsHelper = null; + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureTransformNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureTransformNode.cs.meta new file mode 100644 index 00000000..be1ce29d --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/TextureTransformNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4f9ca941b3f5014448e530c761a418d9 +timeCreated: 1512045037 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/UnpackScaleNormalNode.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/UnpackScaleNormalNode.cs new file mode 100644 index 00000000..364cfcca --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/UnpackScaleNormalNode.cs @@ -0,0 +1,68 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using System; +namespace AmplifyShaderEditor +{ + [NodeAttributes( "Unpack Scale Normal", "Textures", "Applies UnpackNormal/UnpackScaleNormal function" )] + [Serializable] + public class UnpackScaleNormalNode : ParentNode + { + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + AddInputPort( WirePortDataType.FLOAT4, false, "Value" ); + AddInputPort( WirePortDataType.FLOAT, false, "Scale" ); + m_inputPorts[ 1 ].FloatInternalData = 1; + AddOutputVectorPorts( WirePortDataType.FLOAT3, "XYZ" ); + m_useInternalPortData = true; + m_previewShaderGUID = "8b0ae05e25d280c45af81ded56f8012e"; + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) + { + string src = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector ); + + + bool isScaledNormal = false; + if ( m_inputPorts[ 1 ].IsConnected ) + { + isScaledNormal = true; + } + else + { + if ( m_inputPorts[ 1 ].FloatInternalData != 1 ) + { + isScaledNormal = true; + } + } + + string normalMapUnpackMode = string.Empty; + string scaleValue = isScaledNormal?m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector ):"1.0"; + normalMapUnpackMode = string.Format( TemplateHelperFunctions.CreateUnpackNormalStr( dataCollector, isScaledNormal, scaleValue ), src); + if( isScaledNormal && !( dataCollector.IsTemplate && dataCollector.IsSRP ) ) + { + dataCollector.AddToIncludes( UniqueId, Constants.UnityStandardUtilsLibFuncs ); + } + + int outputUsage = 0; + for ( int i = 0; i < m_outputPorts.Count; i++ ) + { + if ( m_outputPorts[ i ].IsConnected ) + outputUsage += 1; + } + + + if ( outputUsage > 1 ) + { + string varName = "localUnpackNormal" + OutputId; + dataCollector.AddLocalVariable( UniqueId, "float3 " + varName + " = " + normalMapUnpackMode + ";" ); + return GetOutputVectorItem( 0, outputId, varName ); + } + else + { + return GetOutputVectorItem( 0, outputId, normalMapUnpackMode ); + } + } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/UnpackScaleNormalNode.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/UnpackScaleNormalNode.cs.meta new file mode 100644 index 00000000..270e519f --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/UnpackScaleNormalNode.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ad04713692e9f124e86030d792c3e648 +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/VirtualTextureObject.cs b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/VirtualTextureObject.cs new file mode 100644 index 00000000..339cdc24 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/VirtualTextureObject.cs @@ -0,0 +1,296 @@ +// Amplify Shader Editor - Visual Shader Editing Tool +// Copyright (c) Amplify Creations, Lda <info@amplify.pt> + +using UnityEngine; +using UnityEditor; +using System; + +namespace AmplifyShaderEditor +{ + public enum VirtualPreset + { + Unity_Legacy, + Unity5, + Alloy, + UBER, + Skyshop, + Lux + } + + public enum VirtualChannel + { + Albedo = 0, + Base, + Normal, + Height, + Occlusion, + Displacement, + Specular, + SpecMet, + Material, + } + + [Serializable] + [NodeAttributes( "Virtual Texture Object", "Textures", "Represents a Virtual Texture Asset", SortOrderPriority = 1 )] + public class VirtualTextureObject : TexturePropertyNode + { + protected const string VirtualPresetStr = "Layout Preset"; + protected const string VirtualChannelStr = "Virtual Layer"; + + private const string VirtualTextureObjectInfo = "Can only be used alongside a Texture Sample node by connecting to its Tex Input Port.\n" + + "\nProperty name must match the value set on your Virtual Texture.\n" + + "Default e.g Albedo = _MainTex\n" + + "\nName your node according to the respective channel property in your Virtual Texture. The Albedo must be set to _MainTex ( temporary requirement )."; + private readonly string[] ChannelTypeStr = { + "Albedo - D.RGBA", + "Base - D.RGBA", + "Normal - N.GA", + "Height - N.B", + "Occlusion - N.R", + "Displacement - N.B", + "Specular - S.RGBA", + "Specular|Metallic - S.RGBA", + "Material - S.RGBA",}; + + private readonly string[] Dummy = { string.Empty }; + private string[] m_channelTypeStr; + + [SerializeField] + protected VirtualPreset m_virtualPreset = VirtualPreset.Unity5; + + [SerializeField] + protected VirtualChannel m_virtualChannel = VirtualChannel.Albedo; + + [SerializeField] + private int m_selectedChannelInt = 0; + + protected override void CommonInit( int uniqueId ) + { + base.CommonInit( uniqueId ); + ChangeChannels(); + } + + protected override void OnUniqueIDAssigned() + { + base.OnUniqueIDAssigned(); + if ( UniqueId != -1 ) + UIUtils.AddVirtualTextureCount(); + } + + public override void DrawSubProperties() + { + ShowDefaults(); + + base.DrawSubProperties(); + } + + public override void DrawMaterialProperties() + { + ShowDefaults(); + + base.DrawMaterialProperties(); + } + + new void ShowDefaults() + { + EditorGUI.BeginChangeCheck(); + m_virtualPreset = ( VirtualPreset ) EditorGUILayoutEnumPopup( VirtualPresetStr, m_virtualPreset ); + if ( EditorGUI.EndChangeCheck() ) + { + ChangeChannels(); + } + + EditorGUI.BeginChangeCheck(); + m_selectedChannelInt = EditorGUILayoutPopup( VirtualChannelStr, m_selectedChannelInt, m_channelTypeStr ); + if ( EditorGUI.EndChangeCheck() ) + { + m_virtualChannel = GetChannel( m_selectedChannelInt ); + } + } + + public override void DrawProperties() + { + base.DrawProperties(); + EditorGUILayout.HelpBox( VirtualTextureObjectInfo, MessageType.Info ); + } + + private VirtualChannel GetChannel( int popupInt ) + { + int remapInt = 0; + switch ( m_virtualPreset ) + { + case VirtualPreset.Unity_Legacy: + remapInt = popupInt == 0 ? 1 : popupInt == 1 ? 2 : popupInt == 2 ? 4 : popupInt == 3 ? 5 : 0; + break; + default: + case VirtualPreset.Unity5: + case VirtualPreset.UBER: + remapInt = popupInt == 0 ? 0 : popupInt == 1 ? 7 : popupInt == 2 ? 2 : popupInt == 3 ? 3 : popupInt == 4 ? 4 : 0; + break; + case VirtualPreset.Alloy: + remapInt = popupInt == 0 ? 1 : popupInt == 1 ? 2 : popupInt == 2 ? 8 : popupInt == 3 ? 3 : 0; + break; + case VirtualPreset.Skyshop: + case VirtualPreset.Lux: + remapInt = popupInt == 0 ? 1 : popupInt == 1 ? 2 : popupInt == 2 ? 6 : 0; + break; + } + + return ( VirtualChannel ) remapInt; + } + + private void ChangeChannels() + { + m_channelTypeStr = Dummy; + switch ( m_virtualPreset ) + { + case VirtualPreset.Unity_Legacy: + m_channelTypeStr = new string[] { ChannelTypeStr[ 1 ], ChannelTypeStr[ 2 ], ChannelTypeStr[ 4 ], ChannelTypeStr[ 5 ] }; + break; + default: + case VirtualPreset.Unity5: + case VirtualPreset.UBER: + m_channelTypeStr = new string[] { ChannelTypeStr[ 0 ], ChannelTypeStr[ 7 ], ChannelTypeStr[ 2 ], ChannelTypeStr[ 3 ], ChannelTypeStr[ 4 ] }; + break; + case VirtualPreset.Alloy: + m_channelTypeStr = new string[] { ChannelTypeStr[ 1 ], ChannelTypeStr[ 2 ], ChannelTypeStr[ 8 ], ChannelTypeStr[ 3 ] }; + break; + case VirtualPreset.Skyshop: + case VirtualPreset.Lux: + m_channelTypeStr = new string[] { ChannelTypeStr[ 1 ], ChannelTypeStr[ 2 ], ChannelTypeStr[ 6 ] }; + break; + } + } + + public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar ) + { + base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalVar ); + dataCollector.AddToProperties( UniqueId, "[HideInInspector] _VTInfoBlock( \"VT( auto )\", Vector ) = ( 0, 0, 0, 0 )", -1 ); + + return PropertyName; + } + + public override string GetPropertyValue() + { + string propertyValue = string.Empty; + switch ( m_virtualChannel ) + { + default: + case VirtualChannel.Albedo: + case VirtualChannel.Base: + propertyValue = PropertyName + "(\"" + m_propertyInspectorName + "\", 2D) = \"" + m_defaultTextureValue + "\" {}"; + break; + case VirtualChannel.Normal: + propertyValue = PropertyName + "(\"" + m_propertyInspectorName + "\", 2D) = \"" + m_defaultTextureValue + "\" {}"; + break; + case VirtualChannel.SpecMet: + propertyValue = PropertyName + "(\"" + m_propertyInspectorName + "\", 2D) = \"" + m_defaultTextureValue + "\" {}"; + break; + } + return PropertyAttributes + propertyValue; + } + + public override string GetUniformValue() + { + return "uniform sampler2D " + PropertyName + ";"; + } + + public override bool GetUniformData( out string dataType, out string dataName, ref bool fullValue ) + { + dataType = "sampler2D"; + dataName = PropertyName; + return true; + } + + public override void ReadFromString( ref string[] nodeParams ) + { + base.ReadFromString( ref nodeParams ); + string defaultTextureGUID = GetCurrentParam( ref nodeParams ); + //m_defaultValue = AssetDatabase.LoadAssetAtPath<Texture>( textureName ); + if( UIUtils.CurrentShaderVersion() > 14101 ) + { + m_defaultValue = AssetDatabase.LoadAssetAtPath<Texture>( AssetDatabase.GUIDToAssetPath( defaultTextureGUID ) ); + string materialTextureGUID = GetCurrentParam( ref nodeParams ); + m_materialValue = AssetDatabase.LoadAssetAtPath<Texture>( AssetDatabase.GUIDToAssetPath( materialTextureGUID ) ); + } + else + { + m_defaultValue = AssetDatabase.LoadAssetAtPath<Texture>( defaultTextureGUID ); + } + m_isNormalMap = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); + m_defaultTextureValue = ( TexturePropertyValues ) Enum.Parse( typeof( TexturePropertyValues ), GetCurrentParam( ref nodeParams ) ); + m_autocastMode = ( AutoCastType ) Enum.Parse( typeof( AutoCastType ), GetCurrentParam( ref nodeParams ) ); + m_virtualPreset = ( VirtualPreset ) Enum.Parse( typeof( VirtualPreset ), GetCurrentParam( ref nodeParams ) ); + m_selectedChannelInt = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); + ChangeChannels(); + m_virtualChannel = GetChannel( m_selectedChannelInt ); + + //m_forceNodeUpdate = true; + + //ConfigFromObject( m_defaultValue ); + if( m_materialValue == null ) + { + ConfigFromObject( m_defaultValue ); + } + else + { + CheckTextureImporter( true, true ); + } + ConfigureInputPorts(); + ConfigureOutputPorts(); + } + + public override void ReadAdditionalData( ref string[] nodeParams ) { } + + public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) + { + base.WriteToString( ref nodeInfo, ref connectionsInfo ); + //IOUtils.AddFieldValueToString( ref nodeInfo, ( m_defaultValue != null ) ? AssetDatabase.GetAssetPath( m_defaultValue ) : Constants.NoStringValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_defaultValue != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_defaultValue ) ) : Constants.NoStringValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, ( m_materialValue != null ) ? AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( m_materialValue ) ) : Constants.NoStringValue ); + + IOUtils.AddFieldValueToString( ref nodeInfo, m_isNormalMap.ToString() ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_defaultTextureValue ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_autocastMode ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_virtualPreset ); + IOUtils.AddFieldValueToString( ref nodeInfo, m_selectedChannelInt ); + } + + public override void WriteAdditionalToString( ref string nodeInfo, ref string connectionsInfo ) { } + + //public override string PropertyName + //{ + // get + // { + // string propertyName = string.Empty; + // switch ( m_virtualChannel ) + // { + // default: + // case VirtualChannel.Albedo: + // case VirtualChannel.Base: + // propertyName = "_MainTex"; + // break; + // case VirtualChannel.Normal: + // propertyName = "_BumpMap"; + // break; + // case VirtualChannel.SpecMet: + // propertyName = "_MetallicGlossMap"; + // break; + // case VirtualChannel.Occlusion: + // propertyName = "_OcclusionMap"; + // break; + // } + // return propertyName; + // } + //} + + public override void Destroy() + { + base.Destroy(); + UIUtils.RemoveVirtualTextureCount(); + } + + public override bool IsNormalMap { get { return m_isNormalMap || m_virtualChannel == VirtualChannel.Normal; } } + public VirtualChannel Channel { get { return m_virtualChannel; } } + } +} diff --git a/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/VirtualTextureObject.cs.meta b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/VirtualTextureObject.cs.meta new file mode 100644 index 00000000..f2719119 --- /dev/null +++ b/Assets/ThirdParty/AmplifyShaderEditor/Plugins/Editor/Nodes/Textures/VirtualTextureObject.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: bacb12043c5bc504aa49e0a5a9bbc534 +timeCreated: 1481126958 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |