123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor.Graphing;
- using UnityEditor.Graphing.Util;
- using UnityEngine;
- using UnityEngine.Rendering;
- using UnityEngine.UIElements;
- using UnityEditor.ShaderGraph.Drawing.Controls;
- namespace UnityEditor.ShaderGraph
- {
- abstract class MasterNode : AbstractMaterialNode, IMasterNode, IHasSettings
- {
- public override bool hasPreview
- {
- get { return false; }
- }
- public override bool allowedInSubGraph
- {
- get { return false; }
- }
- public override PreviewMode previewMode
- {
- get { return PreviewMode.Preview3D; }
- }
- [SerializeField]
- bool m_DOTSInstancing = false;
- public ToggleData dotsInstancing
- {
- get { return new ToggleData(m_DOTSInstancing); }
- set
- {
- if (m_DOTSInstancing == value.isOn)
- return;
- m_DOTSInstancing = value.isOn;
- Dirty(ModificationScope.Graph);
- }
- }
- public abstract string GetShader(GenerationMode mode, string outputName, out List<PropertyCollector.TextureInfo> configuredTextures, List<string> sourceAssetDependencyPaths = null);
- public abstract bool IsPipelineCompatible(RenderPipelineAsset renderPipelineAsset);
- public abstract int GetPreviewPassIndex();
- public VisualElement CreateSettingsElement()
- {
- var container = new VisualElement();
- var commonSettingsElement = CreateCommonSettingsElement();
- if (commonSettingsElement != null)
- container.Add(commonSettingsElement);
- return container;
- }
- protected virtual VisualElement CreateCommonSettingsElement()
- {
- return null;
- }
- public virtual object saveContext => null;
- public virtual void ProcessPreviewMaterial(Material Material) {}
- }
- [Serializable]
- abstract class MasterNode<T> : MasterNode
- where T : class, ISubShader
- {
- [NonSerialized]
- List<T> m_SubShaders = new List<T>();
- [SerializeField]
- List<SerializationHelper.JSONSerializedElement> m_SerializableSubShaders = new List<SerializationHelper.JSONSerializedElement>();
- public IEnumerable<T> subShaders => m_SubShaders;
- public void AddSubShader(T subshader)
- {
- if (m_SubShaders.Contains(subshader))
- return;
- m_SubShaders.Add(subshader);
- Dirty(ModificationScope.Graph);
- }
- public void RemoveSubShader(T subshader)
- {
- m_SubShaders.RemoveAll(x => x == subshader);
- Dirty(ModificationScope.Graph);
- }
- public ISubShader GetActiveSubShader()
- {
- foreach (var subShader in m_SubShaders)
- {
- if (subShader.IsPipelineCompatible(GraphicsSettings.renderPipelineAsset))
- return subShader;
- }
- return null;
- }
- public sealed override string GetShader(GenerationMode mode, string outputName, out List<PropertyCollector.TextureInfo> configuredTextures, List<string> sourceAssetDependencyPaths = null)
- {
- var activeNodeList = Graphing.ListPool<AbstractMaterialNode>.Get();
- NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this);
- var shaderProperties = new PropertyCollector();
- var shaderKeywords = new KeywordCollector();
- if (owner != null)
- {
- owner.CollectShaderProperties(shaderProperties, mode);
- owner.CollectShaderKeywords(shaderKeywords, mode);
- }
- if(owner.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit)
- {
- owner.AddValidationError(tempId, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error);
- configuredTextures = shaderProperties.GetConfiguredTexutres();
- return ShaderGraphImporter.k_ErrorShader;
- }
- foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
- activeNode.CollectShaderProperties(shaderProperties, mode);
- var finalShader = new ShaderStringBuilder();
- finalShader.AppendLine(@"Shader ""{0}""", outputName);
- using (finalShader.BlockScope())
- {
- SubShaderGenerator.GeneratePropertiesBlock(finalShader, shaderProperties, shaderKeywords, mode);
- foreach (var subShader in m_SubShaders)
- {
- if (mode != GenerationMode.Preview || subShader.IsPipelineCompatible(GraphicsSettings.renderPipelineAsset))
- finalShader.AppendLines(subShader.GetSubshader(this, mode, sourceAssetDependencyPaths));
- }
- finalShader.AppendLine(@"FallBack ""Hidden/Shader Graph/FallbackError""");
- }
- configuredTextures = shaderProperties.GetConfiguredTexutres();
- return finalShader.ToString();
- }
- public sealed override bool IsPipelineCompatible(RenderPipelineAsset renderPipelineAsset)
- {
- foreach (var subShader in m_SubShaders)
- {
- if (subShader.IsPipelineCompatible(GraphicsSettings.renderPipelineAsset))
- return true;
- }
- return false;
- }
- public sealed override int GetPreviewPassIndex()
- {
- return GetActiveSubShader()?.GetPreviewPassIndex() ?? 0;
- }
- public override void OnBeforeSerialize()
- {
- base.OnBeforeSerialize();
- m_SerializableSubShaders = SerializationHelper.Serialize<T>(m_SubShaders);
- }
- public override void OnAfterDeserialize()
- {
- m_SubShaders = SerializationHelper.Deserialize<T>(m_SerializableSubShaders, GraphUtil.GetLegacyTypeRemapping());
- m_SubShaders.RemoveAll(x => x == null);
- m_SerializableSubShaders = null;
- base.OnAfterDeserialize();
- }
- public override void UpdateNodeAfterDeserialization()
- {
- base.UpdateNodeAfterDeserialization();
- foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
- {
- foreach (var type in assembly.GetTypesOrNothing())
- {
- var isValid = !type.IsAbstract && !type.IsGenericType && type.IsClass && typeof(T).IsAssignableFrom(type);
- if (isValid && !subShaders.Any(s => s.GetType() == type))
- {
- try
- {
- var subShader = (T)Activator.CreateInstance(type);
- AddSubShader(subShader);
- }
- catch (Exception e)
- {
- Debug.LogException(e);
- }
- }
- }
- }
- }
- }
- }
|