You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
4.1 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. namespace AmplifyShaderEditor
  5. {
  6. [Serializable]
  7. [NodeAttributes( "Clip", "Miscellaneous", "Conditionally kill a pixel before output" )]
  8. public sealed class ClipNode : ParentNode
  9. {
  10. private const string ClipOpFormat = "clip( {0} );";
  11. private const string ClipSubOpFormat = "clip( {0} - {1});";
  12. protected override void CommonInit( int uniqueId )
  13. {
  14. base.CommonInit( uniqueId );
  15. AddInputPort( WirePortDataType.FLOAT, false, Constants.EmptyPortValue );
  16. AddInputPort( WirePortDataType.FLOAT, false, "Alpha" );
  17. AddInputPort( WirePortDataType.FLOAT, false, "Threshold" );
  18. AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
  19. m_useInternalPortData = true;
  20. m_inputPorts[ 0 ].CreatePortRestrictions( WirePortDataType.OBJECT,
  21. WirePortDataType.FLOAT ,
  22. WirePortDataType.FLOAT2,
  23. WirePortDataType.FLOAT3,
  24. WirePortDataType.FLOAT4,
  25. WirePortDataType.COLOR ,
  26. WirePortDataType.INT);
  27. }
  28. public override void OnInputPortConnected( int portId, int otherNodeId, int otherPortId, bool activateNode = true )
  29. {
  30. base.OnInputPortConnected( portId, otherNodeId, otherPortId, activateNode );
  31. m_inputPorts[ portId ].MatchPortToConnection();
  32. UpdatePortConnection( portId );
  33. }
  34. public override void OnConnectedOutputNodeChanges( int outputPortId, int otherNodeId, int otherPortId, string name, WirePortDataType type )
  35. {
  36. base.OnConnectedOutputNodeChanges( outputPortId, otherNodeId, otherPortId, name, type );
  37. m_inputPorts[ outputPortId ].MatchPortToConnection();
  38. UpdatePortConnection( outputPortId );
  39. }
  40. void UpdatePortConnection( int portId )
  41. {
  42. if( portId == 0 )
  43. {
  44. m_outputPorts[ 0 ].ChangeType( m_inputPorts[ 0 ].DataType, false );
  45. }
  46. else
  47. {
  48. int otherPortId = portId == 1 ? 2 : 1;
  49. if( m_inputPorts[ otherPortId ].IsConnected )
  50. {
  51. WirePortDataType type1 = m_inputPorts[ portId ].DataType;
  52. WirePortDataType type2 = m_inputPorts[ otherPortId ].DataType;
  53. WirePortDataType mainType = UIUtils.GetPriority( type1 ) > UIUtils.GetPriority( type2 ) ? type1 : type2;
  54. m_inputPorts[ portId ].ChangeType( mainType, false );
  55. m_inputPorts[ otherPortId ].ChangeType( mainType , false );
  56. }
  57. else
  58. {
  59. m_inputPorts[ otherPortId ].ChangeType( m_inputPorts[ portId ].DataType,false );
  60. }
  61. }
  62. }
  63. public override void OnInputPortDisconnected( int portId )
  64. {
  65. base.OnInputPortDisconnected( portId );
  66. if( portId == 0 )
  67. return;
  68. int otherPortId = portId == 1 ? 2 : 1;
  69. if( m_inputPorts[ otherPortId ].IsConnected )
  70. {
  71. m_inputPorts[ portId ].ChangeType( m_inputPorts[ otherPortId ].DataType, false );
  72. }
  73. else
  74. {
  75. m_inputPorts[ portId ].ChangeType( WirePortDataType.FLOAT, false );
  76. m_inputPorts[ otherPortId ].ChangeType( WirePortDataType.FLOAT, false );
  77. }
  78. }
  79. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  80. {
  81. if( dataCollector.PortCategory == MasterNodePortCategory.Vertex ||
  82. dataCollector.PortCategory == MasterNodePortCategory.Tessellation )
  83. {
  84. UIUtils.ShowMessage( "Clip can only be used in fragment functions", MessageSeverity.Warning );
  85. return GenerateErrorValue();
  86. }
  87. string value = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
  88. string alpha = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
  89. if( m_inputPorts[ 2 ].IsConnected )
  90. {
  91. string threshold = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector );
  92. dataCollector.AddLocalVariable( UniqueId, string.Format( ClipSubOpFormat, alpha , threshold) );
  93. }
  94. else
  95. {
  96. if( m_inputPorts[ 2 ].IsZeroInternalData )
  97. {
  98. dataCollector.AddLocalVariable( UniqueId, string.Format( ClipOpFormat, alpha ) );
  99. }
  100. else
  101. {
  102. string threshold = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector );
  103. dataCollector.AddLocalVariable( UniqueId, string.Format( ClipSubOpFormat, alpha, threshold ) );
  104. }
  105. }
  106. return value;
  107. }
  108. }
  109. }