ChannelMixerNode.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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("Artistic", "Adjustment", "Channel Mixer")]
  10. class ChannelMixerNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
  11. {
  12. public ChannelMixerNode()
  13. {
  14. name = "Channel Mixer";
  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_ChannelMixer_{concretePrecision.ToShaderString()}";
  28. }
  29. public sealed override void UpdateNodeAfterDeserialization()
  30. {
  31. AddSlot(new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero));
  32. AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
  33. RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
  34. }
  35. [SerializeField]
  36. ChannelMixer m_ChannelMixer = new ChannelMixer(new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1));
  37. [Serializable]
  38. public struct ChannelMixer
  39. {
  40. public Vector3 outRed;
  41. public Vector3 outGreen;
  42. public Vector3 outBlue;
  43. public ChannelMixer(Vector3 red, Vector3 green, Vector3 blue)
  44. {
  45. outRed = red;
  46. outGreen = green;
  47. outBlue = blue;
  48. }
  49. }
  50. [ChannelMixerControl("")]
  51. public ChannelMixer channelMixer
  52. {
  53. get { return m_ChannelMixer; }
  54. set
  55. {
  56. if ((value.outRed == m_ChannelMixer.outRed) && (value.outGreen == m_ChannelMixer.outGreen) && (value.outBlue == m_ChannelMixer.outBlue))
  57. return;
  58. m_ChannelMixer = value;
  59. Dirty(ModificationScope.Node);
  60. }
  61. }
  62. public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
  63. {
  64. var inputValue = GetSlotValue(InputSlotId, generationMode);
  65. var outputValue = GetSlotValue(OutputSlotId, generationMode);
  66. sb.AppendLine("{0} {1};", FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToShaderString(), GetVariableNameForSlot(OutputSlotId));
  67. if (!generationMode.IsPreview())
  68. {
  69. sb.AppendLine("$precision3 _{0}_Red = $precision3 ({1}, {2}, {3});", GetVariableNameForNode(), channelMixer.outRed[0], channelMixer.outRed[1], channelMixer.outRed[2]);
  70. sb.AppendLine("$precision3 _{0}_Green = $precision3 ({1}, {2}, {3});", GetVariableNameForNode(), channelMixer.outGreen[0], channelMixer.outGreen[1], channelMixer.outGreen[2]);
  71. sb.AppendLine("$precision3 _{0}_Blue = $precision3 ({1}, {2}, {3});", GetVariableNameForNode(), channelMixer.outBlue[0], channelMixer.outBlue[1], channelMixer.outBlue[2]);
  72. }
  73. sb.AppendLine("{0}({1}, _{2}_Red, _{2}_Green, _{2}_Blue, {3});", GetFunctionName(), inputValue, GetVariableNameForNode(), outputValue);
  74. }
  75. public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
  76. {
  77. base.CollectPreviewMaterialProperties(properties);
  78. properties.Add(new PreviewProperty(PropertyType.Vector3)
  79. {
  80. name = string.Format("_{0}_Red", GetVariableNameForNode()),
  81. vector4Value = channelMixer.outRed
  82. });
  83. properties.Add(new PreviewProperty(PropertyType.Vector3)
  84. {
  85. name = string.Format("_{0}_Green", GetVariableNameForNode()),
  86. vector4Value = channelMixer.outGreen
  87. });
  88. properties.Add(new PreviewProperty(PropertyType.Vector3)
  89. {
  90. name = string.Format("_{0}_Blue", GetVariableNameForNode()),
  91. vector4Value = channelMixer.outBlue
  92. });
  93. }
  94. public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
  95. {
  96. if (!generationMode.IsPreview())
  97. return;
  98. base.CollectShaderProperties(properties, generationMode);
  99. properties.AddShaderProperty(new Vector4ShaderProperty()
  100. {
  101. overrideReferenceName = string.Format("_{0}_Red", GetVariableNameForNode()),
  102. generatePropertyBlock = false
  103. });
  104. properties.AddShaderProperty(new Vector4ShaderProperty()
  105. {
  106. overrideReferenceName = string.Format("_{0}_Green", GetVariableNameForNode()),
  107. generatePropertyBlock = false
  108. });
  109. properties.AddShaderProperty(new Vector4ShaderProperty()
  110. {
  111. overrideReferenceName = string.Format("_{0}_Blue", GetVariableNameForNode()),
  112. generatePropertyBlock = false
  113. });
  114. }
  115. public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
  116. {
  117. registry.ProvideFunction(GetFunctionName(), s =>
  118. {
  119. s.AppendLine("void {0} ({1} In, $precision3 Red, $precision3 Green, $precision3 Blue, out {2} Out)",
  120. GetFunctionName(),
  121. FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToShaderString(),
  122. FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString());
  123. using (s.BlockScope())
  124. {
  125. s.AppendLine("Out = {0}(dot(In, Red), dot(In, Green), dot(In, Blue));",
  126. FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString());
  127. }
  128. });
  129. }
  130. }
  131. }