A game about forced loneliness, made by TACStudios
1using System.Linq;
2using UnityEngine;
3using UnityEditor.Graphing;
4using UnityEditor.ShaderGraph.Drawing.Controls;
5using UnityEditor.ShaderGraph.Internal;
6
7namespace UnityEditor.ShaderGraph
8{
9 [Title("Input", "Texture", "Sample Texture 2D Array")]
10 class SampleTexture2DArrayNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
11 {
12 public const int OutputSlotRGBAId = 0;
13 public const int OutputSlotRId = 4;
14 public const int OutputSlotGId = 5;
15 public const int OutputSlotBId = 6;
16 public const int OutputSlotAId = 7;
17 public const int TextureInputId = 1;
18 public const int UVInput = 2;
19 public const int SamplerInput = 3;
20 public const int IndexInputId = 8;
21 public const int MipBiasInput = 9;
22 public const int LodInput = 10;
23 public const int DdxInput = 11;
24 public const int DdyInput = 12;
25
26 const string kTextureInputName = "Texture Array";
27 const string kUVInputName = "UV";
28 const string kSamplerInputName = "Sampler";
29 const string kIndexInputName = "Index";
30
31 RGBANodeOutput m_RGBAPins = RGBANodeOutput.NewDefault();
32 Mip2DSamplingInputs m_Mip2DSamplingInputs = Mip2DSamplingInputs.NewDefault();
33
34 public override bool hasPreview { get { return true; } }
35
36 public SampleTexture2DArrayNode()
37 {
38 name = "Sample Texture 2D Array";
39 synonyms = new string[] { "stack", "pile", "tex2darray" };
40 UpdateNodeAfterDeserialization();
41 }
42
43 [SerializeField]
44 private bool m_EnableGlobalMipBias = false;
45 internal bool enableGlobalMipBias
46 {
47 set { m_EnableGlobalMipBias = value; }
48 get { return m_EnableGlobalMipBias; }
49 }
50
51 [SerializeField]
52 private Texture2DMipSamplingMode m_MipSamplingMode = Texture2DMipSamplingMode.Standard;
53 internal Texture2DMipSamplingMode mipSamplingMode
54 {
55 set { m_MipSamplingMode = value; UpdateMipSamplingModeInputs(); }
56 get { return m_MipSamplingMode; }
57 }
58
59 private void UpdateMipSamplingModeInputs()
60 {
61 var capabilities = ShaderStageCapability.Fragment;
62 if (m_MipSamplingMode == Texture2DMipSamplingMode.LOD || m_MipSamplingMode == Texture2DMipSamplingMode.Gradient)
63 capabilities |= ShaderStageCapability.Vertex;
64
65 m_RGBAPins.SetCapabilities(capabilities);
66
67 m_Mip2DSamplingInputs = MipSamplingModesUtils.CreateMip2DSamplingInputs(
68 this, m_MipSamplingMode, m_Mip2DSamplingInputs, MipBiasInput, LodInput, DdxInput, DdyInput);
69 }
70
71 public sealed override void UpdateNodeAfterDeserialization()
72 {
73 m_RGBAPins.CreateNodes(this, ShaderStageCapability.None, OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId);
74 AddSlot(new Texture2DArrayInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
75 AddSlot(new Vector1MaterialSlot(IndexInputId, kIndexInputName, kIndexInputName, SlotType.Input, 0));
76 AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.UV0));
77 AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input));
78 UpdateMipSamplingModeInputs();
79 RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, IndexInputId, UVInput, SamplerInput, MipBiasInput, LodInput, DdxInput, DdyInput });
80 }
81
82 // Node generations
83 public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
84 {
85 var uvName = GetSlotValue(UVInput, generationMode);
86 var indexName = GetSlotValue(IndexInputId, generationMode);
87
88 //Sampler input slot
89 var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput);
90 var edgesSampler = owner.GetEdges(samplerSlot.slotReference);
91
92 var id = GetSlotValue(TextureInputId, generationMode);
93 var result = string.Format("$precision4 {0} = {1}({2}.tex, {3}.samplerstate, {4}, {5} {6});"
94 , GetVariableNameForSlot(OutputSlotRGBAId)
95 , MipSamplingModesUtils.Get2DTextureSamplingMacro(m_MipSamplingMode, usePlatformMacros: !m_EnableGlobalMipBias, isArray: true)
96 , id
97 , edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id
98 , uvName
99 , indexName
100 , MipSamplingModesUtils.GetSamplerMipArgs(this, m_MipSamplingMode, m_Mip2DSamplingInputs, generationMode));
101
102 sb.AppendLine(result);
103
104 sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId)));
105 sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId)));
106 sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId)));
107 sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId)));
108 }
109
110 public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
111 {
112 using (var tempSlots = PooledList<MaterialSlot>.Get())
113 {
114 GetInputSlots(tempSlots);
115 var result = false;
116 foreach (var slot in tempSlots)
117 {
118 if (slot.RequiresMeshUV(channel))
119 {
120 result = true;
121 break;
122 }
123 }
124
125 tempSlots.Clear();
126 return result;
127 }
128 }
129 }
130}