FlipNode.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEditor.Graphing;
  4. using UnityEditor.ShaderGraph.Drawing.Controls;
  5. using UnityEditor.ShaderGraph.Internal;
  6. using UnityEngine;
  7. namespace UnityEditor.ShaderGraph
  8. {
  9. [Title("Channel", "Flip")]
  10. class FlipNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
  11. {
  12. public FlipNode()
  13. {
  14. name = "Flip";
  15. UpdateNodeAfterDeserialization();
  16. }
  17. const int InputSlotId = 0;
  18. const int OutputSlotId = 1;
  19. const string kInputSlotName = "In";
  20. const string kOutputSlotName = "Out";
  21. public override bool hasPreview
  22. {
  23. get { return true; }
  24. }
  25. string GetFunctionName()
  26. {
  27. return $"Unity_Flip_{FindSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString(concretePrecision)}";
  28. }
  29. public sealed override void UpdateNodeAfterDeserialization()
  30. {
  31. AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero));
  32. AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
  33. RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
  34. }
  35. int channelCount { get { return SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType); } }
  36. [SerializeField]
  37. private bool m_RedChannel;
  38. [ToggleControl("Red")]
  39. public ToggleData redChannel
  40. {
  41. get { return new ToggleData(m_RedChannel, channelCount > 0); }
  42. set
  43. {
  44. if (m_RedChannel == value.isOn)
  45. return;
  46. m_RedChannel = value.isOn;
  47. Dirty(ModificationScope.Node);
  48. }
  49. }
  50. [SerializeField]
  51. private bool m_GreenChannel;
  52. [ToggleControl("Green")]
  53. public ToggleData greenChannel
  54. {
  55. get { return new ToggleData(m_GreenChannel, channelCount > 1); }
  56. set
  57. {
  58. if (m_GreenChannel == value.isOn)
  59. return;
  60. m_GreenChannel = value.isOn;
  61. Dirty(ModificationScope.Node);
  62. }
  63. }
  64. [SerializeField]
  65. private bool m_BlueChannel;
  66. [ToggleControl("Blue")]
  67. public ToggleData blueChannel
  68. {
  69. get { return new ToggleData(m_BlueChannel, channelCount > 2); }
  70. set
  71. {
  72. if (m_BlueChannel == value.isOn)
  73. return;
  74. m_BlueChannel = value.isOn;
  75. Dirty(ModificationScope.Node);
  76. }
  77. }
  78. [SerializeField]
  79. private bool m_AlphaChannel;
  80. [ToggleControl("Alpha")]
  81. public ToggleData alphaChannel
  82. {
  83. get { return new ToggleData(m_AlphaChannel, channelCount > 3); }
  84. set
  85. {
  86. if (m_AlphaChannel == value.isOn)
  87. return;
  88. m_AlphaChannel = value.isOn;
  89. Dirty(ModificationScope.Node);
  90. }
  91. }
  92. public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
  93. {
  94. var inputValue = GetSlotValue(InputSlotId, generationMode);
  95. var outputValue = GetSlotValue(OutputSlotId, generationMode);
  96. sb.AppendLine("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString(), GetVariableNameForSlot(OutputSlotId));
  97. if (!generationMode.IsPreview())
  98. {
  99. sb.AppendLine("{0} _{1}_Flip = {0} ({2}",
  100. FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString(),
  101. GetVariableNameForNode(),
  102. Convert.ToInt32(m_RedChannel));
  103. if (channelCount > 1)
  104. sb.Append(", {0}", Convert.ToInt32(m_GreenChannel));
  105. if (channelCount > 2)
  106. sb.Append(", {0}", Convert.ToInt32(m_BlueChannel));
  107. if (channelCount > 3)
  108. sb.Append(", {0}", Convert.ToInt32(m_AlphaChannel));
  109. sb.Append(");");
  110. }
  111. sb.AppendLine("{0}({1}, _{2}_Flip, {3});", GetFunctionName(), inputValue, GetVariableNameForNode(), outputValue);
  112. }
  113. public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
  114. {
  115. base.CollectPreviewMaterialProperties(properties);
  116. properties.Add(new PreviewProperty(PropertyType.Vector4)
  117. {
  118. name = string.Format("_{0}_Flip", GetVariableNameForNode()),
  119. vector4Value = new Vector4(Convert.ToInt32(m_RedChannel), Convert.ToInt32(m_GreenChannel), Convert.ToInt32(m_BlueChannel), Convert.ToInt32(m_AlphaChannel)),
  120. });
  121. }
  122. public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
  123. {
  124. if (!generationMode.IsPreview())
  125. return;
  126. base.CollectShaderProperties(properties, generationMode);
  127. properties.AddShaderProperty(new Vector4ShaderProperty
  128. {
  129. overrideReferenceName = string.Format("_{0}_Flip", GetVariableNameForNode()),
  130. generatePropertyBlock = false
  131. });
  132. }
  133. public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
  134. {
  135. registry.ProvideFunction(GetFunctionName(), s =>
  136. {
  137. s.AppendLine("void {0}({1} In, {2} Flip, out {3} Out)",
  138. GetFunctionName(),
  139. FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToShaderString(),
  140. FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToShaderString(),
  141. FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString());
  142. using (s.BlockScope())
  143. {
  144. s.AppendLine("Out = (Flip * -2 + 1) * In;");
  145. }
  146. });
  147. }
  148. }
  149. }