浏览代码

[Material graph] Working subGraph now. Copies function / properties etc.

/main
Tim Cooper 8 年前
当前提交
62377747
共有 41 个文件被更改,包括 344 次插入144 次删除
  1. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs
  2. 4
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Testing/UnitTests/SerializedGraphTests.cs
  3. 1
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Assets/IGraphAsset.cs
  4. 7
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Assets/SerializableGraphAsset.cs
  5. 8
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableGraph.cs
  6. 9
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableNode.cs
  7. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IGraph.cs
  8. 41
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs
  9. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/TextureNodeUI.cs
  10. 26
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/ShaderGeneratorTests.cs
  11. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraphAsset.cs
  12. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/PixelGraph.cs
  13. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/Interfaces.cs
  14. 26
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs
  15. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ColorNode.cs
  16. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function1Input.cs
  17. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function2Input.cs
  18. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function3Input.cs
  19. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/FunctionMultiInput.cs
  20. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MaterialSlot.cs
  21. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/NormalNode.cs
  22. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PixelShaderNode.cs
  23. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PropertyNode.cs
  24. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ScreenPosNode.cs
  25. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SinTimeNode.cs
  26. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TextureNode.cs
  27. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TimeNode.cs
  28. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UVNode.cs
  29. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector1Node.cs
  30. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector2Node.cs
  31. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector3Node.cs
  32. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector4Node.cs
  33. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ViewDirectionNode.cs
  34. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldPosNode.cs
  35. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MaterialSubGraphAsset.cs
  36. 88
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraph.cs
  37. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs
  38. 176
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs
  39. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs
  40. 7
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IOnAssetEnabled.cs
  41. 12
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IOnAssetEnabled.cs.meta

3
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs


var selection = Selection.activeObject as T;
if (selection != m_LastSelection)
{
var graph = selection.graph;
graph.OnEnable();
graph.ValidateGraph();
m_LastSelection = selection;
Rebuild();
Repaint();

4
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Testing/UnitTests/SerializedGraphTests.cs


[Test]
public void TestCanRemoveSlotFromSerializableNode()
{
var graph = new SerializableGraph();
graph.AddNode(node);
Assert.AreEqual(2, node.GetSlots<ISlot>().Count());
Assert.AreEqual(1, node.GetInputSlots<ISlot>().Count());

[Test]
public void TestCanRemoveSlotsWithNonMathingNameFromSerializableNode()
{
var graph = new SerializableGraph();
graph.AddNode(node);
node.AddSlot(new SerializableSlot("input1", "input", SlotType.Input, 0));
node.AddSlot(new SerializableSlot("input2", "input", SlotType.Input, 0));
node.AddSlot(new SerializableSlot("input3", "input", SlotType.Input, 0));

1
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Assets/IGraphAsset.cs


IGraph graph { get; }
bool shouldRepaint { get; }
ScriptableObject GetScriptableObject();
void OnEnable();
}
}

7
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Assets/SerializableGraphAsset.cs


namespace UnityEngine.Graphing
{
public class SerializableGraphAsset : ScriptableObject, IGraphAsset
public class SerializableGraphAsset : ScriptableObject, IGraphAsset, IOnAssetEnabled
{
[SerializeField]
protected SerializableGraph m_Graph = new SerializableGraph();

public ScriptableObject GetScriptableObject()
{
return this;
}
public void OnEnable()
{
graph.OnEnable();
}
}
}

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


foreach (var node in GetNodes<INode>())
node.ValidateNode();
}
public void OnEnable()
{
foreach (var node in GetNodes<INode>().OfType<IOnAssetEnabled>())
{
node.OnEnable();
}
}
}
}

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


public void RemoveSlot(string name)
{
//Remove edges that use this slot
var edges = owner.GetEdges(GetSlotReference(name));
foreach (var edge in edges.ToArray())
owner.RemoveEdge(edge);
//remove slots
public void RemoveSlotsNameNotMatching(string[] slotNames)
public void RemoveSlotsNameNotMatching(IEnumerable<string> slotNames)
{
var invalidSlots = m_Slots.Select(x => x.name).Except(slotNames);

2
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IGraph.cs


namespace UnityEngine.Graphing
{
public interface IGraph
public interface IGraph : IOnAssetEnabled
{
IEnumerable<T> GetNodes<T>() where T : INode;
IEnumerable<IEdge> edges { get; }

41
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
public class SubgraphNodeUI : ICustomNodeUi
public class SubgraphNodeUI : AbstractMaterialNodeUI
private SubGraphNode m_Node;
return 1 * EditorGUIUtility.singleLineHeight;
return base.GetNodeUiHeight(width) + 2 * EditorGUIUtility.singleLineHeight;
public GUIModificationType Render(Rect area)
public override GUIModificationType Render(Rect area)
if (m_Node == null)
return GUIModificationType.None;
var node = m_Node as SubGraphNode;
if (node == null)
return base.Render(area);
m_Node.subGraphAsset = (MaterialSubGraphAsset) EditorGUI.ObjectField(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight),
node.subGraphAsset = (MaterialSubGraphAsset) EditorGUI.ObjectField(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight),
m_Node.subGraphAsset,
node.subGraphAsset,
var toReturn = GUIModificationType.None;
{
m_Node.UpdateNodeAfterDeserialization();
return GUIModificationType.ModelChanged;
}
toReturn |= GUIModificationType.ModelChanged;
return GUIModificationType.None;
}
public void SetNode(INode node)
{
if (node is SubGraphNode)
m_Node = (SubGraphNode) node;
}
public float GetNodeWidth()
{
return 200;
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
toReturn |= base.Render(area);
return toReturn;
}
}
}

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/TextureNodeUI.cs


using System;
using System.Collections.Generic;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;

26
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/ShaderGeneratorTests.cs


var node = new TestNode();
var slot = node.FindOutputSlot<MaterialSlot>("V1Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("{0}", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V1Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0})", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V1Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("({0})", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V1Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector4);
Assert.AreEqual(string.Format("({0})", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V2Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V2Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("{0}", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var node = new TestNode();
var slot = node.FindOutputSlot<MaterialSlot>("V3Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V3Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0}.xy)", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0}.xy)", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V3Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("{0}", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var node = new TestNode();
var slot = node.FindOutputSlot<MaterialSlot>("V4Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V4Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0}.xy)", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0}.xy)", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V4Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("({0}.xyz)", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("({0}.xyz)", node.GetVariableNameForSlot(slot)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>("V4Out");
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector4);
Assert.AreEqual(string.Format("{0}", node.GetOutputVariableNameForSlot(slot)), result);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(slot)), result);
}

5
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraphAsset.cs


return this;
}
public void OnEnable()
{
graph.OnEnable();
}
public Material GetMaterial()
{
return null;

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/PixelGraph.cs


if (node is IGenerateProperties)
{
(node as IGenerateProperties).GeneratePropertyBlock(shaderProperties, genMode);
(node as IGenerateProperties).GeneratePropertyUsages(propertyUsages, genMode, ConcreteSlotValueType.Vector4);
(node as IGenerateProperties).GeneratePropertyUsages(propertyUsages, genMode);
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/Interfaces.cs


public interface IGenerateProperties
{
void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode);
void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType);
void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode);
}
}

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


public virtual void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
{}
public virtual void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
public virtual void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
{
if (!generateDefaultInputs)
return;

{
var edges = owner.GetEdges(GetSlotReference(inputSlot.name)).ToArray();
if (edges.Length > 0)
if (edges.Any())
{
var fromSocketRef = edges[0].outputSlot;
var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(fromSocketRef.nodeGuid);

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

var pp = new PreviewProperty
{
m_Name = GetOutputVariableNameForSlot(s),
m_Name = GetVariableNameForSlot(s),
m_PropType = PropertyType.Vector4,
m_Vector4 = s.currentValue
};

public virtual string GetOutputVariableNameForSlot(MaterialSlot s)
{
if (s.isInputSlot)
Debug.LogError("Attempting to use input MaterialSlot (" + s + ") for output!");
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;
}
public virtual string GetInputVariableNameForSlot(MaterialSlot s)
public virtual string GetVariableNameForSlot(MaterialSlot s)
if (s.isOutputSlot)
Debug.LogError("Attempting to use output MaterialSlot (" + s + ") for default input!");
if (!GetInputSlots<MaterialSlot>().Contains(s))
Debug.LogError("Attempting to use MaterialSlot (" + s + ") for default input on a node that does not have this MaterialSlot!");
if (!GetSlots<MaterialSlot>().Contains(s))
Debug.LogError("Attempting to use MaterialSlot (" + s + ") on a node that does not have this MaterialSlot!");
return GetVariableNameForNode() + "_" + s.name;
}

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


set { m_Color = value; }
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
{
if (exposed || generationMode.IsPreview())
visitor.AddShaderChunk("float4 " + propertyName + ";", true);

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


}
var inputValue = GetSlotValue(inputSlot, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetOutputVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(inputValue) + ";", true);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(inputValue) + ";", true);
}
protected virtual string GetFunctionCallBody(string inputValue)

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


string input1Value = GetSlotValue(inputSlot1, generationMode);
string input2Value = GetSlotValue(inputSlot2, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetOutputVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(input1Value, input2Value) + ";", true);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(input1Value, input2Value) + ";", true);
}
protected virtual string GetFunctionCallBody(string input1Value, string input2Value)

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


string input2Value = GetSlotValue(inputSlot2, generationMode);
string input3Value = GetSlotValue(inputSlot3, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetOutputVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(input1Value, input2Value, input3Value) + ";", true);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(input1Value, input2Value, input3Value) + ";", true);
}
protected virtual string GetFunctionCallBody(string inputValue1, string inputValue2, string inputValue3)

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


var inputValues = new List<string>(inputSlotCount);
MaterialWindow.DebugMaterialGraph("Generating On Node: " + GetOutputVariableNameForNode() + " - Preview is: " + generationMode);
inputValues.AddRange(inputSlots.Select(inputSlot => GetSlotValue(inputSlot, generationMode)));
visitor.AddShaderChunk(precision + "4 " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + GetFunctionCallBody(inputValues) + ";", true);
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(outputSlot, generationMode) + " = " + GetFunctionCallBody(inputValues) + ";", true);
}
protected virtual string GetFunctionCallBody(List<string> inputValues)

4
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MaterialSlot.cs


if (!generationMode.IsPreview())
return;
visitor.AddShaderChunk("float" + AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(slotValueType) + " " + owner.GetInputVariableNameForSlot(this) + ";", true);
visitor.AddShaderChunk("float" + AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(slotValueType) + " " + owner.GetVariableNameForSlot(this) + ";", true);
return owner.GetInputVariableNameForSlot(this);
return owner.GetVariableNameForSlot(this);
switch (concreteValueType)
{

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


get { return PreviewMode.Preview3D; }
}
public override string GetOutputVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(MaterialSlot s)
{
return "o.Normal";
}

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


if (fromSlot == null)
continue;
shaderBody.AddShaderChunk("o." + firstPassSlot.name + " = " + fromNode.GetOutputVariableNameForSlot(fromSlot) + ";", true);
shaderBody.AddShaderChunk("o." + firstPassSlot.name + " = " + fromNode.GetVariableNameForSlot(fromSlot) + ";", true);
}
// track the last index of nodes... they have already been processed :)

if (fromSlot == null)
continue;
shaderBody.AddShaderChunk("o." + slot.name + " = " + fromNode.GetOutputVariableNameForSlot(fromSlot) + ";", true);
shaderBody.AddShaderChunk("o." + slot.name + " = " + fromNode.GetVariableNameForSlot(fromSlot) + ";", true);
public override string GetOutputVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(MaterialSlot s)
{
return GetVariableNameForNode();
}

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


public abstract PreviewProperty GetPreviewProperty();
public override string GetOutputVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(MaterialSlot s)
{
return propertyName;
}

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


RemoveSlotsNameNotMatching(new[] { kOutputSlotName });
}
public override string GetOutputVariableNameForSlot(MaterialSlot slot)
public override string GetVariableNameForSlot(MaterialSlot slot)
{
return "IN.screenPos";
}

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


get { return true; }
}
public override string GetOutputVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(MaterialSlot s)
{
return "_SinTime";
}

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


visitor.AddShaderChunk("float4 " + GetVariableNameForNode() + " = " + body + ";", true);
}
public override string GetOutputVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(MaterialSlot s)
{
string slotOutput;
switch (s.name)

visitor.AddShaderProperty(new TexturePropertyChunk(propertyName, description, defaultTexture, m_TextureType, false, exposed));
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
{
visitor.AddShaderChunk("sampler2D " + propertyName + ";", true);
}

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


get { return new[] {kOutputSlotName, kOutputSlotNameX, kOutputSlotNameY, kOutputSlotNameZ, kOutputSlotName}; }
}
public override string GetOutputVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(MaterialSlot s)
{
switch (s.name)
{

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


var outputSlot = FindOutputSlot<MaterialSlot>(kOutputSlotName);
string uvValue = "IN.meshUV0";
visitor.AddShaderChunk(precision + "4 " + GetOutputVariableNameForSlot(outputSlot) + " = " + uvValue + ";", true);
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(outputSlot) + " = " + uvValue + ";", true);
}
}
}

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


visitor.AddShaderProperty(new FloatPropertyChunk(propertyName, description, m_Value, false));
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType valueType)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
{
if (exposed || generationMode.IsPreview())
visitor.AddShaderChunk("float " + propertyName + ";", true);

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


visitor.AddShaderProperty(new VectorPropertyChunk(propertyName, description, m_Value, false));
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType valueType)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
{
if (exposed || generationMode.IsPreview())
visitor.AddShaderChunk("float2 " + propertyName + ";", true);

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


visitor.AddShaderProperty(new VectorPropertyChunk(propertyName, description, m_Value, false));
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType valueType)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
{
if (exposed || generationMode.IsPreview())
visitor.AddShaderChunk("float3 " + propertyName + ";", true);

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


visitor.AddShaderProperty(new VectorPropertyChunk(propertyName, description, m_Value, false));
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType valueType)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
{
if (exposed || generationMode.IsPreview())
visitor.AddShaderChunk("float4 " + propertyName + ";", true);

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


RemoveSlotsNameNotMatching(new[] { kOutputSlotName });
}
public override string GetOutputVariableNameForSlot(MaterialSlot slot)
public override string GetVariableNameForSlot(MaterialSlot slot)
{
return "IN.viewDir";
}

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


RemoveSlotsNameNotMatching(new[] { kOutputSlotName });
}
public override string GetOutputVariableNameForSlot(MaterialSlot slot)
public override string GetVariableNameForSlot(MaterialSlot slot)
{
return "IN.worldPos";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MaterialSubGraphAsset.cs


{
get { return m_MaterialSubGraph; }
}
public SubGraph subGraph
{
get { return m_MaterialSubGraph; }

public ScriptableObject GetScriptableObject()
{
return this;
}
public void OnEnable()
{
graph.OnEnable();
}
public void PostCreate()

88
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraph.cs


{
[Serializable]
public class SubGraph : AbstractMaterialGraph
, IGeneratesBodyCode
, IGeneratesFunction
, IGenerateProperties
, IGeneratesVertexShaderBlock
, IGeneratesVertexToFragmentBlock
[NonSerialized]
private SubGraphOutputNode m_OutputNode;

return m_OutputNode;
}
}
public IEnumerable<AbstractMaterialNode> activeNodes
{
get

{
AddNode(new SubGraphInputNode());
AddNode(new SubGraphOutputNode());
}
private IEnumerable<AbstractMaterialNode> usedNodes
{
get
{
var nodes = new List<INode>();
//Get the rest of the nodes for all the other slots
NodeUtils.DepthFirstCollectNodesFromNode(nodes, outputNode, null, false);
return nodes.OfType<AbstractMaterialNode>();
}
}
public PreviewMode previewMode
{
get { return usedNodes.Any(x => x.previewMode == PreviewMode.Preview3D) ? PreviewMode.Preview3D : PreviewMode.Preview2D; }
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGeneratesBodyCode)
(node as IGeneratesBodyCode).GenerateNodeCode(visitor, generationMode);
}
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGeneratesFunction)
(node as IGeneratesFunction).GenerateNodeFunction(visitor, generationMode);
}
}
public void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGenerateProperties)
(node as IGenerateProperties).GeneratePropertyBlock(visitor, generationMode);
}
}
public void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGenerateProperties)
(node as IGenerateProperties).GeneratePropertyUsages(visitor, generationMode);
}
}
public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGeneratesVertexShaderBlock)
(node as IGeneratesVertexShaderBlock).GenerateVertexShaderBlock(visitor, generationMode);
}
}
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGeneratesVertexToFragmentBlock)
(node as IGeneratesVertexToFragmentBlock).GenerateVertexToFragmentBlock(visitor, generationMode);
}
}
public IEnumerable<PreviewProperty> GetPreviewProperties()
{
List<PreviewProperty> props = new List<PreviewProperty>();
foreach (var node in usedNodes)
node.CollectPreviewMaterialProperties(props);
return props;
}
}
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs


RemoveSlot("Input" + (index - 1));
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType valueType)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
visitor.AddShaderChunk("float" + outDimension + " " + GetOutputVariableNameForSlot(slot) + ";", true);
visitor.AddShaderChunk("float" + outDimension + " " + GetVariableNameForSlot(slot) + ";", true);
}
}

properties.Add(
new PreviewProperty
{
m_Name = GetOutputVariableNameForSlot(slot),
m_Name = GetVariableNameForSlot(slot),
m_PropType = PropertyType.Vector4,
m_Vector4 = slot.defaultValue
}

176
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs


using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Graphing;

{
[Title("Sub-graph/Sub-graph Node")]
public class SubGraphNode : AbstractMaterialNode, IGeneratesBodyCode
public class SubGraphNode : AbstractMaterialNode
, IGeneratesBodyCode
, IGeneratesFunction
, IGeneratesVertexShaderBlock
, IGeneratesVertexToFragmentBlock
, IOnAssetEnabled
private MaterialSubGraphAsset m_SubGraphAsset;
private string m_SubGraphAssetGuid;
#if UNITY_EDITOR
get { return m_SubGraphAsset; }
set { m_SubGraphAsset = value; }
get
{
if (string.IsNullOrEmpty(m_SubGraphAssetGuid))
return null;
var path = AssetDatabase.GUIDToAssetPath(m_SubGraphAssetGuid);
if (string.IsNullOrEmpty(path))
return null;
return AssetDatabase.LoadAssetAtPath<MaterialSubGraphAsset>(path);
}
set
{
var assetPath = AssetDatabase.GetAssetPath(value);
if (string.IsNullOrEmpty(assetPath))
return;
m_SubGraphAssetGuid = AssetDatabase.AssetPathToGUID(assetPath);
OnEnable();
}
}
#else
public MaterialSubGraphAsset subGraphAsset
{
get
{
return null;
}
set
{}
}
#endif
private SubGraph subGraph
{
get
{
if (subGraphAsset == null)
return null;
return subGraphAsset.subGraph;
}
}
public override bool hasPreview
{
get { return subGraphAsset != null; }
}
public override PreviewMode previewMode
{
get
{
if (subGraphAsset == null)
return PreviewMode.Preview2D;
return subGraph.previewMode;
}
UpdateNodeAfterDeserialization();
public sealed override void UpdateNodeAfterDeserialization()
{
foreach (var slot in GetSlots<MaterialSlot>().Select(x => x.name).ToArray())
RemoveSlot(slot);
if (m_SubGraphAsset == null)
public void OnEnable()
{
List<string> validNames = new List<string>();
if (subGraphAsset == null)
{
RemoveSlotsNameNotMatching(validNames);
}
var subGraphInputNode = m_SubGraphAsset.subGraph.inputNode;
var subGraphInputNode = subGraphAsset.subGraph.inputNode;
AddSlot(new MaterialSlot(slot.name, slot.displayName, SlotType.Input, slot.priority, slot.valueType, slot.defaultValue ));
AddSlot(new MaterialSlot(slot.name, slot.displayName, SlotType.Input, slot.priority, slot.valueType, slot.defaultValue));
validNames.Add(slot.name);
var subGraphOutputNode = m_SubGraphAsset.subGraph.outputNode;
var subGraphOutputNode = subGraphAsset.subGraph.outputNode;
validNames.Add(slot.name);
RemoveSlotsNameNotMatching(validNames);
if (m_SubGraphAsset == null)
if (subGraphAsset == null)
return;
var outputString = new ShaderGenerator();

"float"
+ outDimension
+ " "
+ GetOutputVariableNameForSlot(slot)
+ GetVariableNameForSlot(slot)
+ " = 0;", false);
}

// Step 3...
// For each input that is used and connects through we want to generate code.
// First we assign the input variables to the subgraph
var subGraphInputNode = m_SubGraphAsset.subGraph.inputNode;
var subGraphInputNode = subGraphAsset.subGraph.inputNode;
var varName = subGraphInputNode.GetOutputVariableNameForSlot(subGraphInputNode.FindOutputSlot<MaterialSlot>(slot.name));
var varValue = GetSlotValue(slot, generationMode);
var varName = subGraphInputNode.GetVariableNameForSlot(subGraphInputNode.FindOutputSlot<MaterialSlot>(slot.name));
var varValue = GetSlotValue(slot, GenerationMode.SurfaceShader);
var outDimension = ConvertConcreteSlotValueTypeToString(slot.concreteValueType);
outputString.AddShaderChunk(

// Step 4...
// Using the inputs we can now generate the shader body :)
var bodyGenerator = new ShaderGenerator();
var subGraphOutputNode = m_SubGraphAsset.subGraph.outputNode;
var nodes = ListPool<INode>.Get();
//Get the rest of the nodes for all the other slots
NodeUtils.DepthFirstCollectNodesFromNode(nodes, subGraphOutputNode, null, false);
foreach (var node in nodes)
{
if (node is IGeneratesBodyCode)
(node as IGeneratesBodyCode).GenerateNodeCode(bodyGenerator, generationMode);
}
ListPool<INode>.Release(nodes);
subGraph.GenerateNodeCode(bodyGenerator, GenerationMode.SurfaceShader);
var subGraphOutputNode = subGraphAsset.subGraph.outputNode;
outputString.AddShaderChunk(bodyGenerator.GetShaderString(0), false);
// Step 5...

var inputSlot = subGraphOutputNode.FindInputSlot<MaterialSlot>(slot.name);
var inputValue = subGraphOutputNode.GetSlotValue(inputSlot, generationMode);
var inputValue = subGraphOutputNode.GetSlotValue(inputSlot, GenerationMode.SurfaceShader);
GetOutputVariableNameForSlot(slot)
GetVariableNameForSlot(slot)
+ " = "
+ inputValue
+ ";", false);

shaderBodyVisitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
/* public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
public override void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
m_SubGraphAsset.GenerateVertexToFragmentBlock(visitor, GenerationMode.SurfaceShader);
base.GeneratePropertyBlock(visitor, generationMode);
if (subGraph == null)
return;
subGraph.GeneratePropertyBlock(visitor, GenerationMode.SurfaceShader);
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)
m_SubGraphAsset.GenerateNodeFunction(visitor, GenerationMode.SurfaceShader);
base.GeneratePropertyUsages(visitor, generationMode);
if (subGraph == null)
return;
subGraph.GeneratePropertyUsages(visitor, GenerationMode.SurfaceShader);
public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
public override void CollectPreviewMaterialProperties (List<PreviewProperty> properties)
m_SubGraphAsset.GenerateVertexShaderBlock(visitor, GenerationMode.SurfaceShader);
base.CollectPreviewMaterialProperties(properties);
if (subGraph == null)
return;
properties.AddRange(subGraph.GetPreviewProperties());
public override void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
base.GeneratePropertyBlock(visitor, generationMode);
m_SubGraphAsset.GeneratePropertyBlock(visitor, GenerationMode.SurfaceShader);
if (subGraph == null)
return;
subGraph.GenerateNodeFunction(visitor, GenerationMode.SurfaceShader);
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
base.GeneratePropertyUsages(visitor, generationMode, slotValueType);
m_SubGraphAsset.GeneratePropertyUsages(visitor, GenerationMode.SurfaceShader, slotValueType);
if (subGraph == null)
return;
subGraph.GenerateVertexShaderBlock(visitor, GenerationMode.SurfaceShader);
protected override void CollectPreviewMaterialProperties (List<PreviewProperty> properties)
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
base.CollectPreviewMaterialProperties(properties);
properties.AddRange(m_SubGraphAsset.GetPreviewProperties());
}*/
if (subGraph == null)
return;
subGraph.GenerateVertexToFragmentBlock(visitor, GenerationMode.SurfaceShader);
}
}
}

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


return kErrorString;
var convertFromType = outputSlot.concreteValueType;
var rawOutput = node.GetOutputVariableNameForSlot(outputSlot);
var rawOutput = node.GetVariableNameForSlot(outputSlot);
if (convertFromType == convertToType)
return rawOutput;

if (convertFromType >= convertToType || convertFromType == ConcreteSlotValueType.Vector1)
return AdaptNodeOutput(node, outputSlot, convertToType);
var rawOutput = node.GetOutputVariableNameForSlot(outputSlot);
var rawOutput = node.GetVariableNameForSlot(outputSlot);
// otherwise we need to pad output for the preview!
switch (convertToType)

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

(activeNode as IGeneratesVertexShaderBlock).GenerateVertexShaderBlock(vertexShaderBlock, generationMode);
activeNode.GeneratePropertyBlock(shaderPropertiesVisitor, generationMode);
activeNode.GeneratePropertyUsages(shaderPropertyUsagesVisitor, generationMode, ConcreteSlotValueType.Vector4);
activeNode.GeneratePropertyUsages(shaderPropertyUsagesVisitor, generationMode);
}
if (shaderInputVisitor.numberOfChunks == 0)

7
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IOnAssetEnabled.cs


namespace UnityEngine.Graphing
{
public interface IOnAssetEnabled
{
void OnEnable();
}
}

12
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/IOnAssetEnabled.cs.meta


fileFormatVersion: 2
guid: ed722b1f9c66a7441b3893cec3e3ff4d
timeCreated: 1468409044
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存