A game about forced loneliness, made by TACStudios
at master 247 lines 8.9 kB view raw
1using System; 2using System.Linq; 3using System.Collections.Generic; 4using UnityEngine; 5using UnityEngine.Rendering; 6using UnityEngine.UIElements; 7using UnityEditor; 8using UnityEditor.ShaderGraph; 9using UnityEditor.UIElements; 10using UnityEditor.ShaderGraph.Serialization; 11using SubTargetListPool = UnityEngine.Rendering.ListPool<UnityEditor.ShaderGraph.SubTarget>; 12using System.Reflection; 13 14namespace UnityEditor.Rendering.CustomRenderTexture.ShaderGraph 15{ 16 [GenerateBlocks] 17 internal struct FullScreenBlocks 18 { 19 // TODO: use base color and alpha blocks 20 public static BlockFieldDescriptor colorBlock = new BlockFieldDescriptor(String.Empty, "Color", "Color", 21 new ColorRGBAControl(UnityEngine.Color.white), ShaderStage.Fragment); 22 } 23 24 sealed class CustomRenderTextureTarget : Target 25 { 26 // Constants 27 const string kAssetGuid = "a0bae34258e39cd4899b63278c24c086"; // FullscreenPassTarget.cs 28 29 // SubTarget 30 List<SubTarget> m_SubTargets; 31 List<string> m_SubTargetNames; 32 int activeSubTargetIndex => m_SubTargets.IndexOf(m_ActiveSubTarget); 33 34 // View 35 PopupField<string> m_SubTargetField; 36 TextField m_CustomGUIField; 37 38 [SerializeField] 39 JsonData<SubTarget> m_ActiveSubTarget; 40 41 [SerializeField] 42 string m_CustomEditorGUI; 43 44 public CustomRenderTextureTarget() 45 { 46 displayName = "Custom Render Texture"; 47 isHidden = false; 48 m_SubTargets = GetSubTargets(this); 49 m_SubTargetNames = m_SubTargets.Select(x => x.displayName).ToList(); 50 ProcessSubTargetList(ref m_ActiveSubTarget, ref m_SubTargets); 51 } 52 53 public static void ProcessSubTargetList(ref JsonData<SubTarget> activeSubTarget, ref List<SubTarget> subTargets) 54 { 55 if (subTargets == null || subTargets.Count == 0) 56 return; 57 58 // assign the initial sub-target, if none is assigned yet 59 if (activeSubTarget.value == null) 60 activeSubTarget = subTargets[0]; 61 62 // Update SubTarget list with active SubTarget 63 var activeSubTargetType = activeSubTarget.value.GetType(); 64 var activeSubTargetCurrent = subTargets.FirstOrDefault(x => x.GetType() == activeSubTargetType); 65 var index = subTargets.IndexOf(activeSubTargetCurrent); 66 subTargets[index] = activeSubTarget; 67 } 68 69 public static List<SubTarget> GetSubTargets<T>(T target) where T : Target 70 { 71 // Get Variants 72 var subTargets = SubTargetListPool.Get(); 73 var typeCollection = TypeCache.GetTypesDerivedFrom<SubTarget>(); 74 foreach (var type in typeCollection) 75 { 76 if (type.IsAbstract || !type.IsClass) 77 continue; 78 79 var subTarget = (SubTarget)Activator.CreateInstance(type); 80 if (!subTarget.isHidden && subTarget.targetType.Equals(typeof(T))) 81 { 82 subTarget.target = target; 83 subTargets.Add(subTarget); 84 } 85 } 86 87 return subTargets; 88 } 89 90 public SubTarget activeSubTarget 91 { 92 get => m_ActiveSubTarget; 93 set => m_ActiveSubTarget = value; 94 } 95 96 public string customEditorGUI 97 { 98 get => m_CustomEditorGUI; 99 set => m_CustomEditorGUI = value; 100 } 101 102 public override bool IsActive() => activeSubTarget.IsActive(); 103 104 public override void Setup(ref TargetSetupContext context) 105 { 106 // Setup the Target 107 context.AddAssetDependency(new GUID(kAssetGuid), AssetCollection.Flags.SourceDependency); 108 109 // Setup the active SubTarget 110 ProcessSubTargetList(ref m_ActiveSubTarget, ref m_SubTargets); 111 m_ActiveSubTarget.value.target = this; 112 m_ActiveSubTarget.value.Setup(ref context); 113 114 // Override EditorGUI 115 if (!string.IsNullOrEmpty(m_CustomEditorGUI)) 116 { 117 context.SetDefaultShaderGUI(m_CustomEditorGUI); 118 } 119 } 120 121 public override void GetFields(ref TargetFieldContext context) 122 { 123 var descs = context.blocks.Select(x => x.descriptor); 124 // Core fields 125 context.AddField(Fields.GraphVertex, descs.Contains(BlockFields.VertexDescription.Position) || 126 descs.Contains(BlockFields.VertexDescription.Normal) || 127 descs.Contains(BlockFields.VertexDescription.Tangent)); 128 context.AddField(Fields.GraphPixel); 129 130 // SubTarget fields 131 m_ActiveSubTarget.value.GetFields(ref context); 132 } 133 134 public override void GetActiveBlocks(ref TargetActiveBlockContext context) 135 { 136 // SubTarget blocks 137 m_ActiveSubTarget.value.GetActiveBlocks(ref context); 138 } 139 140 public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action<String> registerUndo) 141 { 142 // Core properties 143 m_SubTargetField = new PopupField<string>(m_SubTargetNames, activeSubTargetIndex); 144 context.AddProperty("Material", m_SubTargetField, (evt) => 145 { 146 if (Equals(activeSubTargetIndex, m_SubTargetField.index)) 147 return; 148 149 registerUndo("Change Material"); 150 m_ActiveSubTarget = m_SubTargets[m_SubTargetField.index]; 151 onChange(); 152 }); 153 154 // SubTarget properties 155 m_ActiveSubTarget.value.GetPropertiesGUI(ref context, onChange, registerUndo); 156 157 // Custom Editor GUI 158 // Requires FocusOutEvent 159 m_CustomGUIField = new TextField("") { value = customEditorGUI }; 160 m_CustomGUIField.RegisterCallback<FocusOutEvent>(s => 161 { 162 if (Equals(customEditorGUI, m_CustomGUIField.value)) 163 return; 164 165 registerUndo("Change Custom Editor GUI"); 166 customEditorGUI = m_CustomGUIField.value; 167 onChange(); 168 }); 169 context.AddProperty("Custom Editor GUI", m_CustomGUIField, (evt) => { }); 170 } 171 172 public bool TrySetActiveSubTarget(Type subTargetType) 173 { 174 if (!subTargetType.IsSubclassOf(typeof(SubTarget))) 175 return false; 176 177 foreach (var subTarget in m_SubTargets) 178 { 179 if (subTarget.GetType().Equals(subTargetType)) 180 { 181 m_ActiveSubTarget = subTarget; 182 return true; 183 } 184 } 185 186 return false; 187 } 188 189 public override bool WorksWithSRP(RenderPipelineAsset scriptableRenderPipeline) => true; 190 191 public override bool IsNodeAllowedByTarget(System.Type nodeType) 192 { 193 SRPFilterAttribute srpFilter = NodeClassCache.GetAttributeOnNodeType<SRPFilterAttribute>(nodeType); 194 bool allowed = true; 195 196 if (srpFilter != null) 197 allowed = false; 198 199 return allowed && nodeType != typeof(MainLightDirectionNode); 200 } 201 } 202 203 static class FullscreePasses 204 { 205 public static PassDescriptor CustomRenderTexture = new PassDescriptor 206 { 207 // Definition 208 referenceName = "SHADERPASS_CUSTOM_RENDER_TEXTURE", 209 useInPreview = true, 210 211 // Template 212 passTemplatePath = AssetDatabase.GUIDToAssetPath("afa536a0de48246de92194c9e987b0b8"), // CustomTextureSubShader.template 213 214 // Port Mask 215 validVertexBlocks = new BlockFieldDescriptor[] 216 { 217 BlockFields.VertexDescription.Position, 218 BlockFields.VertexDescription.Normal, 219 BlockFields.VertexDescription.Tangent, 220 }, 221 validPixelBlocks = new BlockFieldDescriptor[] 222 { 223 BlockFields.SurfaceDescription.BaseColor, 224 BlockFields.SurfaceDescription.Alpha, 225 }, 226 227 // Fields 228 structs = new StructCollection 229 { 230 { Structs.Attributes }, 231 { Structs.SurfaceDescriptionInputs }, 232 { Structs.VertexDescriptionInputs }, 233 }, 234 requiredFields = new FieldCollection() 235 { 236 StructFields.Attributes.color, 237 StructFields.Attributes.uv0, 238 StructFields.Varyings.color, 239 StructFields.Varyings.texCoord0, 240 }, 241 fieldDependencies = new DependencyCollection() 242 { 243 { FieldDependencies.Default }, 244 }, 245 }; 246 } 247}