A game about forced loneliness, made by TACStudios
at master 113 lines 3.9 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Reflection; 5using UnityEditor.ShaderGraph.Drawing; 6using UnityEngine; 7using UnityEditor.Graphing; 8using UnityEditor.Rendering; 9using UnityEngine.Rendering.ShaderGraph; 10using UnityEngine.UIElements; 11 12namespace UnityEditor.ShaderGraph 13{ 14 class SubGraphOutputNode : AbstractMaterialNode 15 { 16 static string s_MissingOutputSlot = "A Sub Graph must have at least one output slot"; 17 static List<ConcreteSlotValueType> s_ValidSlotTypes = new List<ConcreteSlotValueType>() 18 { 19 ConcreteSlotValueType.Vector1, 20 ConcreteSlotValueType.Vector2, 21 ConcreteSlotValueType.Vector3, 22 ConcreteSlotValueType.Vector4, 23 ConcreteSlotValueType.Matrix2, 24 ConcreteSlotValueType.Matrix3, 25 ConcreteSlotValueType.Matrix4, 26 ConcreteSlotValueType.Boolean 27 }; 28 public bool IsFirstSlotValid = true; 29 30 public SubGraphOutputNode() 31 { 32 name = "Output"; 33 } 34 35 // Link to the Sub Graph overview page instead of the specific Node page, seems more useful 36 public override string documentationURL => Documentation.GetPageLink("Sub-graph"); 37 38 void ValidateShaderStage() 39 { 40 List<MaterialSlot> slots = new List<MaterialSlot>(); 41 GetInputSlots(slots); 42 43 // Reset all input slots back to All, otherwise they'll be incorrectly configured when traversing below 44 foreach (MaterialSlot slot in slots) 45 slot.stageCapability = ShaderStageCapability.All; 46 47 foreach (var slot in slots) 48 { 49 slot.stageCapability = NodeUtils.GetEffectiveShaderStageCapability(slot, true); 50 } 51 } 52 53 void ValidateSlotName() 54 { 55 List<MaterialSlot> slots = new List<MaterialSlot>(); 56 GetInputSlots(slots); 57 58 foreach (var slot in slots) 59 { 60 var error = NodeUtils.ValidateSlotName(slot.RawDisplayName(), out string errorMessage); 61 if (error) 62 { 63 owner.AddValidationError(objectId, errorMessage); 64 break; 65 } 66 } 67 } 68 69 void ValidateSlotType() 70 { 71 List<MaterialSlot> slots = new List<MaterialSlot>(); 72 GetInputSlots(slots); 73 74 if (!slots.Any()) 75 { 76 owner.AddValidationError(objectId, s_MissingOutputSlot, ShaderCompilerMessageSeverity.Error); 77 } 78 else if (!s_ValidSlotTypes.Contains(slots.FirstOrDefault().concreteValueType)) 79 { 80 IsFirstSlotValid = false; 81 owner.AddValidationError(objectId, "Preview can only compile if the first output slot is a Vector, Matrix, or Boolean type. Please adjust slot types.", ShaderCompilerMessageSeverity.Error); 82 } 83 } 84 85 public override void ValidateNode() 86 { 87 base.ValidateNode(); 88 IsFirstSlotValid = true; 89 ValidateSlotType(); 90 if (IsFirstSlotValid) 91 ValidateShaderStage(); 92 } 93 94 protected override void OnSlotsChanged() 95 { 96 base.OnSlotsChanged(); 97 ValidateNode(); 98 } 99 100 public int AddSlot(ConcreteSlotValueType concreteValueType) 101 { 102 var index = this.GetInputSlots<MaterialSlot>().Count() + 1; 103 var name = NodeUtils.GetDuplicateSafeNameForSlot(this, index, "Out_" + concreteValueType.ToString()); 104 AddSlot(MaterialSlot.CreateMaterialSlot(concreteValueType.ToSlotValueType(), index, name, 105 NodeUtils.GetHLSLSafeName(name), SlotType.Input, Vector4.zero)); 106 return index; 107 } 108 109 public override bool canDeleteNode => false; 110 111 public override bool canCopyNode => false; 112 } 113}