123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using UnityEditor.Graphing;
- using UnityEditor.ShaderGraph.Internal;
-
- namespace UnityEditor.ShaderGraph
- {
- [HasDependencies(typeof(MinimalSubGraphNode))]
- [Title("Utility", "Sub-graph")]
- class SubGraphNode : AbstractMaterialNode
- , IGeneratesBodyCode
- , IOnAssetEnabled
- , IGeneratesFunction
- , IMayRequireNormal
- , IMayRequireTangent
- , IMayRequireBitangent
- , IMayRequireMeshUV
- , IMayRequireScreenPosition
- , IMayRequireNDCPosition
- , IMayRequirePixelPosition
- , IMayRequireViewDirection
- , IMayRequirePosition
- , IMayRequirePositionPredisplacement
- , IMayRequireVertexColor
- , IMayRequireTime
- , IMayRequireFaceSign
- , IMayRequireCameraOpaqueTexture
- , IMayRequireDepthTexture
- , IMayRequireVertexSkinning
- , IMayRequireVertexID
- , IMayRequireInstanceID
- , IDisposable
- {
- [Serializable]
- public class MinimalSubGraphNode : IHasDependencies
- {
- [SerializeField]
- string m_SerializedSubGraph = string.Empty;
-
- public void GetSourceAssetDependencies(AssetCollection assetCollection)
- {
- var assetReference = JsonUtility.FromJson<SubGraphAssetReference>(m_SerializedSubGraph);
- string guidString = assetReference?.subGraph?.guid;
- if (!string.IsNullOrEmpty(guidString) && GUID.TryParse(guidString, out GUID guid))
- {
- // subgraphs are read as artifacts
- // they also should be pulled into .unitypackages
- assetCollection.AddAssetDependency(
- guid,
- AssetCollection.Flags.ArtifactDependency |
- AssetCollection.Flags.IsSubGraph |
- AssetCollection.Flags.IncludeInExportPackage);
- }
- }
- }
-
- [Serializable]
- class SubGraphHelper
- {
- public SubGraphAsset subGraph;
- }
-
- [Serializable]
- class SubGraphAssetReference
- {
- public AssetReference subGraph = default;
-
- public override string ToString()
- {
- return $"subGraph={subGraph}";
- }
- }
-
- [Serializable]
- class AssetReference
- {
- public long fileID = default;
- public string guid = default;
- public int type = default;
-
- public override string ToString()
- {
- return $"fileID={fileID}, guid={guid}, type={type}";
- }
- }
-
- [SerializeField]
- string m_SerializedSubGraph = string.Empty;
-
- [NonSerialized]
- SubGraphAsset m_SubGraph; // This should not be accessed directly by most code -- use the asset property instead, and check for NULL! :)
-
- [SerializeField]
- List<string> m_PropertyGuids = new List<string>();
-
- [SerializeField]
- List<int> m_PropertyIds = new List<int>();
-
- [SerializeField]
- List<string> m_Dropdowns = new List<string>();
-
- [SerializeField]
- List<string> m_DropdownSelectedEntries = new List<string>();
-
- public string subGraphGuid
- {
- get
- {
- var assetReference = JsonUtility.FromJson<SubGraphAssetReference>(m_SerializedSubGraph);
- return assetReference?.subGraph?.guid;
- }
- }
-
- void LoadSubGraph()
- {
- if (m_SubGraph == null)
- {
- if (string.IsNullOrEmpty(m_SerializedSubGraph))
- {
- return;
- }
-
- var graphGuid = subGraphGuid;
- var assetPath = AssetDatabase.GUIDToAssetPath(graphGuid);
- if (string.IsNullOrEmpty(assetPath))
- {
- // this happens if the editor has never seen the GUID
- // error will be printed by validation code in this case
- return;
- }
- m_SubGraph = AssetDatabase.LoadAssetAtPath<SubGraphAsset>(assetPath);
- if (m_SubGraph == null)
- {
- // this happens if the editor has seen the GUID, but the file has been deleted since then
- // error will be printed by validation code in this case
- return;
- }
- m_SubGraph.LoadGraphData();
- m_SubGraph.LoadDependencyData();
-
- name = m_SubGraph.name;
- }
- }
-
- public SubGraphAsset asset
- {
- get
- {
- LoadSubGraph();
- return m_SubGraph;
- }
- set
- {
- if (asset == value)
- return;
-
- var helper = new SubGraphHelper();
- helper.subGraph = value;
- m_SerializedSubGraph = EditorJsonUtility.ToJson(helper, true);
- m_SubGraph = null;
- UpdateSlots();
-
- Dirty(ModificationScope.Topological);
- }
- }
-
- public override bool hasPreview
- {
- get { return true; }
- }
-
- public override PreviewMode previewMode
- {
- get
- {
- PreviewMode mode = m_PreviewMode;
- if ((mode == PreviewMode.Inherit) && (asset != null))
- mode = asset.previewMode;
- return mode;
- }
- }
-
- public SubGraphNode()
- {
- name = "Sub Graph";
- }
-
- public override bool allowedInSubGraph
- {
- get { return true; }
- }
-
- public override bool canSetPrecision
- {
- get { return asset?.subGraphGraphPrecision == GraphPrecision.Graph; }
- }
-
- public override void GetInputSlots<T>(MaterialSlot startingSlot, List<T> foundSlots)
- {
- var allSlots = new List<T>();
- GetInputSlots<T>(allSlots);
- var info = asset?.GetOutputDependencies(startingSlot.RawDisplayName());
- if (info != null)
- {
- foreach (var slot in allSlots)
- {
- if (info.ContainsSlot(slot))
- foundSlots.Add(slot);
- }
- }
- }
-
- public override void GetOutputSlots<T>(MaterialSlot startingSlot, List<T> foundSlots)
- {
- var allSlots = new List<T>();
- GetOutputSlots<T>(allSlots);
- var info = asset?.GetInputDependencies(startingSlot.RawDisplayName());
- if (info != null)
- {
- foreach (var slot in allSlots)
- {
- if (info.ContainsSlot(slot))
- foundSlots.Add(slot);
- }
- }
- }
-
- ShaderStageCapability GetSlotCapability(MaterialSlot slot)
- {
- SlotDependencyInfo dependencyInfo;
- if (slot.isInputSlot)
- dependencyInfo = asset?.GetInputDependencies(slot.RawDisplayName());
- else
- dependencyInfo = asset?.GetOutputDependencies(slot.RawDisplayName());
-
- if (dependencyInfo != null)
- return dependencyInfo.capabilities;
- return ShaderStageCapability.All;
- }
-
- public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
- {
- var outputGraphPrecision = asset?.outputGraphPrecision ?? GraphPrecision.Single;
- var outputPrecision = outputGraphPrecision.ToConcrete(concretePrecision);
-
- if (asset == null || hasError)
- {
- var outputSlots = new List<MaterialSlot>();
- GetOutputSlots(outputSlots);
-
- foreach (var slot in outputSlots)
- {
- sb.AppendLine($"{slot.concreteValueType.ToShaderString(outputPrecision)} {GetVariableNameForSlot(slot.id)} = {slot.GetDefaultValue(GenerationMode.ForReals)};");
- }
-
- return;
- }
-
- var inputVariableName = $"_{GetVariableNameForNode()}";
-
- GenerationUtils.GenerateSurfaceInputTransferCode(sb, asset.requirements, asset.inputStructName, inputVariableName);
-
- // declare output variables
- foreach (var outSlot in asset.outputs)
- sb.AppendLine("{0} {1};", outSlot.concreteValueType.ToShaderString(outputPrecision), GetVariableNameForSlot(outSlot.id));
-
- var arguments = new List<string>();
- foreach (AbstractShaderProperty prop in asset.inputs)
- {
- // setup the property concrete precision (fallback to node concrete precision when it's switchable)
- prop.SetupConcretePrecision(this.concretePrecision);
- var inSlotId = m_PropertyIds[m_PropertyGuids.IndexOf(prop.guid.ToString())];
- arguments.Add(GetSlotValue(inSlotId, generationMode, prop.concretePrecision));
-
- if (prop.isConnectionTestable)
- arguments.Add(IsSlotConnected(inSlotId) ? "true" : "false");
- }
-
- var dropdowns = asset.dropdowns;
- foreach (var dropdown in dropdowns)
- {
- var name = GetDropdownEntryName(dropdown.referenceName);
- if (dropdown.ContainsEntry(name))
- arguments.Add(dropdown.IndexOfName(name).ToString());
- else
- arguments.Add(dropdown.value.ToString());
- }
-
- // pass surface inputs through
- arguments.Add(inputVariableName);
-
- foreach (var outSlot in asset.outputs)
- arguments.Add(GetVariableNameForSlot(outSlot.id));
-
- foreach (var feedbackSlot in asset.vtFeedbackVariables)
- {
- string feedbackVar = GetVariableNameForNode() + "_" + feedbackSlot;
- sb.AppendLine("{0} {1};", ConcreteSlotValueType.Vector4.ToShaderString(ConcretePrecision.Single), feedbackVar);
- arguments.Add(feedbackVar);
- }
-
- sb.TryAppendIndentation();
- sb.Append(asset.functionName);
- sb.Append("(");
- bool firstArg = true;
- foreach (var arg in arguments)
- {
- if (!firstArg)
- sb.Append(", ");
- firstArg = false;
- sb.Append(arg);
- }
- sb.Append(");");
- sb.AppendNewLine();
- }
-
- public void OnEnable()
- {
- UpdateSlots();
- }
-
- public bool Reload(HashSet<string> changedFileDependencyGUIDs)
- {
- if (!changedFileDependencyGUIDs.Contains(subGraphGuid))
- {
- return false;
- }
-
- if (asset == null)
- {
- // asset missing or deleted
- return true;
- }
-
- if (changedFileDependencyGUIDs.Contains(asset.assetGuid) || asset.descendents.Any(changedFileDependencyGUIDs.Contains))
- {
- m_SubGraph = null;
- UpdateSlots();
-
- if (hasError)
- {
- return true;
- }
-
- owner.ClearErrorsForNode(this);
- ValidateNode();
- Dirty(ModificationScope.Graph);
- }
-
- return true;
- }
-
- public override void UpdatePrecision(List<MaterialSlot> inputSlots)
- {
- if (asset != null)
- {
- if (asset.subGraphGraphPrecision == GraphPrecision.Graph)
- {
- // subgraph is defined to be switchable, so use the default behavior to determine precision
- base.UpdatePrecision(inputSlots);
- }
- else
- {
- // subgraph sets a specific precision, force that
- graphPrecision = asset.subGraphGraphPrecision;
- concretePrecision = graphPrecision.ToConcrete(owner.graphDefaultConcretePrecision);
- }
- }
- else
- {
- // no subgraph asset; use default behavior
- base.UpdatePrecision(inputSlots);
- }
- }
-
- public virtual void UpdateSlots()
- {
- var validNames = new List<int>();
- if (asset == null)
- {
- return;
- }
-
- var props = asset.inputs;
- var toFix = new HashSet<(SlotReference from, SlotReference to)>();
- foreach (var prop in props)
- {
- SlotValueType valueType = prop.concreteShaderValueType.ToSlotValueType();
- var propertyString = prop.guid.ToString();
- var propertyIndex = m_PropertyGuids.IndexOf(propertyString);
- if (propertyIndex < 0)
- {
- propertyIndex = m_PropertyGuids.Count;
- m_PropertyGuids.Add(propertyString);
- m_PropertyIds.Add(prop.guid.GetHashCode());
- }
- var id = m_PropertyIds[propertyIndex];
-
- //for whatever reason, it seems like shader property ids changed between 21.2a17 and 21.2b1
- //tried tracking it down, couldnt find any reason for it, so we gotta fix it in post (after we deserialize)
- List<MaterialSlot> inputs = new List<MaterialSlot>();
- MaterialSlot found = null;
- GetInputSlots(inputs);
- foreach (var input in inputs)
- {
- if (input.shaderOutputName == prop.referenceName && input.id != id)
- {
- found = input;
- break;
- }
- }
-
- MaterialSlot slot = MaterialSlot.CreateMaterialSlot(valueType, id, prop.displayName, prop.referenceName, SlotType.Input, Vector4.zero, ShaderStageCapability.All);
-
- // Copy defaults
- switch (prop.concreteShaderValueType)
- {
- case ConcreteSlotValueType.SamplerState:
- {
- var tSlot = slot as SamplerStateMaterialSlot;
- var tProp = prop as SamplerStateShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.defaultSamplerState = tProp.value;
- }
- break;
- case ConcreteSlotValueType.Matrix4:
- {
- var tSlot = slot as Matrix4MaterialSlot;
- var tProp = prop as Matrix4ShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.value = tProp.value;
- }
- break;
- case ConcreteSlotValueType.Matrix3:
- {
- var tSlot = slot as Matrix3MaterialSlot;
- var tProp = prop as Matrix3ShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.value = tProp.value;
- }
- break;
- case ConcreteSlotValueType.Matrix2:
- {
- var tSlot = slot as Matrix2MaterialSlot;
- var tProp = prop as Matrix2ShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.value = tProp.value;
- }
- break;
- case ConcreteSlotValueType.Texture2D:
- {
- var tSlot = slot as Texture2DInputMaterialSlot;
- var tProp = prop as Texture2DShaderProperty;
- if (tSlot != null && tProp != null)
-
- tSlot.texture = tProp.value.texture;
- }
- break;
- case ConcreteSlotValueType.Texture2DArray:
- {
- var tSlot = slot as Texture2DArrayInputMaterialSlot;
- var tProp = prop as Texture2DArrayShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.textureArray = tProp.value.textureArray;
- }
- break;
- case ConcreteSlotValueType.Texture3D:
- {
- var tSlot = slot as Texture3DInputMaterialSlot;
- var tProp = prop as Texture3DShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.texture = tProp.value.texture;
- }
- break;
- case ConcreteSlotValueType.Cubemap:
- {
- var tSlot = slot as CubemapInputMaterialSlot;
- var tProp = prop as CubemapShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.cubemap = tProp.value.cubemap;
- }
- break;
- case ConcreteSlotValueType.Gradient:
- {
- var tSlot = slot as GradientInputMaterialSlot;
- var tProp = prop as GradientShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.value = tProp.value;
- }
- break;
- case ConcreteSlotValueType.Vector4:
- {
- var tSlot = slot as Vector4MaterialSlot;
- var vector4Prop = prop as Vector4ShaderProperty;
- var colorProp = prop as ColorShaderProperty;
- if (tSlot != null && vector4Prop != null)
- tSlot.value = vector4Prop.value;
- else if (tSlot != null && colorProp != null)
- tSlot.value = colorProp.value;
- }
- break;
- case ConcreteSlotValueType.Vector3:
- {
- var tSlot = slot as Vector3MaterialSlot;
- var tProp = prop as Vector3ShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.value = tProp.value;
- }
- break;
- case ConcreteSlotValueType.Vector2:
- {
- var tSlot = slot as Vector2MaterialSlot;
- var tProp = prop as Vector2ShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.value = tProp.value;
- }
- break;
- case ConcreteSlotValueType.Vector1:
- {
- var tSlot = slot as Vector1MaterialSlot;
- var tProp = prop as Vector1ShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.value = tProp.value;
- }
- break;
- case ConcreteSlotValueType.Boolean:
- {
- var tSlot = slot as BooleanMaterialSlot;
- var tProp = prop as BooleanShaderProperty;
- if (tSlot != null && tProp != null)
- tSlot.value = tProp.value;
- }
- break;
- }
-
- AddSlot(slot);
- validNames.Add(id);
-
- if (found != null)
- {
- List<IEdge> edges = new List<IEdge>();
- owner.GetEdges(found.slotReference, edges);
- foreach (var edge in edges)
- {
- toFix.Add((edge.outputSlot, slot.slotReference));
- }
- }
- }
-
- foreach (var slot in asset.outputs)
- {
- var outputStage = GetSlotCapability(slot);
- var newSlot = MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(),
- slot.shaderOutputName, SlotType.Output, Vector4.zero, outputStage, slot.hidden);
- AddSlot(newSlot);
- validNames.Add(slot.id);
- }
-
- RemoveSlotsNameNotMatching(validNames, true);
-
- // sort slot order to match subgraph property order
- SetSlotOrder(validNames);
-
- foreach (var (from, to) in toFix)
- {
- //for whatever reason, in this particular error fix, GraphView will incorrectly either add two edgeViews or none
- //but it does work correctly if we dont notify GraphView of this added edge. Gross.
- owner.UnnotifyAddedEdge(owner.Connect(from, to));
- }
- }
-
- void ValidateShaderStage()
- {
- if (asset != null)
- {
- List<MaterialSlot> slots = new List<MaterialSlot>();
- GetInputSlots(slots);
- GetOutputSlots(slots);
-
- foreach (MaterialSlot slot in slots)
- slot.stageCapability = GetSlotCapability(slot);
- }
- }
-
- public override void ValidateNode()
- {
- base.ValidateNode();
-
- if (asset == null)
- {
- hasError = true;
- var assetGuid = subGraphGuid;
- var assetPath = string.IsNullOrEmpty(subGraphGuid) ? null : AssetDatabase.GUIDToAssetPath(assetGuid);
- if (string.IsNullOrEmpty(assetPath))
- {
- owner.AddValidationError(objectId, $"Could not find Sub Graph asset with GUID {assetGuid}.");
- }
- else
- {
- owner.AddValidationError(objectId, $"Could not load Sub Graph asset at \"{assetPath}\" with GUID {assetGuid}.");
- }
-
- return;
- }
-
- if (owner.isSubGraph && (asset.descendents.Contains(owner.assetGuid) || asset.assetGuid == owner.assetGuid))
- {
- hasError = true;
- owner.AddValidationError(objectId, $"Detected a recursion in Sub Graph asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}.");
- }
- else if (!asset.isValid)
- {
- hasError = true;
- owner.AddValidationError(objectId, $"Sub Graph has errors, asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}.");
- }
- else if (!owner.isSubGraph && owner.activeTargets.Any(x => asset.unsupportedTargets.Contains(x)))
- {
- SetOverrideActiveState(ActiveState.ExplicitInactive);
- owner.AddValidationError(objectId, $"Sub Graph contains nodes that are unsupported by the current active targets, asset at \"{AssetDatabase.GUIDToAssetPath(subGraphGuid)}\" with GUID {subGraphGuid}.");
- }
-
- // detect disconnected VT properties, and VT layer count mismatches
- foreach (var paramProp in asset.inputs)
- {
- if (paramProp is VirtualTextureShaderProperty vtProp)
- {
- int paramLayerCount = vtProp.value.layers.Count;
-
- var argSlotId = m_PropertyIds[m_PropertyGuids.IndexOf(paramProp.guid.ToString())]; // yikes
- if (!IsSlotConnected(argSlotId))
- {
- owner.AddValidationError(objectId, $"A VirtualTexture property must be connected to the input slot \"{paramProp.displayName}\"");
- }
- else
- {
- var argProp = GetSlotProperty(argSlotId) as VirtualTextureShaderProperty;
- if (argProp != null)
- {
- int argLayerCount = argProp.value.layers.Count;
-
- if (argLayerCount != paramLayerCount)
- owner.AddValidationError(objectId, $"Input \"{paramProp.displayName}\" has different number of layers from the connected property \"{argProp.displayName}\"");
- }
- else
- {
- owner.AddValidationError(objectId, $"Input \"{paramProp.displayName}\" is not connected to a valid VirtualTexture property");
- }
- }
-
- break;
- }
- }
-
- ValidateShaderStage();
- }
-
- public override void CollectShaderProperties(PropertyCollector visitor, GenerationMode generationMode)
- {
- base.CollectShaderProperties(visitor, generationMode);
-
- if (asset == null)
- return;
-
- foreach (var property in asset.nodeProperties)
- {
- visitor.AddShaderProperty(property);
- }
- }
-
- public AbstractShaderProperty GetShaderProperty(int id)
- {
- var index = m_PropertyIds.IndexOf(id);
- if (index >= 0)
- {
- var guid = m_PropertyGuids[index];
- return asset?.inputs.Where(x => x.guid.ToString().Equals(guid)).FirstOrDefault();
- }
- return null;
- }
-
- public void CollectShaderKeywords(KeywordCollector keywords, GenerationMode generationMode)
- {
- if (asset == null)
- return;
-
- foreach (var keyword in asset.keywords)
- {
- keywords.AddShaderKeyword(keyword as ShaderKeyword);
- }
- }
-
- public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
- {
- base.CollectPreviewMaterialProperties(properties);
-
- if (asset == null)
- return;
-
- foreach (var property in asset.nodeProperties)
- {
- properties.Add(property.GetPreviewMaterialProperty());
- }
- }
-
- public virtual void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
- {
- if (asset == null || hasError)
- return;
-
- registry.RequiresIncludes(asset.includes);
-
- var graphData = registry.builder.currentNode.owner;
- var graphDefaultConcretePrecision = graphData.graphDefaultConcretePrecision;
-
- foreach (var function in asset.functions)
- {
- var name = function.key;
- var source = function.value;
- var graphPrecisionFlags = function.graphPrecisionFlags;
-
- // the subgraph may use multiple precision variants of this function internally
- // here we iterate through all the requested precisions and forward those requests out to the graph
- for (int requestedGraphPrecision = 0; requestedGraphPrecision <= (int)GraphPrecision.Half; requestedGraphPrecision++)
- {
- // only provide requested precisions
- if ((graphPrecisionFlags & (1 << requestedGraphPrecision)) != 0)
- {
- // when a function coming from a subgraph asset has a graph precision of "Graph",
- // that means it is up to the subgraph NODE to decide (i.e. us!)
- GraphPrecision actualGraphPrecision = (GraphPrecision)requestedGraphPrecision;
-
- // subgraph asset setting falls back to this node setting (when switchable)
- actualGraphPrecision = actualGraphPrecision.GraphFallback(this.graphPrecision);
-
- // which falls back to the graph default concrete precision
- ConcretePrecision actualConcretePrecision = actualGraphPrecision.ToConcrete(graphDefaultConcretePrecision);
-
- // forward the function into the current graph
- registry.ProvideFunction(name, actualGraphPrecision, actualConcretePrecision, sb => sb.AppendLines(source));
- }
- }
- }
- }
-
- public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return NeededCoordinateSpace.None;
-
- return asset.requirements.requiresNormal;
- }
-
- public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresMeshUVs.Contains(channel);
- }
-
- public bool RequiresScreenPosition(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresScreenPosition;
- }
-
- public bool RequiresNDCPosition(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresNDCPosition;
- }
-
- public bool RequiresPixelPosition(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresPixelPosition;
- }
-
- public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return NeededCoordinateSpace.None;
-
- return asset.requirements.requiresViewDir;
- }
-
- public NeededCoordinateSpace RequiresPosition(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return NeededCoordinateSpace.None;
-
- return asset.requirements.requiresPosition;
- }
-
- public NeededCoordinateSpace RequiresPositionPredisplacement(ShaderStageCapability stageCapability = ShaderStageCapability.All)
- {
- if (asset == null)
- return NeededCoordinateSpace.None;
-
- return asset.requirements.requiresPositionPredisplacement;
- }
-
- public NeededCoordinateSpace RequiresTangent(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return NeededCoordinateSpace.None;
-
- return asset.requirements.requiresTangent;
- }
-
- public bool RequiresTime()
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresTime;
- }
-
- public bool RequiresFaceSign(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresFaceSign;
- }
-
- public NeededCoordinateSpace RequiresBitangent(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return NeededCoordinateSpace.None;
-
- return asset.requirements.requiresBitangent;
- }
-
- public bool RequiresVertexColor(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresVertexColor;
- }
-
- public bool RequiresCameraOpaqueTexture(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresCameraOpaqueTexture;
- }
-
- public bool RequiresDepthTexture(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresDepthTexture;
- }
-
- public bool RequiresVertexSkinning(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresVertexSkinning;
- }
-
- public bool RequiresVertexID(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresVertexID;
- }
-
- public bool RequiresInstanceID(ShaderStageCapability stageCapability)
- {
- if (asset == null)
- return false;
-
- return asset.requirements.requiresInstanceID;
- }
-
- public string GetDropdownEntryName(string referenceName)
- {
- var index = m_Dropdowns.IndexOf(referenceName);
- return index >= 0 ? m_DropdownSelectedEntries[index] : string.Empty;
- }
-
- public void SetDropdownEntryName(string referenceName, string value)
- {
- var index = m_Dropdowns.IndexOf(referenceName);
- if (index >= 0)
- {
- m_DropdownSelectedEntries[index] = value;
- }
- else
- {
- m_Dropdowns.Add(referenceName);
- m_DropdownSelectedEntries.Add(value);
- }
- }
-
- public override void Dispose()
- {
- base.Dispose();
- m_SubGraph = null;
- }
- }
- }
|