initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
@ -0,0 +1,256 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
using UnityEditor.AssetImporters;
|
||||
#else
|
||||
using UnityEditor.Experimental.AssetImporters;
|
||||
#endif
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
[Serializable]
|
||||
struct FunctionPair
|
||||
{
|
||||
public string key; // aka function name
|
||||
public string value; // aka function code
|
||||
public int graphPrecisionFlags; // Flags<GraphPrecision> indicating which precision variants are requested by the subgraph
|
||||
|
||||
public FunctionPair(string key, string value, int graphPrecisionFlags)
|
||||
{
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.graphPrecisionFlags = graphPrecisionFlags;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class SlotCapability
|
||||
{
|
||||
public string slotName;
|
||||
public ShaderStageCapability capabilities = ShaderStageCapability.All;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class SlotDependencyPair
|
||||
{
|
||||
public string inputSlotName;
|
||||
public string outputSlotName;
|
||||
}
|
||||
|
||||
/// Cached run-time information for slot dependency tracking within a sub-graph
|
||||
class SlotDependencyInfo
|
||||
{
|
||||
internal string slotName;
|
||||
internal ShaderStageCapability capabilities = ShaderStageCapability.All;
|
||||
internal HashSet<string> dependencies = new HashSet<string>();
|
||||
|
||||
internal void AddDepencencySlotName(string slotName)
|
||||
{
|
||||
dependencies.Add(slotName);
|
||||
}
|
||||
|
||||
internal bool ContainsSlot(MaterialSlot slot)
|
||||
{
|
||||
return dependencies.Contains(slot.RawDisplayName());
|
||||
}
|
||||
}
|
||||
|
||||
class SubGraphData : JsonObject
|
||||
{
|
||||
public List<JsonData<AbstractShaderProperty>> inputs = new List<JsonData<AbstractShaderProperty>>();
|
||||
public List<JsonData<ShaderKeyword>> keywords = new List<JsonData<ShaderKeyword>>();
|
||||
public List<JsonData<ShaderDropdown>> dropdowns = new List<JsonData<ShaderDropdown>>();
|
||||
public List<JsonData<AbstractShaderProperty>> nodeProperties = new List<JsonData<AbstractShaderProperty>>();
|
||||
public List<JsonData<MaterialSlot>> outputs = new List<JsonData<MaterialSlot>>();
|
||||
public List<JsonData<Target>> unsupportedTargets = new List<JsonData<Target>>();
|
||||
}
|
||||
|
||||
class SubGraphAsset : ScriptableObject, ISerializationCallbackReceiver
|
||||
{
|
||||
public bool isValid;
|
||||
|
||||
public long processedAt;
|
||||
|
||||
public string functionName;
|
||||
|
||||
public string inputStructName;
|
||||
|
||||
public string hlslName;
|
||||
|
||||
public string assetGuid;
|
||||
|
||||
public ShaderGraphRequirements requirements;
|
||||
|
||||
public string path;
|
||||
|
||||
public List<FunctionPair> functions = new List<FunctionPair>();
|
||||
|
||||
public IncludeCollection includes;
|
||||
|
||||
public List<string> vtFeedbackVariables = new List<string>();
|
||||
|
||||
private SubGraphData m_SubGraphData;
|
||||
|
||||
[SerializeField]
|
||||
private SerializationHelper.JSONSerializedElement m_SerializedSubGraphData;
|
||||
|
||||
public DataValueEnumerable<AbstractShaderProperty> inputs => m_SubGraphData.inputs.SelectValue();
|
||||
|
||||
public DataValueEnumerable<ShaderKeyword> keywords => m_SubGraphData.keywords.SelectValue();
|
||||
|
||||
public DataValueEnumerable<ShaderDropdown> dropdowns => m_SubGraphData.dropdowns.SelectValue();
|
||||
|
||||
public DataValueEnumerable<AbstractShaderProperty> nodeProperties => m_SubGraphData.nodeProperties.SelectValue();
|
||||
|
||||
public DataValueEnumerable<MaterialSlot> outputs => m_SubGraphData.outputs.SelectValue();
|
||||
|
||||
public DataValueEnumerable<Target> unsupportedTargets => m_SubGraphData.unsupportedTargets.SelectValue();
|
||||
|
||||
public List<string> children = new List<string>(); // guids of direct USED SUBGRAPH file dependencies
|
||||
|
||||
public List<string> descendents = new List<string>(); // guids of ALL file dependencies at any level, SHOULD LIST EVEN MISSING DESCENDENTS
|
||||
|
||||
public List<SlotCapability> inputCapabilities = new List<SlotCapability>();
|
||||
public List<SlotCapability> outputCapabilities = new List<SlotCapability>();
|
||||
// Every unique input/output dependency pair
|
||||
public List<SlotDependencyPair> slotDependencies = new List<SlotDependencyPair>();
|
||||
|
||||
Dictionary<string, SlotDependencyInfo> m_InputDependencies = new Dictionary<string, SlotDependencyInfo>();
|
||||
Dictionary<string, SlotDependencyInfo> m_OutputDependencies = new Dictionary<string, SlotDependencyInfo>();
|
||||
|
||||
|
||||
public SlotDependencyInfo GetInputDependencies(string slotName)
|
||||
{
|
||||
m_InputDependencies.TryGetValue(slotName, out SlotDependencyInfo result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public SlotDependencyInfo GetOutputDependencies(string slotName)
|
||||
{
|
||||
m_OutputDependencies.TryGetValue(slotName, out SlotDependencyInfo result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// this is the precision that the entire subgraph is set to (indicates whether the graph is hard-coded or switchable)
|
||||
public GraphPrecision subGraphGraphPrecision;
|
||||
|
||||
// this is the precision of the subgraph outputs
|
||||
// NOTE: this may not be the same as subGraphGraphPrecision
|
||||
// for example, a graph could allow switching precisions for internal calculations,
|
||||
// but the output of the graph is always full float
|
||||
// NOTE: we don't currently have a way to select the graph precision for EACH output
|
||||
// there's a single shared precision for all of them
|
||||
public GraphPrecision outputGraphPrecision;
|
||||
|
||||
public PreviewMode previewMode;
|
||||
|
||||
public void WriteData(IEnumerable<AbstractShaderProperty> inputs, IEnumerable<ShaderKeyword> keywords, IEnumerable<ShaderDropdown> dropdowns, IEnumerable<AbstractShaderProperty> nodeProperties, IEnumerable<MaterialSlot> outputs, IEnumerable<Target> unsupportedTargets)
|
||||
{
|
||||
if (m_SubGraphData == null)
|
||||
{
|
||||
m_SubGraphData = new SubGraphData();
|
||||
m_SubGraphData.OverrideObjectId(assetGuid, "_subGraphData");
|
||||
}
|
||||
|
||||
m_SubGraphData.inputs.Clear();
|
||||
m_SubGraphData.keywords.Clear();
|
||||
m_SubGraphData.dropdowns.Clear();
|
||||
m_SubGraphData.nodeProperties.Clear();
|
||||
m_SubGraphData.outputs.Clear();
|
||||
m_SubGraphData.unsupportedTargets.Clear();
|
||||
|
||||
foreach (var input in inputs)
|
||||
{
|
||||
m_SubGraphData.inputs.Add(input);
|
||||
}
|
||||
|
||||
foreach (var keyword in keywords)
|
||||
{
|
||||
m_SubGraphData.keywords.Add(keyword);
|
||||
}
|
||||
|
||||
foreach (var dropdown in dropdowns)
|
||||
{
|
||||
m_SubGraphData.dropdowns.Add(dropdown);
|
||||
}
|
||||
|
||||
foreach (var nodeProperty in nodeProperties)
|
||||
{
|
||||
m_SubGraphData.nodeProperties.Add(nodeProperty);
|
||||
}
|
||||
|
||||
foreach (var output in outputs)
|
||||
{
|
||||
m_SubGraphData.outputs.Add(output);
|
||||
}
|
||||
|
||||
foreach (var unsupportedTarget in unsupportedTargets)
|
||||
{
|
||||
m_SubGraphData.unsupportedTargets.Add(unsupportedTarget);
|
||||
}
|
||||
var json = MultiJson.Serialize(m_SubGraphData);
|
||||
m_SerializedSubGraphData = new SerializationHelper.JSONSerializedElement() { JSONnodeData = json };
|
||||
m_SubGraphData = null;
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void LoadGraphData()
|
||||
{
|
||||
m_SubGraphData = new SubGraphData();
|
||||
if (!String.IsNullOrEmpty(m_SerializedSubGraphData.JSONnodeData))
|
||||
{
|
||||
MultiJson.Deserialize(m_SubGraphData, m_SerializedSubGraphData.JSONnodeData);
|
||||
}
|
||||
}
|
||||
|
||||
internal void LoadDependencyData()
|
||||
{
|
||||
m_InputDependencies.Clear();
|
||||
m_OutputDependencies.Clear();
|
||||
|
||||
foreach (var capabilityInfo in inputCapabilities)
|
||||
{
|
||||
var dependencyInfo = new SlotDependencyInfo();
|
||||
dependencyInfo.slotName = capabilityInfo.slotName;
|
||||
dependencyInfo.capabilities = capabilityInfo.capabilities;
|
||||
if (m_InputDependencies.ContainsKey(dependencyInfo.slotName))
|
||||
{
|
||||
Debug.LogWarning($"SubGraph '{hlslName}' has multiple input slots named '{dependencyInfo.slotName}', which is unsupported. Please assign the input slots unique names.");
|
||||
continue;
|
||||
}
|
||||
m_InputDependencies.Add(dependencyInfo.slotName, dependencyInfo);
|
||||
}
|
||||
foreach (var capabilityInfo in outputCapabilities)
|
||||
{
|
||||
var dependencyInfo = new SlotDependencyInfo();
|
||||
dependencyInfo.slotName = capabilityInfo.slotName;
|
||||
dependencyInfo.capabilities = capabilityInfo.capabilities;
|
||||
if (m_OutputDependencies.ContainsKey(dependencyInfo.slotName))
|
||||
{
|
||||
Debug.LogWarning($"SubGraph '{hlslName}' has multiple output slots named '{dependencyInfo.slotName}', which is unsupported. Please assign the output slots unique names.");
|
||||
continue;
|
||||
}
|
||||
m_OutputDependencies.Add(dependencyInfo.slotName, dependencyInfo);
|
||||
}
|
||||
foreach (var slotDependency in slotDependencies)
|
||||
{
|
||||
// This shouldn't fail since every input/output must be in the above lists...
|
||||
if (m_InputDependencies.ContainsKey(slotDependency.inputSlotName))
|
||||
m_InputDependencies[slotDependency.inputSlotName].AddDepencencySlotName(slotDependency.outputSlotName);
|
||||
if (m_OutputDependencies.ContainsKey(slotDependency.outputSlotName))
|
||||
m_OutputDependencies[slotDependency.outputSlotName].AddDepencencySlotName(slotDependency.inputSlotName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f28ce979dc22145fd8160e458f72f65d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,113 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor.ShaderGraph.Drawing;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine.Rendering.ShaderGraph;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
class SubGraphOutputNode : AbstractMaterialNode
|
||||
{
|
||||
static string s_MissingOutputSlot = "A Sub Graph must have at least one output slot";
|
||||
static List<ConcreteSlotValueType> s_ValidSlotTypes = new List<ConcreteSlotValueType>()
|
||||
{
|
||||
ConcreteSlotValueType.Vector1,
|
||||
ConcreteSlotValueType.Vector2,
|
||||
ConcreteSlotValueType.Vector3,
|
||||
ConcreteSlotValueType.Vector4,
|
||||
ConcreteSlotValueType.Matrix2,
|
||||
ConcreteSlotValueType.Matrix3,
|
||||
ConcreteSlotValueType.Matrix4,
|
||||
ConcreteSlotValueType.Boolean
|
||||
};
|
||||
public bool IsFirstSlotValid = true;
|
||||
|
||||
public SubGraphOutputNode()
|
||||
{
|
||||
name = "Output";
|
||||
}
|
||||
|
||||
// Link to the Sub Graph overview page instead of the specific Node page, seems more useful
|
||||
public override string documentationURL => Documentation.GetPageLink("Sub-graph");
|
||||
|
||||
void ValidateShaderStage()
|
||||
{
|
||||
List<MaterialSlot> slots = new List<MaterialSlot>();
|
||||
GetInputSlots(slots);
|
||||
|
||||
// Reset all input slots back to All, otherwise they'll be incorrectly configured when traversing below
|
||||
foreach (MaterialSlot slot in slots)
|
||||
slot.stageCapability = ShaderStageCapability.All;
|
||||
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
slot.stageCapability = NodeUtils.GetEffectiveShaderStageCapability(slot, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ValidateSlotName()
|
||||
{
|
||||
List<MaterialSlot> slots = new List<MaterialSlot>();
|
||||
GetInputSlots(slots);
|
||||
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
var error = NodeUtils.ValidateSlotName(slot.RawDisplayName(), out string errorMessage);
|
||||
if (error)
|
||||
{
|
||||
owner.AddValidationError(objectId, errorMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ValidateSlotType()
|
||||
{
|
||||
List<MaterialSlot> slots = new List<MaterialSlot>();
|
||||
GetInputSlots(slots);
|
||||
|
||||
if (!slots.Any())
|
||||
{
|
||||
owner.AddValidationError(objectId, s_MissingOutputSlot, ShaderCompilerMessageSeverity.Error);
|
||||
}
|
||||
else if (!s_ValidSlotTypes.Contains(slots.FirstOrDefault().concreteValueType))
|
||||
{
|
||||
IsFirstSlotValid = false;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ValidateNode()
|
||||
{
|
||||
base.ValidateNode();
|
||||
IsFirstSlotValid = true;
|
||||
ValidateSlotType();
|
||||
if (IsFirstSlotValid)
|
||||
ValidateShaderStage();
|
||||
}
|
||||
|
||||
protected override void OnSlotsChanged()
|
||||
{
|
||||
base.OnSlotsChanged();
|
||||
ValidateNode();
|
||||
}
|
||||
|
||||
public int AddSlot(ConcreteSlotValueType concreteValueType)
|
||||
{
|
||||
var index = this.GetInputSlots<MaterialSlot>().Count() + 1;
|
||||
var name = NodeUtils.GetDuplicateSafeNameForSlot(this, index, "Out_" + concreteValueType.ToString());
|
||||
AddSlot(MaterialSlot.CreateMaterialSlot(concreteValueType.ToSlotValueType(), index, name,
|
||||
NodeUtils.GetHLSLSafeName(name), SlotType.Input, Vector4.zero));
|
||||
return index;
|
||||
}
|
||||
|
||||
public override bool canDeleteNode => false;
|
||||
|
||||
public override bool canCopyNode => false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ec0207b061e270b4a96a01fbe11c18ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue