A game about forced loneliness, made by TACStudios
at master 155 lines 6.7 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 [Title("Input", "Texture", "Sample Texture 2D LOD")] 10 class SampleTexture2DLODNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV 11 { 12 public const int OutputSlotRGBAId = 0; 13 public const int OutputSlotRId = 5; 14 public const int OutputSlotGId = 6; 15 public const int OutputSlotBId = 7; 16 public const int OutputSlotAId = 8; 17 18 public const int TextureInputId = 1; 19 public const int UVInputId = 2; 20 public const int SamplerInputId = 3; 21 public const int LODInputId = 4; 22 23 const string kOutputSlotRGBAName = "RGBA"; 24 const string kOutputSlotRName = "R"; 25 const string kOutputSlotGName = "G"; 26 const string kOutputSlotBName = "B"; 27 const string kOutputSlotAName = "A"; 28 29 const string kTextureInputName = "Texture"; 30 const string kUVInputName = "UV"; 31 const string kSamplerInputName = "Sampler"; 32 const string kLODInputName = "LOD"; 33 34 public override bool hasPreview { get { return true; } } 35 36 public SampleTexture2DLODNode() 37 { 38 name = "Sample Texture 2D LOD"; 39 synonyms = new string[] { "tex2dlod" }; 40 UpdateNodeAfterDeserialization(); 41 } 42 43 [SerializeField] 44 private TextureType m_TextureType = TextureType.Default; 45 46 [EnumControl("Type")] 47 public TextureType textureType 48 { 49 get { return m_TextureType; } 50 set 51 { 52 if (m_TextureType == value) 53 return; 54 55 m_TextureType = value; 56 Dirty(ModificationScope.Graph); 57 58 ValidateNode(); 59 } 60 } 61 62 [SerializeField] 63 private NormalMapSpace m_NormalMapSpace = NormalMapSpace.Tangent; 64 65 [EnumControl("Space")] 66 public NormalMapSpace normalMapSpace 67 { 68 get { return m_NormalMapSpace; } 69 set 70 { 71 if (m_NormalMapSpace == value) 72 return; 73 74 m_NormalMapSpace = value; 75 Dirty(ModificationScope.Graph); 76 } 77 } 78 79 public sealed override void UpdateNodeAfterDeserialization() 80 { 81 AddSlot(new Vector4MaterialSlot(OutputSlotRGBAId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, Vector4.zero, ShaderStageCapability.All)); 82 AddSlot(new Vector1MaterialSlot(OutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, 0, ShaderStageCapability.All)); 83 AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0, ShaderStageCapability.All)); 84 AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0, ShaderStageCapability.All)); 85 AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0, ShaderStageCapability.All)); 86 AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName)); 87 AddSlot(new UVMaterialSlot(UVInputId, kUVInputName, kUVInputName, UVChannel.UV0)); 88 AddSlot(new SamplerStateMaterialSlot(SamplerInputId, kSamplerInputName, kSamplerInputName, SlotType.Input)); 89 AddSlot(new Vector1MaterialSlot(LODInputId, kLODInputName, kLODInputName, SlotType.Input, 0)); 90 RemoveSlotsNameNotMatching(new[] { OutputSlotRGBAId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, TextureInputId, UVInputId, SamplerInputId, LODInputId }); 91 } 92 93 public override void Setup() 94 { 95 base.Setup(); 96 var textureSlot = FindInputSlot<Texture2DInputMaterialSlot>(TextureInputId); 97 textureSlot.defaultType = (textureType == TextureType.Normal ? Texture2DShaderProperty.DefaultType.NormalMap : Texture2DShaderProperty.DefaultType.White); 98 } 99 100 // Node generations 101 public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) 102 { 103 var uvName = GetSlotValue(UVInputId, generationMode); 104 105 //Sampler input slot 106 var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInputId); 107 var edgesSampler = owner.GetEdges(samplerSlot.slotReference); 108 var lodSlot = GetSlotValue(LODInputId, generationMode); 109 var id = GetSlotValue(TextureInputId, generationMode); 110 var result = string.Format(" $precision4 {0} = SAMPLE_TEXTURE2D_LOD({1}.tex, {2}.samplerstate, {1}.GetTransformedUV({3}), {4});" 111 , GetVariableNameForSlot(OutputSlotRGBAId) 112 , id 113 , edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : id 114 , uvName 115 , lodSlot); 116 sb.AppendLine(result); 117 118 if (textureType == TextureType.Normal) 119 { 120 if (normalMapSpace == NormalMapSpace.Tangent) 121 { 122 sb.AppendLine(string.Format("{0}.rgb = UnpackNormal({0});", GetVariableNameForSlot(OutputSlotRGBAId))); 123 } 124 else 125 { 126 sb.AppendLine(string.Format("{0}.rgb = UnpackNormalRGB({0});", GetVariableNameForSlot(OutputSlotRGBAId))); 127 } 128 } 129 130 sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId))); 131 sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId))); 132 sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId))); 133 sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId))); 134 } 135 136 public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) 137 { 138 var result = false; 139 using (var tempSlots = PooledList<MaterialSlot>.Get()) 140 { 141 GetInputSlots(tempSlots); 142 foreach (var slot in tempSlots) 143 { 144 if (slot.RequiresMeshUV(channel)) 145 { 146 result = true; 147 break; 148 } 149 } 150 } 151 152 return result; 153 } 154 } 155}