浏览代码

[material graph] Tidy up API for slot management (make generic).

/main
Tim Cooper 9 年前
当前提交
d9619701
共有 15 个文件被更改,包括 124 次插入162 次删除
  1. 4
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DrawableNode.cs
  2. 8
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphDataSource.cs
  3. 86
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Tests/SerializedGraphTests.cs
  4. 10
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/NodeUtils.cs
  5. 8
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableGraph.cs
  6. 28
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableNode.cs
  7. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/INode.cs
  8. 68
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs
  9. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function1Input.cs
  10. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function2Input.cs
  11. 16
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function3Input.cs
  12. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PixelShaderNode.cs
  13. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TextureNode.cs
  14. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UVNode.cs
  15. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs

4
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DrawableNode.cs


Vector3 pos = vector3;
// input slots
foreach (var slot in node.inputSlots.OrderBy(x => x.priority))
foreach (var slot in node.GetInputSlots<ISlot>().OrderBy(x => x.priority))
{
pos.y += 22;
AddChild(new NodeAnchor(pos, typeof(Vector4), node, slot, data, Direction.Input));

pos.x = width;
pos.y = yStart;
bool first = true;
foreach (var slot in node.outputSlots.OrderBy(x => x.priority))
foreach (var slot in node.GetOutputSlots<ISlot>().OrderBy(x => x.priority))
{
var edges = node.owner.GetEdges(node.GetSlotReference(slot.name));
// don't show empty output slots in collapsed mode

8
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphDataSource.cs


foreach (var drawableMaterialNode in m_DrawableNodes)
{
var baseNode = drawableMaterialNode.m_Node;
foreach (var slot in baseNode.outputSlots)
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
{
var sourceAnchor = (NodeAnchor)drawableMaterialNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor) x).m_Slot == slot);

var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot(edge.inputSlot.slotName);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotName);
var targetNode = m_DrawableNodes.FirstOrDefault(x => x.m_Node == toNode);
var targetAnchor = (NodeAnchor)targetNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor) x).m_Slot == toSlot);
drawableEdges.Add(new Edge<NodeAnchor>(this, sourceAnchor, targetAnchor));

foreach (var e in elements.OfType<Edge<NodeAnchor>>())
{
//find the edge
var edge = graph.edges.FirstOrDefault(x => graph.GetNodeFromGuid(x.outputSlot.nodeGuid).FindOutputSlot(x.outputSlot.slotName) == e.Left.m_Slot
&& graph.GetNodeFromGuid(x.inputSlot.nodeGuid).FindInputSlot(x.inputSlot.slotName) == e.Right.m_Slot);
var edge = graph.edges.FirstOrDefault(x => graph.GetNodeFromGuid(x.outputSlot.nodeGuid).FindOutputSlot<ISlot>(x.outputSlot.slotName) == e.Left.m_Slot
&& graph.GetNodeFromGuid(x.inputSlot.nodeGuid).FindInputSlot<ISlot>(x.inputSlot.slotName) == e.Right.m_Slot);
toRemoveEdge.Add(edge);
}

86
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Tests/SerializedGraphTests.cs


Assert.AreEqual(1, graph.GetNodes<INode>().Count());
var found = graph.GetNodes<INode>().FirstOrDefault();
Assert.AreEqual(1, found.inputSlots.Count());
Assert.AreEqual("input", found.inputSlots.FirstOrDefault().name);
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual("output", found.outputSlots.FirstOrDefault().name);
Assert.AreEqual(2, found.slots.Count());
Assert.AreEqual(1, found.GetInputSlots<ISlot>().Count());
Assert.AreEqual("input", found.GetInputSlots<ISlot>().FirstOrDefault().name);
Assert.AreEqual(1, found.GetOutputSlots<ISlot>().Count());
Assert.AreEqual("output", found.GetOutputSlots<ISlot>().FirstOrDefault().name);
Assert.AreEqual(2, found.GetSlots<ISlot>().Count());
}
[Test]

node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));
Assert.AreEqual(2, node.slots.Count());
Assert.AreEqual(1, node.inputSlots.Count());
Assert.AreEqual(1, node.outputSlots.Count());
Assert.AreEqual(2, node.GetSlots<ISlot>().Count());
Assert.AreEqual(1, node.GetInputSlots<ISlot>().Count());
Assert.AreEqual(1, node.GetOutputSlots<ISlot>().Count());
Assert.AreEqual(1, node.slots.Count());
Assert.AreEqual(0, node.inputSlots.Count());
Assert.AreEqual(1, node.outputSlots.Count());
Assert.AreEqual(1, node.GetSlots<ISlot>().Count());
Assert.AreEqual(0, node.GetInputSlots<ISlot>().Count());
Assert.AreEqual(1, node.GetOutputSlots<ISlot>().Count());
}
[Test]

node.AddSlot(new SerializableSlot("input3", "input", SlotType.Input, 0));
node.AddSlot(new SerializableSlot("input4", "input", SlotType.Input, 0));
Assert.AreEqual(4, node.slots.Count());
Assert.AreEqual(4, node.inputSlots.Count());
Assert.AreEqual(0, node.outputSlots.Count());
Assert.AreEqual(4, node.GetSlots<ISlot>().Count());
Assert.AreEqual(4, node.GetInputSlots<ISlot>().Count());
Assert.AreEqual(0, node.GetOutputSlots<ISlot>().Count());
Assert.AreEqual(2, node.slots.Count());
Assert.AreEqual(2, node.inputSlots.Count());
Assert.AreEqual(0, node.outputSlots.Count());
Assert.AreEqual(2, node.GetSlots<ISlot>().Count());
Assert.AreEqual(2, node.GetInputSlots<ISlot>().Count());
Assert.AreEqual(0, node.GetOutputSlots<ISlot>().Count());
Assert.IsNotNull(node.FindInputSlot("input1"));
Assert.IsNull(node.FindInputSlot("input2"));
Assert.IsNotNull(node.FindInputSlot("input3"));
Assert.IsNull(node.FindInputSlot("input4"));
Assert.IsNotNull(node.FindInputSlot<ISlot>("input1"));
Assert.IsNull(node.FindInputSlot<ISlot>("input2"));
Assert.IsNotNull(node.FindInputSlot<ISlot>("input3"));
Assert.IsNull(node.FindInputSlot<ISlot>("input4"));
}
[Test]

Assert.AreEqual(1, graph.GetNodes<INode>().Count());
var found = graph.GetNodes<INode>().FirstOrDefault();
Assert.AreEqual(0, found.inputSlots.Count());
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual(1, found.slots.Count());
Assert.AreEqual(0, found.GetInputSlots<ISlot>().Count());
Assert.AreEqual(1, found.GetOutputSlots<ISlot>().Count());
Assert.AreEqual(1, found.GetSlots<ISlot>().Count());
}
[Test]

Assert.AreEqual(1, graph.GetNodes<INode>().Count());
var found = graph.GetNodes<INode>().FirstOrDefault();
Assert.AreEqual(0, found.inputSlots.Count());
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual(1, found.slots.Count());
Assert.AreEqual(0, found.GetInputSlots<ISlot>().Count());
Assert.AreEqual(1, found.GetOutputSlots<ISlot>().Count());
Assert.AreEqual(1, found.GetSlots<ISlot>().Count());
var slot = found.outputSlots.FirstOrDefault();
var slot = found.GetOutputSlots<ISlot>().FirstOrDefault();
Assert.AreEqual("output_updated", slot.displayName);
}

Assert.AreEqual(1, graph.GetNodes<INode>().Count());
var found = graph.GetNodes<INode>().FirstOrDefault();
Assert.AreEqual(0, found.inputSlots.Count());
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual(1, found.slots.Count());
Assert.AreEqual(0, found.GetInputSlots<ISlot>().Count());
Assert.AreEqual(1, found.GetOutputSlots<ISlot>().Count());
Assert.AreEqual(1, found.GetSlots<ISlot>().Count());
var slot = found.outputSlots.FirstOrDefault();
var slot = found.GetOutputSlots<ISlot>().FirstOrDefault();
Assert.AreEqual(1, slot.priority);
}

node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));
Assert.AreEqual(2, node.slots.Count());
Assert.IsNotNull(node.FindInputSlot("input"));
Assert.IsNull(node.FindInputSlot("output"));
Assert.IsNotNull(node.FindOutputSlot("output"));
Assert.IsNull(node.FindOutputSlot("input"));
Assert.AreEqual(2, node.GetSlots<ISlot>().Count());
Assert.IsNotNull(node.FindInputSlot<ISlot>("input"));
Assert.IsNull(node.FindInputSlot<ISlot>("output"));
Assert.IsNotNull(node.FindOutputSlot<ISlot>("output"));
Assert.IsNull(node.FindOutputSlot<ISlot>("input"));
Assert.IsNotNull(node.FindSlot("input"));
Assert.IsNotNull(node.FindSlot("output"));
Assert.IsNull(node.FindSlot("invalid"));
Assert.IsNotNull(node.FindSlot<ISlot>("input"));
Assert.IsNotNull(node.FindSlot<ISlot>("output"));
Assert.IsNull(node.FindSlot<ISlot>("invalid"));
}
[Test]

node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));
Assert.AreEqual(2, node.slots.Count());
Assert.AreEqual(2, node.GetSlots<ISlot>().Count());
Assert.IsNotNull(node.GetSlotReference("input"));
Assert.IsNotNull(node.GetSlotReference("output"));
Assert.Null(node.GetSlotReference("invalid"));

Assert.AreEqual(createdEdge, edge);
var foundOutputNode = graph.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var foundOutputSlot = foundOutputNode.FindOutputSlot(edge.outputSlot.slotName);
var foundOutputSlot = foundOutputNode.FindOutputSlot<ISlot>(edge.outputSlot.slotName);
var foundInputSlot = foundInputNode.FindInputSlot(edge.inputSlot.slotName);
var foundInputSlot = foundInputNode.FindInputSlot<ISlot>(edge.inputSlot.slotName);
Assert.AreEqual(inputNode, foundInputNode);
Assert.AreEqual(inputSlot, foundInputSlot);
}

10
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/NodeUtils.cs


}
var validSlots = ListPool<ISlot>.Get();
validSlots.AddRange(currentNode.inputSlots);
validSlots.AddRange(currentNode.GetInputSlots<ISlot>());
for (int index = 0; index < validSlots.Count; index++)
{
var inputSlot = validSlots[index];

var outputNode = currentNode.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);
var outputSlot = outputNode.FindOutputSlot(edge.outputSlot.slotName);
var outputSlot = outputNode.FindOutputSlot<ISlot>(edge.outputSlot.slotName);
if (outputNode == fromNode && !foundUsedOutputSlots.Contains(outputSlot))
foundUsedOutputSlots.Add(outputSlot);
else

return;
// if we have a slot passed in but can not find it on the node abort
if (slotToUse != null && node.inputSlots.All(x => x.name != slotToUse.name))
if (slotToUse != null && node.GetInputSlots<ISlot>().All(x => x.name != slotToUse.name))
return;
var validSlots = ListPool<ISlot>.Get();

validSlots.AddRange(node.inputSlots);
validSlots.AddRange(node.GetInputSlots<ISlot>());
for (int index = 0; index < validSlots.Count; index++)
{

if (nodeList.Contains(node))
return;
foreach (var slot in node.outputSlots)
foreach (var slot in node.GetOutputSlots<ISlot>())
{
foreach (var edge in node.owner.GetEdges(node.GetSlotReference(slot.name)))
{

8
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableGraph.cs


if (fromNode == null || toNode == null)
return null;
var fromSlot = fromNode.FindSlot(fromSlotRef.slotName);
var toSlot = toNode.FindSlot(toSlotRef.slotName);
var fromSlot = fromNode.FindSlot<ISlot>(fromSlotRef.slotName);
var toSlot = toNode.FindSlot<ISlot>(toSlotRef.slotName);
SlotReference outputSlot = null;
SlotReference inputSlot = null;

if (outputNode == null
|| inputNode == null
|| outputNode.FindOutputSlot(edge.outputSlot.slotName) == null
|| inputNode.FindInputSlot(edge.inputSlot.slotName) == null)
|| outputNode.FindOutputSlot<ISlot>(edge.outputSlot.slotName) == null
|| inputNode.FindInputSlot<ISlot>(edge.inputSlot.slotName) == null)
{
//orphaned edge
RemoveEdgeNoValidate(edge);

28
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableNode.cs


public virtual void ValidateNode()
{}
public IEnumerable<ISlot> inputSlots
public IEnumerable<T> GetInputSlots<T>() where T : ISlot
get { return m_Slots.Where(x => x.isInputSlot); }
return GetSlots<T>().Where(x => x.isInputSlot);
public IEnumerable<ISlot> outputSlots
public IEnumerable<T> GetOutputSlots<T>() where T : ISlot
get { return m_Slots.Where(x => x.isOutputSlot); }
return GetSlots<T>().Where(x => x.isOutputSlot);
public IEnumerable<ISlot> slots
public IEnumerable<T> GetSlots<T>() where T : ISlot
get { return m_Slots; }
return m_Slots.OfType<T>();
}
public SerializableNode()

public SlotReference GetSlotReference(string name)
{
var slot = FindSlot(name);
var slot = FindSlot<ISlot>(name);
public ISlot FindSlot(string name)
public T FindSlot<T>(string name) where T: ISlot
var slot = slots.FirstOrDefault(x => x.name == name);
var slot = GetSlots<T>().FirstOrDefault(x => x.name == name);
public ISlot FindInputSlot(string name)
public T FindInputSlot<T>(string name) where T : ISlot
var slot = inputSlots.FirstOrDefault(x => x.name == name);
var slot = GetInputSlots<T>().FirstOrDefault(x => x.name == name);
public ISlot FindOutputSlot(string name)
public T FindOutputSlot<T>(string name) where T : ISlot
var slot = outputSlots.FirstOrDefault(x => x.name == name);
var slot = GetOutputSlots<T>().FirstOrDefault(x => x.name == name);
if (slot == null)
Debug.LogErrorFormat("Output Slot: {0} could be found on node {1}", name, this);
return slot;

public virtual IEnumerable<ISlot> GetInputsWithNoConnection()
{
return inputSlots.Where(x => !owner.GetEdges(GetSlotReference(x.name)).Any());
return GetInputSlots<ISlot>().Where(x => !owner.GetEdges(GetSlotReference(x.name)).Any());
}
public virtual void UpdateNodeAfterDeserialization()

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/INode.cs


Guid guid { get; }
string name { get; set; }
bool canDeleteNode { get; }
IEnumerable<ISlot> inputSlots { get; }
IEnumerable<ISlot> outputSlots { get; }
IEnumerable<ISlot> slots { get; }
IEnumerable<T> GetInputSlots<T>() where T : ISlot;
IEnumerable<T> GetOutputSlots<T>() where T : ISlot;
IEnumerable<T> GetSlots<T>() where T : ISlot;
ISlot FindSlot(string name);
ISlot FindInputSlot(string name);
ISlot FindOutputSlot(string name);
T FindSlot<T>(string name) where T : ISlot;
T FindInputSlot<T>(string name) where T : ISlot;
T FindOutputSlot<T>(string name) where T : ISlot;
IEnumerable<ISlot> GetInputsWithNoConnection();
DrawingData drawState { get; set; }
bool hasError { get; }

68
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs


protected set { m_HasError = value; }
}
public IEnumerable<MaterialSlot> materialSlots
{
get { return slots.OfType<MaterialSlot>(); }
}
public IEnumerable<MaterialSlot> materialInputSlots
{
get { return inputSlots.OfType<MaterialSlot>(); }
}
public IEnumerable<MaterialSlot> materialOuputSlots
{
get { return outputSlots.OfType<MaterialSlot>(); }
}
protected AbstractMaterialNode()
{
version = 0;

if (!generationMode.IsPreview())
return;
foreach (var inputSlot in materialInputSlots)
foreach (var inputSlot in GetInputSlots<MaterialSlot>())
{
var edges = owner.GetEdges(GetSlotReference(inputSlot.name));
if (edges.Any())

if (fromNode == null)
return string.Empty;
var slot = fromNode.FindOutputSlot(fromSocketRef.slotName) as MaterialSlot;
var slot = fromNode.FindOutputSlot<MaterialSlot>(fromSocketRef.slotName);
if (slot == null)
return string.Empty;

return inputSlot.GetDefaultValue(generationMode, inputSlot.concreteValueType, this);
}
public MaterialSlot FindMaterialInputSlot(string name)
{
var slot = FindInputSlot(name);
if (slot == null)
return null;
if (slot is MaterialSlot)
return slot as MaterialSlot;
Debug.LogErrorFormat("Input Slot: {0} exists but is not of type {1}", name, typeof(MaterialSlot));
return null;
}
public MaterialSlot FindMaterialOutputSlot(string name)
{
var slot = FindOutputSlot(name);
if (slot == null)
return null;
if (slot is MaterialSlot)
return slot as MaterialSlot;
Debug.LogErrorFormat("Output Slot: {0} exists but is not of type {1}", name, typeof(MaterialSlot));
return null;
}
private ConcreteSlotValueType FindCommonChannelType(ConcreteSlotValueType from, ConcreteSlotValueType to)
{
if (ImplicitConversionExists(from, to))

// all children nodes needs to be updated first
// so do that here
foreach (var inputSlot in inputSlots)
foreach (var inputSlot in GetInputSlots<MaterialSlot>())
{
var edges = owner.GetEdges(GetSlotReference(inputSlot.name));
foreach (var edge in edges)

var skippedDynamicSlots = new List<MaterialSlot>();
// iterate the input slots
foreach (var inputSlot in materialInputSlots)
foreach (var inputSlot in GetInputSlots<MaterialSlot>())
{
var inputType = inputSlot.valueType;
// if there is a connection

if (outputNode == null)
continue;
var outputSlot = outputNode.FindOutputSlot(outputSlotRef.slotName) as MaterialSlot;
var outputSlot = outputNode.FindOutputSlot<MaterialSlot>(outputSlotRef.slotName);
if (outputSlot == null)
continue;

foreach (var skippedSlot in skippedDynamicSlots)
skippedSlot.concreteValueType = dynamicType;
var inputError = materialInputSlots.Any(x => x.concreteValueType == ConcreteSlotValueType.Error);
var inputError = GetInputSlots<MaterialSlot>().Any(x => x.concreteValueType == ConcreteSlotValueType.Error);
foreach (var outputSlot in materialOuputSlots)
foreach (var outputSlot in GetOutputSlots<MaterialSlot>())
{
if (inputError)
{

}
isInError |= inputError;
isInError |= materialOuputSlots.Any(x => x.concreteValueType == ConcreteSlotValueType.Error);
isInError |= GetOutputSlots<MaterialSlot>().Any(x => x.concreteValueType == ConcreteSlotValueType.Error);
isInError |= CalculateNodeHasError();
hasError = isInError;

public virtual void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
var validSlots = materialInputSlots.ToArray();
var validSlots = GetOutputSlots<MaterialSlot>().ToArray();
for (var index = 0; index < validSlots.Length; index++)
{

public virtual string GetOutputVariableNameForSlot(MaterialSlot s)
{
if (s.isInputSlot) Debug.LogError("Attempting to use input MaterialSlot (" + s + ") for output!");
if (!materialSlots.Contains(s)) Debug.LogError("Attempting to use MaterialSlot (" + s + ") for output on a node that does not have this MaterialSlot!");
if (!GetOutputSlots<MaterialSlot>().Contains(s)) Debug.LogError("Attempting to use MaterialSlot (" + s + ") for output on a node that does not have this MaterialSlot!");
return GetVariableNameForNode() + "_" + s.name;
}

if (s.isOutputSlot) Debug.LogError("Attempting to use output MaterialSlot (" + s + ") for default input!");
if (!materialSlots.Contains(s)) Debug.LogError("Attempting to use MaterialSlot (" + s + ") for default input on a node that does not have this MaterialSlot!");
if (!GetOutputSlots<MaterialSlot>().Contains(s)) Debug.LogError("Attempting to use MaterialSlot (" + s + ") for default input on a node that does not have this MaterialSlot!");
return GetVariableNameForNode() + "_" + s.name;
}

base.AddSlot(slot);
var addingSlot = (MaterialSlot) slot;
var foundSlot = (MaterialSlot)slots.FirstOrDefault(x => x.name == slot.name);
var foundSlot = FindSlot<MaterialSlot>(slot.name);
if (foundSlot == null)
return;
// if the default and current are the same, change the current
// to the new default.

8
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function1Input.cs


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindMaterialOutputSlot(GetOutputSlotName());
var inputSlot = FindMaterialInputSlot(GetInputSlotName());
var outputSlot = FindOutputSlot<MaterialSlot>(GetOutputSlotName());
var inputSlot = FindInputSlot<MaterialSlot>(GetInputSlotName());
if (inputSlot == null || outputSlot == null)
{

public string outputDimension
{
get { return ConvertConcreteSlotValueTypeToString(FindMaterialOutputSlot(GetOutputSlotName()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindOutputSlot<MaterialSlot>(GetOutputSlotName()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindMaterialInputSlot(GetInputSlotName()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindInputSlot<MaterialSlot>(GetInputSlotName()).concreteValueType); }
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function2Input.cs


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindMaterialOutputSlot(GetOutputSlotName());
var inputSlot1 = FindMaterialInputSlot(GetInputSlot1Name());
var inputSlot2 = FindMaterialInputSlot(GetInputSlot2Name());
var outputSlot = FindOutputSlot<MaterialSlot>(GetOutputSlotName());
var inputSlot1 = FindInputSlot<MaterialSlot>(GetInputSlot1Name());
var inputSlot2 = FindInputSlot<MaterialSlot>(GetInputSlot2Name());
if (inputSlot1 == null || inputSlot2 == null || outputSlot == null)
{

public string outputDimension
{
get { return ConvertConcreteSlotValueTypeToString(FindMaterialOutputSlot(GetOutputSlotName()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindOutputSlot<MaterialSlot>(GetOutputSlotName()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindMaterialInputSlot(GetInputSlot1Name()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindInputSlot<MaterialSlot>(GetInputSlot1Name()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindMaterialInputSlot(GetInputSlot2Name()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindInputSlot<MaterialSlot>(GetInputSlot2Name()).concreteValueType); }
}
}
}

16
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function3Input.cs


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindMaterialOutputSlot(GetOutputSlotName());
var inputSlot1 = FindMaterialInputSlot(GetInputSlot1Name());
var inputSlot2 = FindMaterialInputSlot(GetInputSlot2Name());
var inputSlot3 = FindMaterialInputSlot(GetInputSlot3Name());
var outputSlot = FindOutputSlot<MaterialSlot>(GetOutputSlotName());
var inputSlot1 = FindInputSlot<MaterialSlot>(GetInputSlot1Name());
var inputSlot2 = FindInputSlot<MaterialSlot>(GetInputSlot2Name());
var inputSlot3 = FindInputSlot<MaterialSlot>(GetInputSlot3Name());
if (inputSlot1 == null || inputSlot2 == null || inputSlot3 == null || outputSlot == null)
{

public string outputDimension
{
get { return ConvertConcreteSlotValueTypeToString(FindMaterialOutputSlot(GetOutputSlotName()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindOutputSlot<MaterialSlot>(GetOutputSlotName()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindMaterialInputSlot(GetInputSlot1Name()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindInputSlot<MaterialSlot>(GetInputSlot1Name()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindMaterialInputSlot(GetInputSlot2Name()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindInputSlot<MaterialSlot>(GetInputSlot2Name()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindMaterialInputSlot(GetInputSlot3Name()).concreteValueType); }
get { return ConvertConcreteSlotValueTypeToString(FindInputSlot<MaterialSlot>(GetInputSlot3Name()).concreteValueType); }
}
}
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PixelShaderNode.cs


var lightFunction = GetLightFunction();
var firstPassSlotName = lightFunction.GetFirstPassSlotName();
// do the normal slot first so that it can be used later in the shader :)
var firstPassSlot = FindInputSlot(firstPassSlotName);
var firstPassSlot = FindInputSlot<MaterialSlot>(firstPassSlotName);
var nodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(nodes, this, firstPassSlot, false);

if (fromNode == null)
continue;
var fromSlot = fromNode.FindOutputSlot(outputRef.slotName) as MaterialSlot;
var fromSlot = fromNode.FindOutputSlot<MaterialSlot>(outputRef.slotName) as MaterialSlot;
if (fromSlot == null)
continue;

ListPool<INode>.Release(nodes);
foreach (var slot in inputSlots)
foreach (var slot in GetInputSlots<MaterialSlot>())
{
if (slot == firstPassSlot)
continue;

if (fromNode == null)
continue;
var fromSlot = fromNode.FindOutputSlot(outputRef.slotName) as MaterialSlot;
var fromSlot = fromNode.FindOutputSlot<MaterialSlot>(outputRef.slotName) as MaterialSlot;
if (fromSlot == null)
continue;

8
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TextureNode.cs


// Node generations
public virtual void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var uvSlot = FindInputSlot(kUVSlotName);
var uvSlot = FindInputSlot<MaterialSlot>(kUVSlotName);
if (uvSlot == null)
return;

{
var edge = edges[0];
var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(edge.outputSlot.nodeGuid);
var slot = fromNode.FindMaterialOutputSlot(edge.outputSlot.slotName);
var slot = fromNode.FindOutputSlot<MaterialSlot>(edge.outputSlot.slotName);
uvName = ShaderGenerator.AdaptNodeOutput(fromNode, slot, generationMode, ConcreteSlotValueType.Vector2, true);
}

public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
var uvSlot = FindInputSlot(kUVSlotName);
var uvSlot = FindInputSlot<MaterialSlot>(kUVSlotName);
if (uvSlot == null)
return;

public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
var uvSlot = FindInputSlot(kUVSlotName);
var uvSlot = FindInputSlot<MaterialSlot>(kUVSlotName);
if (uvSlot == null)
return;

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UVNode.cs


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindMaterialOutputSlot(kOutputSlotName);
var outputSlot = FindOutputSlot<MaterialSlot>(kOutputSlotName);
string uvValue = "IN.meshUV0";
visitor.AddShaderChunk(precision + "4 " + GetOutputVariableNameForSlot(outputSlot) + " = " + uvValue + ";", true);

8
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs


public static string GeneratePreviewShader(AbstractMaterialNode node, out PreviewMode generatedShaderMode)
{
if (!node.materialOuputSlots.Any())
if (!node.GetOutputSlots<MaterialSlot>().Any())
{
generatedShaderMode = PreviewMode.Preview2D;
return string.Empty;

var shaderPropertyUsagesVisitor = new ShaderGenerator();
var vertexShaderBlock = new ShaderGenerator();
var shaderName = "Hidden/PreviewShader/" + node.GetOutputVariableNameForSlot(node.materialOuputSlots.First());
var shaderName = "Hidden/PreviewShader/" + node.GetOutputVariableNameForSlot(node.GetOutputSlots<MaterialSlot>().First());
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
{

}
if (generationMode == GenerationMode.Preview2D)
shaderBodyVisitor.AddShaderChunk("return " + AdaptNodeOutputForPreview(node, node.materialOuputSlots.First(), generationMode, ConcreteSlotValueType.Vector4) + ";", true);
shaderBodyVisitor.AddShaderChunk("return " + AdaptNodeOutputForPreview(node, node.GetOutputSlots<MaterialSlot>().First(), generationMode, ConcreteSlotValueType.Vector4) + ";", true);
shaderBodyVisitor.AddShaderChunk("o.Emission = " + AdaptNodeOutputForPreview(node, node.materialOuputSlots.First(), generationMode, ConcreteSlotValueType.Vector3) + ";", true);
shaderBodyVisitor.AddShaderChunk("o.Emission = " + AdaptNodeOutputForPreview(node, node.GetOutputSlots<MaterialSlot>().First(), generationMode, ConcreteSlotValueType.Vector3) + ";", true);
template = template.Replace("${ShaderName}", shaderName);
template = template.Replace("${ShaderPropertiesHeader}", shaderPropertiesVisitor.GetShaderString(2));

正在加载...
取消
保存