浏览代码

[shader graph]Data refactor begins.

/main
Tim Cooper 8 年前
当前提交
51415775
共有 9 个文件被更改,包括 431 次插入355 次删除
  1. 150
      UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs
  2. 28
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/BaseLightFunction.cs
  3. 6
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/SimpleSpecularFunction.cs
  4. 6
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/WrapLambertFunction.cs
  5. 275
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs
  6. 127
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SlotValue.cs
  7. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs
  8. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/PixelGraph.cs
  9. 190
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Slot.cs

150
UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs


using System;
using System.Collections.Generic;
using UnityEditor.Graphs;
public abstract class BaseMaterialGraph : Graph
[Serializable]
public class SlotReference
{
[SerializeField]
private string m_NodeGUIDSerialized;
[NonSerialized]
private GUID m_NodeGUID;
[SerializeField]
private string m_SlotName;
public SlotReference(GUID nodeGuid, string slotName)
{
m_NodeGUID = nodeGuid;
m_SlotName = slotName;
}
public GUID nodeGuid
{
get { return m_NodeGUID; }
}
public string slotName
{
get { return m_SlotName; }
}
public void BeforeSerialize()
{
m_NodeGUIDSerialized = m_NodeGUID.ToString();
}
public void AfterDeserialize()
{
m_NodeGUID = new GUID(m_NodeGUIDSerialized);
}
}
[Serializable]
public class Edge
{
[SerializeField]
private SlotReference m_OutputSlot;
[SerializeField]
private SlotReference m_InputSlot;
public Edge(SlotReference outputSlot, SlotReference inputSlot)
{
m_OutputSlot = outputSlot;
m_InputSlot = inputSlot;
}
public SlotReference outputSlot
{
get { return m_OutputSlot; }
}
public SlotReference inputSlot
{
get { return m_InputSlot; }
}
}
public abstract class BaseMaterialGraph
public PreviewRenderUtility previewUtility
{
get

m_PreviewUtility = new PreviewRenderUtility();
EditorUtility.SetCameraAnimateMaterials(m_PreviewUtility.m_Camera, true);
// EditorUtility.SetCameraAnimateMaterials(m_PreviewUtility.m_Camera, true);
}
return m_PreviewUtility;

private List<BaseMaterialNode> m_Nodes = new List<BaseMaterialNode>();
private List<Edge> m_Edges = new List<Edge>();
protected List<BaseMaterialNode> nodes
{
get
{
return m_Nodes;
}
}
get { return isAwake && nodes.Any(x => x is IRequiresTime); }
get { return nodes.Any(x => x is IRequiresTime); }
public override void RemoveEdge(Edge e)
public void RemoveEdge(Edge e)
base.RemoveEdge(e);
m_Edges.Remove(e);
base.RemoveEdge(e);
m_Edges.Remove(e);
public override void RemoveNode(Node node, bool destroyNode = false)
public void RemoveNode(BaseMaterialNode node)
if (node is BaseMaterialNode)
{
if (!((BaseMaterialNode) node).canDeleteNode)
return;
}
base.RemoveNode(node, destroyNode);
if (!node.canDeleteNode)
return;
m_Nodes.Remove(node);
}
public BaseMaterialNode GetNodeFromGUID(GUID guid)
{
return m_Nodes.FirstOrDefault(x => x.guid == guid);
}
public IEnumerable<Edge> GetEdges(Slot s)
{
return m_Edges.Where(x =>
(x.outputSlot.nodeGuid == s.nodeGuid && x.outputSlot.slotName == s.name)
|| x.inputSlot.nodeGuid == s.nodeGuid && x.inputSlot.slotName == s.name);
public override Edge Connect(Slot fromSlot, Slot toSlot)
public Edge Connect(Slot fromSlot, Slot toSlot)
{
Slot outputSlot = null;
Slot inputSlot = null;

return null;
// remove any inputs that exits before adding
foreach (var edge in inputSlot.edges.ToArray())
foreach (var edge in GetEdges(inputSlot))
base.RemoveEdge(edge);
RemoveEdge(edge);
var newEdge = base.Connect(outputSlot, inputSlot);
var newEdge = new Edge(new SlotReference(outputSlot.nodeGuid, outputSlot.name), new SlotReference(inputSlot.nodeGuid, inputSlot.name));
m_Edges.Add(newEdge);
var toNode = inputSlot.node as BaseMaterialNode;
var fromNode = outputSlot.node as BaseMaterialNode;
if (fromNode == null || toNode == null)
return newEdge;
RevalidateGraph();
return newEdge;
}

}
}
public override void AddNode(Node node)
public void AddNode(BaseMaterialNode node)
base.AddNode(node);
AssetDatabase.AddObjectToAsset(node, this);
m_Nodes.Add(node);
}
public void AddNodeNoValidate(Node node)
{
base.AddNode(node);
AssetDatabase.AddObjectToAsset(node, this);
}
protected void AddMasterNodeNoAddToAsset(Node node)
{
base.AddNode(node);
}
}
}

28
UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/BaseLightFunction.cs


public override string GetSurfaceOutputStructureName() { return "SurfaceOutputStandard"; }
public override void DoSlotsForConfiguration(PixelShaderNode node)
{
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kAlbedoSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kNormalSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kEmissionSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kMetallicSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kSmoothnessSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kOcclusion), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kAlphaSlotName), SlotValueType.Vector1));
node.AddSlot(new Slot(node.guid, kAlbedoSlotName, SlotValueType.Vector3, new SlotValue(), ));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kNormalSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kEmissionSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kMetallicSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kSmoothnessSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kOcclusion), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kAlphaSlotName), SlotValueType.Vector1));
// clear out slot names that do not match the slots
// we support

public override string GetSurfaceOutputStructureName() { return "SurfaceOutputStandardSpecular"; }
public override void DoSlotsForConfiguration(PixelShaderNode node)
{
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kAlbedoSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kNormalSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kSpecularSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kEmissionSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kSmoothnessSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kOcclusion), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kAlphaSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kAlbedoSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kNormalSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kSpecularSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kEmissionSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kSmoothnessSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kOcclusion), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kAlphaSlotName), SlotValueType.Vector1));
// clear out slot names that do not match the slots
// we support

6
UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/SimpleSpecularFunction.cs


public override void DoSlotsForConfiguration(PixelShaderNode node)
{
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kAlbedoSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kNormalSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kAlphaSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kAlbedoSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kNormalSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kAlphaSlotName), SlotValueType.Vector1));
// clear out slot names that do not match the slots
// we support

6
UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/WrapLambertFunction.cs


public override void DoSlotsForConfiguration(PixelShaderNode node)
{
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kAlbedoSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kNormalSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kAlphaSlotName), SlotValueType.Vector1));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kAlbedoSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kNormalSlotName), SlotValueType.Vector3));
node.AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.InputSlot, slotType: kAlphaSlotName), SlotValueType.Vector1));
// clear out slot names that do not match the slots
// we support

275
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs


using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor.Graphs;
using UnityEditorInternal;
using UnityEngine;

Collapsed
}
[Serializable]
class SlotDefaultValueKVP
public abstract class BaseMaterialNode : IGenerateProperties, ISerializationCallbackReceiver
[SerializeField]
public string slotName;
#region Fields
private const int kPreviewWidth = 64;
private const int kPreviewHeight = 64;
[NonSerialized]
private GUID m_GUID;
public SlotValue value;
private string m_GUIDSerialzied;
public SlotDefaultValueKVP(string slotName, SlotValue value)
public GUID guid
this.slotName = slotName;
this.value = value;
get
{
return m_GUID;
}
}
public struct MaterialGraphSlot
{
public Slot slot;
public SlotValueType valueType;
public MaterialGraphSlot(Slot slot, SlotValueType valueType)
private string m_Name;
public string name
this.slot = slot;
this.valueType = valueType;
get { return name; }
public override string ToString()
{
return string.Format("{0} - {1} - {2}", slot.name, slot.isInputSlot, valueType);
}
}
public abstract class BaseMaterialNode : Node, IGenerateProperties
{
public BaseMaterialGraph owner { private get; set; }
#region Fields
private const int kPreviewWidth = 64;
private const int kPreviewHeight = 64;
private List<SlotDefaultValueKVP> m_SlotDefaultValues;
private List<Slot> m_Slots = new List<Slot>();
[SerializeField]
private string m_GUID = string.Empty;
private IEnumerable<Slot> inputSlots
{
get { return m_Slots.Where(x => x.isInputSlot); }
}
protected string guid
private IEnumerable<Slot> outputSlots
get
{
if (string.IsNullOrEmpty(m_GUID))
{
var newGUID = Guid.NewGuid();
m_GUID = newGUID.ToString("N");
}
return m_GUID;
}
get { return m_Slots.Where(x => x.isOutputSlot); }
}
[SerializeField]

onNeedsRepaint();
}
private readonly Dictionary<string, SlotValueType> m_SlotValueTypes = new Dictionary<string, SlotValueType>();
private readonly Dictionary<string, ConcreteSlotValueType> m_ConcreteInputSlotValueTypes = new Dictionary<string, ConcreteSlotValueType>();
private readonly Dictionary<string, ConcreteSlotValueType> m_ConcreteOutputSlotValueTypes = new Dictionary<string, ConcreteSlotValueType>();
[NonSerialized]
private Dictionary<string, SlotValueType> m_SlotValueTypes = new Dictionary<string, SlotValueType>();
[NonSerialized]
private Dictionary<string, ConcreteSlotValueType> m_ConcreteInputSlotValueTypes = new Dictionary<string, ConcreteSlotValueType>();
[NonSerialized]
private Dictionary<string, ConcreteSlotValueType> m_ConcreteOutputSlotValueTypes = new Dictionary<string, ConcreteSlotValueType>();
internal PixelGraph pixelGraph { get { return graph as PixelGraph; } }
public bool generated { get; set; }
// Nodes that want to have a preview area can override this and return true
public virtual bool hasPreview { get { return false; } }
public virtual PreviewMode previewMode { get { return PreviewMode.Preview2D; } }

get { return m_DrawMode; }
set { m_DrawMode = value; }
}
public bool isSelected { get; set; }
// lookup custom slot properties
public void SetSlotDefaultValue(string slotName, SlotValue defaultValue)
{
m_SlotDefaultValues.RemoveAll(x => x.slotName == slotName);
if (defaultValue == null)
return;
m_SlotDefaultValues.Add(new SlotDefaultValueKVP(slotName, defaultValue));
}
protected void SetSlotDefaultValueType(string slot, SlotValueType slotType)
{
if (string.IsNullOrEmpty(slot))
return;
if (m_SlotValueTypes.ContainsKey(slot))
m_SlotValueTypes[slot] = slotType;
else
m_SlotValueTypes.Add(slot, slotType);
}
public string precision
{
get { return "half"; }
}
public string[] m_PrecisionNames = {"half"};
public SlotValue GetSlotDefaultValue(string slotName)
{
var found = m_SlotDefaultValues.FirstOrDefault(x => x.slotName == slotName);
return found != null ? found.value : null;
}
[SerializeField]
private string m_LastShader;

#endregion
public virtual void OnCreate()
{
hideFlags = HideFlags.HideInHierarchy;
}
public virtual void OnEnable()
{
if (m_SlotDefaultValues == null)
{
m_SlotDefaultValues = new List<SlotDefaultValueKVP>();
}
}
public virtual float GetNodeUIHeight(float width)
{
return 0;

// order you can generate a valid code block.
public List<BaseMaterialNode> CollectChildNodesByExecutionOrder(List<BaseMaterialNode> nodeList, Slot slotToUse = null, bool includeSelf = true)
{
if (slotToUse != null && !slots.Contains(slotToUse))
if (slotToUse != null && !m_Slots.Contains(slotToUse))
{
Debug.LogError("Attempting to collect nodes by execution order with an invalid slot on: " + name);
return nodeList;

// if we are now valid
if (m_PreviewShader && ShaderHasError(m_PreviewShader))
{
DestroyImmediate(m_PreviewShader, true);
DestroyImmediate(m_PreviewMaterial, true);
UnityEngine.Object.DestroyImmediate(m_PreviewShader, true);
UnityEngine.Object.DestroyImmediate(m_PreviewMaterial, true);
m_PreviewShader = null;
m_PreviewMaterial = null;
}

public virtual void GetValidInputSlots(List<Slot> slotsToFill)
{
for (int i = 0; i < slots.Count; ++i)
for (int i = 0; i < m_Slots.Count; ++i)
var slot = slots[i];
if (slot != null && slot.isInputSlot)
var slot = m_Slots[i];
if (slot != null && slot.slotType == Slot.SlotType.Input)
slotsToFill.Add(slot);
}
}

if (s.isInputSlot) Debug.LogError("Attempting to use input slot (" + s + ") for output!");
if (!slots.Contains(s)) Debug.LogError("Attempting to use slot (" + s + ") for output on a node that does not have this slot!");
if (s.slotType == Slot.SlotType.Input) Debug.LogError("Attempting to use input slot (" + s + ") for output!");
if (!m_Slots.Contains(s)) Debug.LogError("Attempting to use slot (" + s + ") for output on a node that does not have this slot!");
return GetOutputVariableNameForNode() + "_" + s.name;
}

return Vector4.one;
}
[Obsolete ("This call is not supported for Material Graph. Use: AddSlot(MaterialGraphSlot mgSlot)", true)]
public new void AddSlot(Slot slot)
public void AddSlot(Slot slot)
throw new NotSupportedException("Material graph requires the use of: AddSlot(MaterialGraphSlot mgSlot)");
}
public void AddSlot(MaterialGraphSlot mgSlot)
{
if (mgSlot.slot == null)
if (slot == null)
return;
// new slot, just add it, we cool
if (!m_Slots.Contains(slot))
{
m_Slots.Add(slot);
var slot = mgSlot.slot;
}
if (this[slot.name] == null)
// old slot found
// update the default value, and the slotType!
var foundSlots = m_Slots.FindAll(x => x.name == slot.name);
// if we are in a bad state (> 1 slot with same name, just reset).
if (foundSlots.Count > 1)
base.AddSlot(slot);
Debug.LogWarningFormat("Node {0} has more than one slot with the same name, removing.");
foundSlots.ForEach(x => m_Slots.Remove(x));
m_Slots.Add(slot);
return;
var slotValue = GetSlotDefaultValue(slot.name);
if (slotValue == null || !slotValue.IsValid())
SetSlotDefaultValue(slot.name, new SlotValue(this, slot.name, GetNewSlotDefaultValue(mgSlot.valueType)));
var foundSlot = foundSlots[0];
// if the defualt and current are the same, change the current
// to the new default.
if (foundSlot.defaultValue == foundSlot.currentValue)
foundSlot.currentValue = slot.defaultValue;
SetSlotDefaultValueType(slot.name, mgSlot.valueType);
foundSlot.defaultValue = slot.defaultValue;
foundSlot.valueType = slot.valueType;
public override void RemoveSlot(Slot slot)
public void RemoveSlot(string name)
SetSlotDefaultValue(slot.name, null);
base.RemoveSlot(slot);
m_Slots.RemoveAll(x => x.name == name);
public string GenerateSlotName(SlotType type)
public string GenerateSlotName(Slot.SlotType type)
var slotsToCheck = type == SlotType.InputSlot ? inputSlots.ToArray() : outputSlots.ToArray();
string format = type == SlotType.InputSlot ? "I{0:00}" : "O{0:00}";
int index = slotsToCheck.Length;
var slotsToCheck = type == Slot.SlotType.Input ? inputSlots.ToArray() : outputSlots.ToArray();
string format = type == Slot.SlotType.Input ? "I{0:00}" : "O{0:00}";
int index = slotsToCheck.Count();
var slotName = string.Format(format, index);
if (slotsToCheck.All(x => x.name != slotName))
return slotName;

foreach (var inputSlot in inputSlots)
{
if (inputSlot.edges.Count > 0)
var edges = owner.GetEdges(inputSlot);
if (edges.Any())
var defaultForSlot = GetSlotDefaultValue(inputSlot.name);
if (defaultForSlot != null)
defaultForSlot.GeneratePropertyUsages(visitor, generationMode, concreteInputSlotValueTypes[inputSlot.name]);
inputSlot.GeneratePropertyUsages(visitor, generationMode, concreteInputSlotValueTypes[inputSlot.name], this);
var slot = inputSlots.FirstOrDefault(x => x.name == name);
var slot = m_Slots.FirstOrDefault(x => x.isInputSlot && x.name == name);
if (slot == null)
Debug.LogError("Input slot: " + name + " could be found on node " + GetOutputVariableNameForNode());
return slot;

{
var slot = outputSlots.FirstOrDefault(x => x.name == name);
var slot = m_Slots.FirstOrDefault(x => x.isOutputSlot && x.name == name);
if (slot == null)
Debug.LogError("Output slot: " + name + " could be found on node " + GetOutputVariableNameForNode());
return slot;

{
bool pointInputConnected = inputSlot.edges.Count > 0;
string inputValue;
if (pointInputConnected)
{
inputValue = ShaderGenerator.AdaptNodeOutput(inputSlot.edges[0].fromSlot, generationMode, concreteInputSlotValueTypes[inputSlot.name]);
}
else
var edges = owner.GetEdges(inputSlot).ToArray();
if (edges.Length > 0)
var defaultValue = GetSlotDefaultValue(inputSlot.name);
inputValue = defaultValue.GetDefaultValue(generationMode, concreteInputSlotValueTypes[inputSlot.name]);
var fromSocketRef = edges[0].outputSlot;
var fromNode = owner.GetNodeFromGUID(fromSocketRef.nodeGuid);
var slot = fromNode.FindOutputSlot(fromSocketRef.slotName);
return ShaderGenerator.AdaptNodeOutput(slot, generationMode, concreteInputSlotValueTypes[inputSlot.name]);
return inputValue;
return inputSlot.GetDefaultValue(generationMode, concreteInputSlotValueTypes[inputSlot.name], this);
var invalidSlots = slots.Select(x => x.name).Except(slotNames);
var invalidSlots = m_Slots.Select(x => x.name).Except(slotNames);
RemoveSlot(this[invalidSlot]);
}
var invalidSlotDefaults = m_SlotDefaultValues.Select(x => x.slotName).Except(slotNames);
foreach (var invalidSlot in invalidSlotDefaults.ToList())
{
Debug.LogWarningFormat("Removing Invalid Slot Default: {0}", invalidSlot);
m_SlotDefaultValues.RemoveAll(x => x.slotName == invalidSlot);
RemoveSlot(invalidSlot);
}
}

// so do that here
foreach (var inputSlot in inputSlots)
{
foreach (var edge in inputSlot.edges)
var edges = owner.GetEdges(inputSlot);
foreach (var edge in edges)
var outputSlot = edge.fromSlot;
var outputNode = (BaseMaterialNode) outputSlot.node;
var fromSocketRef = edge.outputSlot;
var outputNode = owner.GetNodeFromGUID(fromSocketRef.nodeGuid);
isInError |= true;
isInError = true;
}
}

{
var inputType = m_SlotValueTypes[inputSlot.name];
// if there is a connection
if (inputSlot.edges.Count == 0)
var edges = owner.GetEdges(inputSlot).ToList();
if (!edges.Any())
{
if (inputType != SlotValueType.Dynamic)
m_ConcreteInputSlotValueTypes.Add(inputSlot.name, ToConcreteType(inputType));

}
// get the output details
var outputSlot = inputSlot.edges[0].fromSlot;
var outputNode = (BaseMaterialNode) outputSlot.node;
var outputSlotRef = edges[0].outputSlot;
var outputNode = owner.GetNodeFromGUID(outputSlotRef.nodeGuid);
var outputSlot = outputNode.FindOutputSlot(outputSlotRef.slotName);
var outputConcreteType = outputNode.GetConcreteOutputSlotValueType(outputSlot);
// if we have a standard connection... just check the types work!

dynamicInputSlotsToCompare.Add(inputSlot.name, outputConcreteType);
}
// we can now figure out the dynamic type
// we can now figure out the dynamic slotType
// from here set all the
var dynamicType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
foreach (var dynamicKvP in dynamicInputSlotsToCompare)

bool inputError = m_ConcreteInputSlotValueTypes.Any(x => x.Value == ConcreteSlotValueType.Error);
// configure the output slots now
// their type will either be the default output type
// or the above dynanic type for dynamic nodes
// or error if there is an input erro
// their slotType will either be the default output slotType
// or the above dynanic slotType for dynamic nodes
// or error if there is an input error
foreach (var outputSlot in outputSlots)
{
if (inputError)

{
return inputSlots.Where(x => x.edges.Count == 0);
}
public abstract void OnBeforeSerialize();
public abstract void OnAfterDeserialize();
}
public enum GUIModificationType

127
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SlotValue.cs


Vector1 = 1,
Error = 0
}
[Serializable]
public class SlotValue : IGenerateProperties
{
[SerializeField]
private Vector4 m_DefaultVector;
public Vector4 defaultValue
{
get { return m_DefaultVector; }
}
[SerializeField]
private string m_SlotName;
public string slotName
{
get { return m_SlotName; }
}
[SerializeField]
private BaseMaterialNode m_Node;
public string nodeName
{
get { return m_Node.GetOutputVariableNameForNode(); }
}
public SlotValue(BaseMaterialNode node, string slotName, Vector4 value)
{
m_DefaultVector = value;
m_SlotName = slotName;
m_Node = node;
}
public bool IsValid()
{
return !string.IsNullOrEmpty(m_SlotName) && m_Node != null;
}
public void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
{
// no need to generate a property block.
// we can just set the uniforms.
}
public string inputName
{
get { return nodeName + "_" + slotName; }
}
public void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
{
if (!generationMode.IsPreview())
return;
visitor.AddShaderChunk("float" + BaseMaterialNode.ConvertConcreteSlotValueTypeToString(slotValueType) + " " + inputName + ";", true);
}
public string GetDefaultValue(GenerationMode generationMode, ConcreteSlotValueType slotValueType)
{
if (generationMode.IsPreview())
return inputName;
switch (slotValueType)
{
case ConcreteSlotValueType.Vector1:
return m_DefaultVector.x.ToString();
case ConcreteSlotValueType.Vector2:
return "half2 (" + m_DefaultVector.x + "," + m_DefaultVector.y + ")";
case ConcreteSlotValueType.Vector3:
return "half3 (" + m_DefaultVector.x + "," + m_DefaultVector.y + "," + m_DefaultVector.z + ")";
case ConcreteSlotValueType.Vector4:
return "half4 (" + m_DefaultVector.x + "," + m_DefaultVector.y + "," + m_DefaultVector.z + "," + m_DefaultVector.w + ")";
default:
return "error";
}
}
public bool OnGUI()
{
EditorGUI.BeginChangeCheck();
m_DefaultVector = EditorGUILayout.Vector4Field("Value", m_DefaultVector);
return EditorGUI.EndChangeCheck();
}
public bool OnGUI(Rect rect, ConcreteSlotValueType inputSlotType)
{
EditorGUI.BeginChangeCheck();
var rectXmax = rect.xMax;
switch (inputSlotType)
{
case ConcreteSlotValueType.Vector1:
rect.x = rectXmax - 50;
rect.width = 50;
EditorGUIUtility.labelWidth = 15;
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
m_DefaultVector.x = EditorGUI.FloatField(rect, "X", m_DefaultVector.x);
break;
case ConcreteSlotValueType.Vector2:
rect.x = rectXmax - 90;
rect.width = 90;
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
var result2 = new Vector4(m_DefaultVector.x, m_DefaultVector.y);
result2 = EditorGUI.Vector2Field(rect, GUIContent.none, result2);
m_DefaultVector.x = result2.x;
m_DefaultVector.y = result2.y;
break;
case ConcreteSlotValueType.Vector3:
rect.x = rectXmax - 140;
rect.width = 140;
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
var result3 = new Vector3(m_DefaultVector.x, m_DefaultVector.y, m_DefaultVector.z);
result3 = EditorGUI.Vector3Field(rect, GUIContent.none, result3);
m_DefaultVector.x = result3.x;
m_DefaultVector.y = result3.y;
m_DefaultVector.z = result3.z;
break;
default:
rect.x = rectXmax - 190;
rect.width = 190;
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
m_DefaultVector = EditorGUI.Vector4Field(rect, GUIContent.none, m_DefaultVector);
break;
}
return EditorGUI.EndChangeCheck();
}
}
}

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs


public override void OnEnable()
{
base.OnEnable();
AddSlot(new MaterialGraphSlot(new Slot(SlotType.OutputSlot, kOutputSlotName), SlotValueType.Vector4));
AddSlot(new MaterialGraphSlot(new Slot(name: SlotType.OutputSlot, slotType: kOutputSlotName), SlotValueType.Vector4));
}
public override PropertyType propertyType

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/PixelGraph.cs


if (m_PixelMasterNode == null)
{
m_PixelMasterNode = CreateInstance<PixelShaderNode>();
m_PixelMasterNode = new PixelShaderNode();
m_PixelMasterNode.OnCreate();
m_PixelMasterNode.position = new Rect(700, m_PixelMasterNode.position.y, m_PixelMasterNode.position.width, m_PixelMasterNode.position.height);
if (addToAsset)

190
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Slot.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public class Slot
{
public enum SlotType
{
Input,
Output
}
[SerializeField]
private string m_Name;
[SerializeField]
private SlotType m_SlotType;
[SerializeField]
private SlotValueType m_ValueType;
[SerializeField]
private Vector4 m_DefaultValue;
[SerializeField]
private Vector4 m_CurrentValue;
[SerializeField]
private string m_NodeGUIDSerialized;
[NonSerialized]
private GUID m_NodeGUID;
public Slot(GUID nodeGuid, string name, SlotType slotType, SlotValueType valueType, Vector4 defaultValue)
{
m_Name = name;
m_SlotType = slotType;
m_ValueType = valueType;
m_DefaultValue = defaultValue;
m_CurrentValue = defaultValue;
m_NodeGUID = nodeGuid;
}
public bool isInputSlot
{
get
{
return m_SlotType == SlotType.Input;
}
}
public bool isOutputSlot
{
get
{
return m_SlotType == SlotType.Output;
}
}
public string name
{
get { return m_Name; }
}
public GUID nodeGuid
{
get { return m_NodeGUID; }
}
public Vector4 defaultValue
{
get { return m_DefaultValue; }
set { m_DefaultValue = value; }
}
public SlotValueType valueType
{
get { return m_ValueType; }
set { m_ValueType = value; }
}
public Vector4 currentValue
{
get { return m_CurrentValue; }
set { m_CurrentValue = value; }
}
public void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
{
// no need to generate a property block.
// we can just set the uniforms.
}
public string GetInputName (string nodeName)
{
return string.Format( "{0}_{1}", nodeName, name);
}
public void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType, BaseMaterialNode owner)
{
if (!generationMode.IsPreview())
return;
visitor.AddShaderChunk("float" + BaseMaterialNode.ConvertConcreteSlotValueTypeToString(slotValueType) + " " + GetInputName(owner.name) + ";", true);
}
public string GetDefaultValue(GenerationMode generationMode, ConcreteSlotValueType slotValueType, BaseMaterialNode owner)
{
if (generationMode.IsPreview())
return GetInputName(owner.name);
switch (slotValueType)
{
case ConcreteSlotValueType.Vector1:
return m_CurrentValue.x.ToString();
case ConcreteSlotValueType.Vector2:
return "half2 (" + m_CurrentValue.x + "," + m_CurrentValue.y + ")";
case ConcreteSlotValueType.Vector3:
return "half3 (" + m_CurrentValue.x + "," + m_CurrentValue.y + "," + m_CurrentValue.z + ")";
case ConcreteSlotValueType.Vector4:
return "half4 (" + m_CurrentValue.x + "," + m_CurrentValue.y + "," + m_CurrentValue.z + "," + m_CurrentValue.w + ")";
default:
return "error";
}
}
public bool OnGUI()
{
EditorGUI.BeginChangeCheck();
m_CurrentValue = EditorGUILayout.Vector4Field("Value", m_CurrentValue);
return EditorGUI.EndChangeCheck();
}
public bool OnGUI(Rect rect, ConcreteSlotValueType inputSlotType)
{
EditorGUI.BeginChangeCheck();
var rectXmax = rect.xMax;
switch (inputSlotType)
{
case ConcreteSlotValueType.Vector1:
rect.x = rectXmax - 50;
rect.width = 50;
EditorGUIUtility.labelWidth = 15;
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
m_CurrentValue.x = EditorGUI.FloatField(rect, "X", m_CurrentValue.x);
break;
case ConcreteSlotValueType.Vector2:
rect.x = rectXmax - 90;
rect.width = 90;
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
var result2 = new Vector4(m_CurrentValue.x, m_CurrentValue.y);
result2 = EditorGUI.Vector2Field(rect, GUIContent.none, result2);
m_CurrentValue.x = result2.x;
m_CurrentValue.y = result2.y;
break;
case ConcreteSlotValueType.Vector3:
rect.x = rectXmax - 140;
rect.width = 140;
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
var result3 = new Vector3(m_CurrentValue.x, m_CurrentValue.y, m_CurrentValue.z);
result3 = EditorGUI.Vector3Field(rect, GUIContent.none, result3);
m_CurrentValue.x = result3.x;
m_CurrentValue.y = result3.y;
m_CurrentValue.z = result3.z;
break;
default:
rect.x = rectXmax - 190;
rect.width = 190;
EditorGUI.DrawRect(rect, new Color(0.0f, 0.0f, 0.0f, 0.7f));
m_CurrentValue = EditorGUI.Vector4Field(rect, GUIContent.none, m_CurrentValue);
break;
}
return EditorGUI.EndChangeCheck();
}
public void BeforeSerialize()
{
m_NodeGUIDSerialized = m_NodeGUID.ToString();
}
public void AfterDeserialize()
{
m_NodeGUID = new GUID(m_NodeGUIDSerialized);
}
}
}
正在加载...
取消
保存