MaterialQualityNode.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Amplify Shader Editor - Visual Shader vEditing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System;
  6. namespace AmplifyShaderEditor
  7. {
  8. [NodeAttributes( "Material Quality", "Logical Operators", "Choose between separate branches according to currently selected Quality (SRP only) ", Available = true )]
  9. public class MaterialQualityNode : ParentNode
  10. {
  11. private const string SRPError = "Node intended to be used only on SRP templates as it makes use of keywords defined over that environment.";
  12. private const string MaxKeyword = "MATERIAL_QUALITY_HIGH";
  13. private const string MedKeyword = "MATERIAL_QUALITY_MEDIUM";
  14. private const string MinKeyword = "MATERIAL_QUALITY_LOW";
  15. private const string MaterialPragmas = "#pragma shader_feature " + MaxKeyword + " " + MedKeyword + " " + MinKeyword;
  16. private readonly string[] MaterialCode =
  17. {
  18. "#if defined("+MaxKeyword+")",
  19. "#elif defined("+MedKeyword+")",
  20. "#else",
  21. "#endif"
  22. };
  23. protected override void CommonInit( int uniqueId )
  24. {
  25. base.CommonInit( uniqueId );
  26. AddInputPort( WirePortDataType.FLOAT, false, "High" );
  27. AddInputPort( WirePortDataType.FLOAT, false, "Medium" );
  28. AddInputPort( WirePortDataType.FLOAT, false, "Low" );
  29. AddOutputPort( WirePortDataType.FLOAT, Constants.EmptyPortValue );
  30. m_errorMessageTypeIsError = NodeMessageType.Error;
  31. m_errorMessageTooltip = SRPError;
  32. }
  33. public override void OnNodeLogicUpdate( DrawInfo drawInfo )
  34. {
  35. base.OnNodeLogicUpdate( drawInfo );
  36. if( !ContainerGraph.IsSRP )
  37. {
  38. if( !m_showErrorMessage )
  39. {
  40. m_showErrorMessage = true;
  41. }
  42. }
  43. else
  44. {
  45. if( m_showErrorMessage )
  46. {
  47. m_showErrorMessage = false;
  48. }
  49. }
  50. }
  51. public override void OnInputPortConnected( int portId , int otherNodeId , int otherPortId , bool activateNode = true )
  52. {
  53. base.OnInputPortConnected( portId , otherNodeId , otherPortId , activateNode );
  54. UpdateConnections();
  55. }
  56. public override void OnConnectedOutputNodeChanges( int inputPortId , int otherNodeId , int otherPortId , string name , WirePortDataType type )
  57. {
  58. base.OnConnectedOutputNodeChanges( inputPortId , otherNodeId , otherPortId , name , type );
  59. UpdateConnections();
  60. }
  61. public override void OnInputPortDisconnected( int portId )
  62. {
  63. base.OnInputPortDisconnected( portId );
  64. UpdateConnections();
  65. }
  66. private void UpdateConnections()
  67. {
  68. WirePortDataType mainType = WirePortDataType.FLOAT;
  69. int highest = UIUtils.GetPriority( mainType );
  70. for( int i = 0 ; i < m_inputPorts.Count ; i++ )
  71. {
  72. if( m_inputPorts[ i ].IsConnected )
  73. {
  74. WirePortDataType portType = m_inputPorts[ i ].GetOutputConnection().DataType;
  75. if( UIUtils.GetPriority( portType ) > highest )
  76. {
  77. mainType = portType;
  78. highest = UIUtils.GetPriority( portType );
  79. }
  80. }
  81. }
  82. for( int i = 0 ; i < m_inputPorts.Count ; i++ )
  83. {
  84. m_inputPorts[ i ].ChangeType( mainType , false );
  85. }
  86. m_outputPorts[ 0 ].ChangeType( mainType , false );
  87. }
  88. public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar )
  89. {
  90. if( m_outputPorts[ 0 ].IsLocalValue( dataCollector.PortCategory ) )
  91. return m_outputPorts[ 0 ].LocalValue( dataCollector.PortCategory );
  92. dataCollector.AddToDirectives( MaterialPragmas );
  93. string maxQualityValue = m_inputPorts[ 0 ].GeneratePortInstructions( ref dataCollector );
  94. string medQualityValue = m_inputPorts[ 1 ].GeneratePortInstructions( ref dataCollector );
  95. string minQualityValue = m_inputPorts[ 2 ].GeneratePortInstructions( ref dataCollector );
  96. string localVarName = "currQuality" + OutputId;
  97. dataCollector.AddLocalVariable( UniqueId, CurrentPrecisionType, m_outputPorts[ 0 ].DataType, localVarName, "0" );
  98. //High
  99. dataCollector.AddLocalVariable( UniqueId, MaterialCode[ 0 ], true );
  100. dataCollector.AddLocalVariable( UniqueId, localVarName, maxQualityValue, false, true );
  101. //Medium
  102. dataCollector.AddLocalVariable( UniqueId, MaterialCode[ 1 ], true );
  103. dataCollector.AddLocalVariable( UniqueId, localVarName, medQualityValue, false, true );
  104. //Low
  105. dataCollector.AddLocalVariable( UniqueId, MaterialCode[ 2 ], true );
  106. dataCollector.AddLocalVariable( UniqueId, localVarName, minQualityValue,false,true );
  107. m_outputPorts[ 0 ].SetLocalValue( localVarName, dataCollector.PortCategory );
  108. dataCollector.AddLocalVariable( UniqueId, MaterialCode[ 3 ], true );
  109. return localVarName;
  110. }
  111. }
  112. }