SampleTexture2DArrayNode.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using System.Linq;
  2. using UnityEngine;
  3. using UnityEditor.Graphing;
  4. using UnityEditor.ShaderGraph.Drawing.Controls;
  5. using UnityEditor.ShaderGraph.Internal;
  6. namespace UnityEditor.ShaderGraph
  7. {
  8. [Title("Input", "Texture", "Sample Texture 2D Array")]
  9. class SampleTexture2DArrayNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
  10. {
  11. public const int OutputSlotRGBAId = 0;
  12. public const int OutputSlotRId = 4;
  13. public const int OutputSlotGId = 5;
  14. public const int OutputSlotBId = 6;
  15. public const int OutputSlotAId = 7;
  16. public const int TextureInputId = 1;
  17. public const int UVInput = 2;
  18. public const int SamplerInput = 3;
  19. public const int IndexInputId = 8;
  20. const string kOutputSlotRGBAName = "RGBA";
  21. const string kOutputSlotRName = "R";
  22. const string kOutputSlotGName = "G";
  23. const string kOutputSlotBName = "B";
  24. const string kOutputSlotAName = "A";
  25. const string kTextureInputName = "Texture Array";
  26. const string kUVInputName = "UV";
  27. const string kSamplerInputName = "Sampler";
  28. const string kIndexInputName = "Index";
  29. public override bool hasPreview { get { return true; } }
  30. public SampleTexture2DArrayNode()
  31. {
  32. name = "Sample Texture 2D Array";
  33. UpdateNodeAfterDeserialization();
  34. }
  35. public sealed override void UpdateNodeAfterDeserialization()
  36. {
  37. AddSlot(new Vector4MaterialSlot(OutputSlotRGBAId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, Vector4.zero, ShaderStageCapability.Fragment));
  38. AddSlot(new Vector1MaterialSlot(OutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, 0, ShaderStageCapability.Fragment));
  39. AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0, ShaderStageCapability.Fragment));
  40. AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0, ShaderStageCapability.Fragment));
  41. AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0, ShaderStageCapability.Fragment));
  42. AddSlot(new Texture2DArrayInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
  43. AddSlot(new Vector1MaterialSlot(IndexInputId, kIndexInputName, kIndexInputName, SlotType.Input, 0));
  44. AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.UV0));
  45. AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
  46. RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, IndexInputId, UVInput, SamplerInput });
  47. }
  48. // Node generations
  49. public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
  50. {
  51. var uvName = GetSlotValue(UVInput, generationMode);
  52. var indexName = GetSlotValue(IndexInputId, generationMode);
  53. //Sampler input slot
  54. var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);
  55. var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
  56. var id = GetSlotValue(TextureInputId, generationMode);
  57. var result = string.Format("$precision4 {0} = SAMPLE_TEXTURE2D_ARRAY({1}, {2}, {3}, {4});"
  58. , GetVariableNameForSlot(OutputSlotRGBAId)
  59. , id
  60. , edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : "sampler" + id
  61. , uvName
  62. , indexName);
  63. sb.AppendLine(result);
  64. sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId)));
  65. sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId)));
  66. sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId)));
  67. sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId)));
  68. }
  69. public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
  70. {
  71. using (var tempSlots = PooledList<MaterialSlot>.Get())
  72. {
  73. GetInputSlots(tempSlots);
  74. var result = false;
  75. foreach (var slot in tempSlots)
  76. {
  77. if (slot.RequiresMeshUV(channel))
  78. {
  79. result = true;
  80. break;
  81. }
  82. }
  83. tempSlots.Clear();
  84. return result;
  85. }
  86. }
  87. }
  88. }