A game about forced loneliness, made by TACStudios
at master 7.5 kB view raw
1using System.Linq; 2using UnityEngine; 3using UnityEditor.Graphing; 4using UnityEditor.ShaderGraph.Drawing.Controls; 5using UnityEditor.ShaderGraph.Internal; 6 7namespace UnityEditor.ShaderGraph 8{ 9 enum TextureType 10 { 11 Default, 12 Normal 13 }; 14 15 [FormerName("UnityEditor.ShaderGraph.Texture2DNode")] 16 [Title("Input", "Texture", "Sample Texture 2D")] 17 class SampleTexture2DNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV 18 { 19 public const int OutputSlotRGBAId = 0; 20 public const int OutputSlotRId = 4; 21 public const int OutputSlotGId = 5; 22 public const int OutputSlotBId = 6; 23 public const int OutputSlotAId = 7; 24 public const int TextureInputId = 1; 25 public const int UVInput = 2; 26 public const int SamplerInput = 3; 27 public const int MipBiasInput = 8; 28 public const int LodInput = 9; 29 public const int DdxInput = 10; 30 public const int DdyInput = 11; 31 32 const string kTextureInputName = "Texture"; 33 const string kUVInputName = "UV"; 34 const string kSamplerInputName = "Sampler"; 35 36 RGBANodeOutput m_RGBAPins = RGBANodeOutput.NewDefault(); 37 Mip2DSamplingInputs m_Mip2DSamplingInputs = Mip2DSamplingInputs.NewDefault(); 38 39 public override bool hasPreview { get { return true; } } 40 41 public SampleTexture2DNode() 42 { 43 name = "Sample Texture 2D"; 44 synonyms = new string[] { "tex2d" }; 45 UpdateNodeAfterDeserialization(); 46 } 47 48 [SerializeField] 49 private TextureType m_TextureType = TextureType.Default; 50 51 [EnumControl("Type")] 52 public TextureType textureType 53 { 54 get { return m_TextureType; } 55 set 56 { 57 if (m_TextureType == value) 58 return; 59 60 m_TextureType = value; 61 Dirty(ModificationScope.Graph); 62 63 ValidateNode(); 64 } 65 } 66 67 [SerializeField] 68 private NormalMapSpace m_NormalMapSpace = NormalMapSpace.Tangent; 69 70 [EnumControl("Space")] 71 public NormalMapSpace normalMapSpace 72 { 73 get { return m_NormalMapSpace; } 74 set 75 { 76 if (m_NormalMapSpace == value) 77 return; 78 79 m_NormalMapSpace = value; 80 Dirty(ModificationScope.Graph); 81 } 82 } 83 84 [SerializeField] 85 private bool m_EnableGlobalMipBias = true; 86 internal bool enableGlobalMipBias 87 { 88 set { m_EnableGlobalMipBias = value; } 89 get { return m_EnableGlobalMipBias; } 90 } 91 92 [SerializeField] 93 private Texture2DMipSamplingMode m_MipSamplingMode = Texture2DMipSamplingMode.Standard; 94 internal Texture2DMipSamplingMode mipSamplingMode 95 { 96 set { m_MipSamplingMode = value; UpdateMipSamplingModeInputs(); } 97 get { return m_MipSamplingMode; } 98 } 99 100 private void UpdateMipSamplingModeInputs() 101 { 102 var capabilities = ShaderStageCapability.Fragment; 103 if (m_MipSamplingMode == Texture2DMipSamplingMode.LOD || m_MipSamplingMode == Texture2DMipSamplingMode.Gradient) 104 capabilities |= ShaderStageCapability.Vertex; 105 106 m_RGBAPins.SetCapabilities(capabilities); 107 108 m_Mip2DSamplingInputs = MipSamplingModesUtils.CreateMip2DSamplingInputs( 109 this, m_MipSamplingMode, m_Mip2DSamplingInputs, MipBiasInput, LodInput, DdxInput, DdyInput); 110 111 } 112 113 public sealed override void UpdateNodeAfterDeserialization() 114 { 115 m_RGBAPins.CreateNodes(this, ShaderStageCapability.None, OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId); 116 AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName)); 117 AddSlot(new UVMaterialSlot(UVInput, kUVInputName, kUVInputName, UVChannel.UV0)); 118 AddSlot(new SamplerStateMaterialSlot(SamplerInput, kSamplerInputName, kSamplerInputName, SlotType.Input)); 119 UpdateMipSamplingModeInputs(); 120 RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, UVInput, SamplerInput, MipBiasInput, LodInput, DdxInput, DdyInput }); 121 } 122 123 public override void Setup() 124 { 125 base.Setup(); 126 var textureSlot = FindInputSlot<Texture2DInputMaterialSlot>(TextureInputId); 127 textureSlot.defaultType = (textureType == TextureType.Normal ? Texture2DShaderProperty.DefaultType.NormalMap : Texture2DShaderProperty.DefaultType.White); 128 } 129 130 // Node generations 131 public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) 132 { 133 var uvName = GetSlotValue(UVInput, generationMode); 134 135 //Sampler input slot 136 var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInput); 137 var edgesSampler = owner.GetEdges(samplerSlot.slotReference); 138 139 var id = GetSlotValue(TextureInputId, generationMode); 140 var result = string.Format("$precision4 {0} = {1}({2}.tex, {3}.samplerstate, {2}.GetTransformedUV({4}) {5});" 141 , GetVariableNameForSlot(OutputSlotRGBAId) 142 , MipSamplingModesUtils.Get2DTextureSamplingMacro(m_MipSamplingMode, usePlatformMacros: !m_EnableGlobalMipBias, isArray: false) 143 , id 144 , edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id 145 , uvName 146 , MipSamplingModesUtils.GetSamplerMipArgs(this, m_MipSamplingMode, m_Mip2DSamplingInputs, generationMode)); 147 148 sb.AppendLine(result); 149 150 if (textureType == TextureType.Normal) 151 { 152 if (normalMapSpace == NormalMapSpace.Tangent) 153 { 154 sb.AppendLine(string.Format("{0}.rgb = UnpackNormal({0});", GetVariableNameForSlot(OutputSlotRGBAId))); 155 } 156 else 157 { 158 sb.AppendLine(string.Format("{0}.rgb = UnpackNormalRGB({0});", GetVariableNameForSlot(OutputSlotRGBAId))); 159 } 160 } 161 162 sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId))); 163 164 165 sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId))); 166 sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId))); 167 sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId))); 168 } 169 170 public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) 171 { 172 using (var tempSlots = PooledList<MaterialSlot>.Get()) 173 { 174 GetInputSlots(tempSlots); 175 var result = false; 176 foreach (var slot in tempSlots) 177 { 178 if (slot.RequiresMeshUV(channel)) 179 { 180 result = true; 181 break; 182 } 183 } 184 185 tempSlots.Clear(); 186 return result; 187 } 188 } 189 } 190}