FlipNode.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System;
  6. namespace AmplifyShaderEditor
  7. {
  8. [Serializable]
  9. [NodeAttributes( "Flip", "Vector Operators", "Flip value sign on specific channels from vectors or color components.", tags: "invert sign" )]
  10. public sealed class FlipNode : ParentNode
  11. {
  12. [SerializeField]
  13. private bool[] m_selection = { true, true, true, true };
  14. [SerializeField]
  15. private string[] m_labels;
  16. private static readonly int _Flip = Shader.PropertyToID( "_Flip" );
  17. private static readonly int _Count = Shader.PropertyToID( "_Count" );
  18. protected override void CommonInit( int uniqueId )
  19. {
  20. base.CommonInit( uniqueId );
  21. AddInputPort( WirePortDataType.FLOAT4, false, Constants.EmptyPortValue );
  22. AddOutputPort( WirePortDataType.FLOAT4, Constants.EmptyPortValue );
  23. m_inputPorts[ 0 ].CreatePortRestrictions( WirePortDataType.FLOAT,
  24. WirePortDataType.FLOAT2,
  25. WirePortDataType.FLOAT3,
  26. WirePortDataType.FLOAT4,
  27. WirePortDataType.COLOR,
  28. WirePortDataType.INT );
  29. m_useInternalPortData = true;
  30. m_autoWrapProperties = true;
  31. m_selectedLocation = PreviewLocation.TopCenter;
  32. m_labels = new string[] { "X", "Y", "Z", "W" };
  33. m_previewShaderGUID = "99b235eb03070cd4ab7470cda5a77e2d";
  34. SetAdditonalTitleText( "Value( XYZW )" );
  35. }
  36. public override void SetPreviewInputs()
  37. {
  38. base.SetPreviewInputs();
  39. var dataType = m_inputPorts[ 0 ].DataType;
  40. var flip = new Vector4( 0, 0, 0, 0 );
  41. int count = 1;
  42. flip.x = m_selection[ 0 ] ? 1 : 0;
  43. if ( dataType >= WirePortDataType.FLOAT2 )
  44. {
  45. flip.y = m_selection[ 1 ] ? 1 : 0;
  46. count++;
  47. }
  48. if ( dataType >= WirePortDataType.FLOAT3 )
  49. {
  50. flip.z = m_selection[ 2 ] ? 1 : 0;
  51. count++;
  52. }
  53. if ( dataType == WirePortDataType.FLOAT4 || dataType == WirePortDataType.COLOR )
  54. {
  55. flip.w = m_selection[ 3 ] ? 1 : 0;
  56. count++;
  57. }
  58. PreviewMaterial.SetVector( _Flip, flip );
  59. PreviewMaterial.SetInt( _Count, count );
  60. }
  61. public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
  62. {
  63. base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode );
  64. m_inputPorts[ 0 ].MatchPortToConnection();
  65. m_outputPorts[ 0 ].ChangeType( InputPorts[ 0 ].DataType, false );
  66. UpdateTitle();
  67. }
  68. public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
  69. {
  70. base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type );
  71. m_inputPorts[ 0 ].MatchPortToConnection();
  72. m_outputPorts[ 0 ].ChangeType( InputPorts[ 0 ].DataType, false );
  73. UpdateTitle();
  74. }
  75. public override void OnInputPortDisconnected( int portId )
  76. {
  77. base.OnInputPortDisconnected( portId );
  78. UpdateTitle();
  79. }
  80. private void UpdateTitle()
  81. {
  82. var dataType = m_inputPorts[ 0 ].DataType;
  83. var additionalText = ( m_selection[ 0 ] ? "1" : "0" );
  84. if ( dataType >= WirePortDataType.FLOAT2 )
  85. {
  86. additionalText += ", " + ( m_selection[ 1 ] ? "1" : "0" );
  87. }
  88. if ( dataType >= WirePortDataType.FLOAT3 )
  89. {
  90. additionalText += ", " + ( m_selection[ 2 ] ? "1" : "0" );
  91. }
  92. if ( ( dataType == WirePortDataType.FLOAT4 || dataType == WirePortDataType.COLOR ) )
  93. {
  94. additionalText += ", " + ( m_selection[ 3 ] ? "1" : "0" );
  95. }
  96. SetAdditonalTitleText( ( additionalText.Length > 0 ) ? "Value( " + additionalText + " )" : string.Empty );
  97. }
  98. public override void DrawProperties()
  99. {
  100. base.DrawProperties();
  101. EditorGUILayout.BeginVertical();
  102. int count = 0;
  103. switch ( m_inputPorts[ 0 ].DataType )
  104. {
  105. case WirePortDataType.FLOAT4:
  106. case WirePortDataType.OBJECT:
  107. case WirePortDataType.COLOR: count = 4; break;
  108. case WirePortDataType.FLOAT3: count = 3; break;
  109. case WirePortDataType.FLOAT2: count = 2; break;
  110. case WirePortDataType.FLOAT:
  111. case WirePortDataType.INT: count = 1; break;
  112. case WirePortDataType.FLOAT3x3:
  113. case WirePortDataType.FLOAT4x4: break;
  114. }
  115. if ( count > 0 )
  116. {
  117. for ( int i = 0; i < count; i++ )
  118. {
  119. m_selection[ i ] = EditorGUILayoutToggleLeft( m_labels[ i ], m_selection[ i ] );
  120. m_labels[ i ] = UIUtils.GetComponentForPosition( i, m_inputPorts[ 0 ].DataType ).ToUpper();
  121. }
  122. }
  123. EditorGUILayout.EndVertical();
  124. }
  125. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar )
  126. {
  127. if ( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
  128. {
  129. return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
  130. }
  131. string inputValue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
  132. string outputType = UIUtils.PrecisionWirePortToCgType( CurrentPrecisionType, m_outputPorts[ 0 ].DataType );
  133. var dataType = m_inputPorts[ 0 ].DataType;
  134. string flip = outputType + "( " + ( m_selection[ 0 ] ? "1" : "0" );
  135. if ( dataType >= WirePortDataType.FLOAT2 )
  136. {
  137. flip += ", " + ( m_selection[ 1 ] ? "1" : "0" );
  138. }
  139. if ( dataType >= WirePortDataType.FLOAT3 )
  140. {
  141. flip += ", " + ( m_selection[ 2 ] ? "1" : "0" );
  142. }
  143. if ( ( dataType == WirePortDataType.FLOAT4 || dataType == WirePortDataType.COLOR ) )
  144. {
  145. flip += ", " + ( m_selection[ 3 ] ? "1" : "0" );
  146. }
  147. flip += " )";
  148. string result = string.Format( "( ( {0} * -2 + 1 ) * {1} )", flip, inputValue );
  149. return CreateOutputLocalVariable( 0, result, ref dataCollector );
  150. }
  151. public string GetComponentForPosition( int i )
  152. {
  153. switch ( i )
  154. {
  155. case 0: return ( ( m_outputPorts[ 0 ].DataType == WirePortDataType.COLOR ) ? "r" : "x" );
  156. case 1: return ( ( m_outputPorts[ 0 ].DataType == WirePortDataType.COLOR ) ? "g" : "y" );
  157. case 2: return ( ( m_outputPorts[ 0 ].DataType == WirePortDataType.COLOR ) ? "b" : "z" );
  158. case 3: return ( ( m_outputPorts[ 0 ].DataType == WirePortDataType.COLOR ) ? "a" : "w" );
  159. }
  160. return string.Empty;
  161. }
  162. public override void ReadFromString( ref string[] nodeParams )
  163. {
  164. base.ReadFromString( ref nodeParams );
  165. for ( int i = 0; i < 4; i++ )
  166. {
  167. m_selection[ i ] = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) );
  168. }
  169. UpdateTitle();
  170. }
  171. public override void WriteToString( ref string nodeInfo, ref string connectionsInfo )
  172. {
  173. base.WriteToString( ref nodeInfo, ref connectionsInfo );
  174. for ( int i = 0; i < 4; i++ )
  175. {
  176. IOUtils.AddFieldValueToString( ref nodeInfo, m_selection[ i ] );
  177. }
  178. }
  179. }
  180. }