浏览代码

[mat graph]Sub graph is working again.

/main
Tim Cooper 8 年前
当前提交
8e10c8cb
共有 13 个文件被更改,包括 220 次插入176 次删除
  1. 4
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/GraphEditWindow.cs
  2. 20
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphIONodeUI.cs
  3. 20
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs
  4. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AddNode.cs
  5. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MaterialSlot.cs
  6. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PropertyNode.cs
  7. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphIONode.cs
  8. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MaterialSubGraphAsset.cs
  9. 73
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs
  10. 179
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs
  11. 18
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphOutputNode.cs
  12. 50
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs
  13. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs.meta

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


{
node = Activator.CreateInstance(posObj.m_Type) as INode;
}
catch
catch (Exception e)
Debug.LogWarningFormat("Could not construct instance of: {0}", posObj.m_Type);
Debug.LogWarningFormat("Could not construct instance of: {0} - {1}", posObj.m_Type, e);
return;
}

20
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphIONodeUI.cs


public float GetNodeUiHeight(float width)
{
return EditorGUIUtility.singleLineHeight;
return 2 * EditorGUIUtility.singleLineHeight;
return GUIModificationType.None;
}
if (m_Node == null)
return GUIModificationType.None;
var modification = GUIModificationType.None;
if (GUI.Button(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), "Add Slot"))
{
m_Node.AddSlot();
modification |= GUIModificationType.ModelChanged;
}
if (GUI.Button(new Rect(area.x, area.y + EditorGUIUtility.singleLineHeight, area.width, EditorGUIUtility.singleLineHeight), "Remove Slot"))
{
m_Node.RemoveSlot();
modification |= GUIModificationType.ModelChanged;
}
return modification;
}
public void SetNode(INode node)
{

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


}
}
protected string GetSlotValue(MaterialSlot inputSlot, GenerationMode generationMode)
public string GetSlotValue(MaterialSlot inputSlot, GenerationMode generationMode)
{
var edges = owner.GetEdges(GetSlotReference(inputSlot.name)).ToArray();

return ShaderGenerator.AdaptNodeOutput(fromNode, slot, inputSlot.concreteValueType);
}
return inputSlot.GetDefaultValue(generationMode, inputSlot.concreteValueType, this);
return inputSlot.GetDefaultValue(generationMode, this);
}
private ConcreteSlotValueType FindCommonChannelType(ConcreteSlotValueType from, ConcreteSlotValueType to)

var pp = new PreviewProperty
{
m_Name = GetDefaultInputNameForSlot(s),
m_Name = GetOutputVariableNameForSlot(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!");
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!");
public virtual string GetDefaultInputNameForSlot(MaterialSlot s)
public virtual string GetInputVariableNameForSlot(MaterialSlot s)
if (s.isOutputSlot) Debug.LogError("Attempting to use output MaterialSlot (" + s + ") for default input!");
if (!GetOutputSlots<MaterialSlot>().Contains(s)) Debug.LogError("Attempting to use MaterialSlot (" + s + ") for default input on a node that does not have this MaterialSlot!");
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!");
return GetVariableNameForNode() + "_" + s.name;
}

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


using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
[Title("Math/Add Node")]

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


if (!generationMode.IsPreview())
return;
visitor.AddShaderChunk("float" + AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(slotValueType) + " " + owner.GetDefaultInputNameForSlot(this) + ";", true);
visitor.AddShaderChunk("float" + AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(slotValueType) + " " + owner.GetInputVariableNameForSlot(this) + ";", true);
public string GetDefaultValue(GenerationMode generationMode, ConcreteSlotValueType slotValueType, AbstractMaterialNode owner)
public string GetDefaultValue(GenerationMode generationMode, AbstractMaterialNode owner)
return owner.GetDefaultInputNameForSlot(this);
return owner.GetInputVariableNameForSlot(this);
switch (slotValueType)
switch (concreteValueType)
{
case ConcreteSlotValueType.Vector1:
return m_CurrentValue.x.ToString();

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


using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{

4
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphIONode.cs


{
public abstract class AbstractSubGraphIONode : AbstractMaterialNode
{
public abstract void AddSlot();
public abstract void RemoveSlot();
/*public void FooterUI(GraphGUI host)
{
// TODO: make it pretty

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


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

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


using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
public class SubGraphInputNode : AbstractSubGraphIONode, IGenerateProperties
public class SubGraphInputNode : AbstractSubGraphIONode
/*
public override void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
public override void AddSlot()
base.GeneratePropertyBlock(visitor, generationMode);
var index = GetOutputSlots<ISlot>().Count();
AddSlot(new MaterialSlot("Input" + index, "Input" + index, SlotType.Output, index, SlotValueType.Vector4, Vector4.zero));
}
if (!generationMode.IsPreview())
public override void RemoveSlot()
{
var index = GetOutputSlots<ISlot>().Count();
if (index == 0)
foreach (var slot in outputSlots)
{
if (slot.edges.Count == 0)
continue;
var defaultValue = GetSlotDefaultValue(slot.name);
if (defaultValue != null)
defaultValue.GeneratePropertyBlock(visitor, generationMode);
}
RemoveSlot("Input" + (index - 1));
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType valueType)
base.GeneratePropertyUsages(visitor, generationMode, slotValueType);
if (!generationMode.IsPreview())
return;
foreach (var slot in outputSlots)
foreach (var slot in GetOutputSlots<MaterialSlot>())
if (slot.edges.Count == 0)
continue;
var defaultValue = GetSlotDefaultValue(slot.name);
if (defaultValue != null)
defaultValue.GeneratePropertyUsages(visitor, generationMode, slotValueType);
var outDimension = ConvertConcreteSlotValueTypeToString(slot.concreteValueType);
visitor.AddShaderChunk("float" + outDimension + " " + GetOutputVariableNameForSlot(slot) + ";", true);
protected override void CollectPreviewMaterialProperties (List<PreviewProperty> properties)
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
foreach (var slot in outputSlots)
foreach (var slot in GetOutputSlots<MaterialSlot>())
if (slot.edges.Count == 0)
continue;
var defaultOutput = GetSlotDefaultValue(slot.name);
if (defaultOutput == null)
continue;
var pp = new PreviewProperty
{
m_Name = defaultOutput.inputName,
m_PropType = PropertyType.Vector4,
m_Vector4 = defaultOutput.defaultValue
};
properties.Add (pp);
properties.Add(
new PreviewProperty
{
m_Name = GetOutputVariableNameForSlot(slot),
m_PropType = PropertyType.Vector4,
m_Vector4 = slot.defaultValue
}
);
}*/
}
}
}

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


/*using System;
using System.Collections.Generic;
using UnityEditor.Graphs;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
//[Title("Sub-graph/Sub-graph Node")]
public class SubGraphNode : BaseMaterialNode, IGeneratesBodyCode, IGeneratesVertexToFragmentBlock, IGeneratesFunction, IGeneratesVertexShaderBlock
[Title("Sub-graph/Sub-graph Node")]
public class SubGraphNode : AbstractMaterialNode, IGeneratesBodyCode
private MaterialSubGraph m_SubGraphAsset;
private MaterialSubGraphAsset m_SubGraphAsset;
public MaterialSubGraph subGraphAsset { get { return m_SubGraphAsset; } }
public override PreviewMode previewMode
public MaterialSubGraphAsset subGraphAsset
get
{
if (subGraphAsset == null)
return PreviewMode.Preview2D;
var nodes = ListPool<BaseMaterialNode>.Get();
var preview3D = subGraphAsset.outputsNode.CollectChildNodesByExecutionOrder(nodes).Any(x => x.previewMode == PreviewMode.Preview3D);
ListPool <BaseMaterialNode >.Release(nodes);
return preview3D ? PreviewMode.Preview3D : PreviewMode.Preview2D;
}
get { return m_SubGraphAsset; }
set { m_SubGraphAsset = value; }
public const int kMaxSlots = 16;
public override void OnCreate()
public SubGraphNode()
base.OnCreate();
position = new Rect(position.x, position.y, Mathf.Max(300, position.width), position.height);
}
static string GetInputSlotName(int n)
{
return string.Format("I{0:00}", n);
UpdateNodeAfterDeserialization();
static string GetOutputSlotName(int n)
public sealed override void UpdateNodeAfterDeserialization()
return string.Format("O{0:00}", n);
}
foreach (var slot in GetSlots<MaterialSlot>().Select(x => x.name).ToArray())
RemoveSlot(slot);
/* public override IEnumerable<Slot> GetValidInputSlots()
{
// We only want to return the input slots that are internally wired to an output slot
return base.GetValidInputSlots().Where(slot => m_SubGraphAsset.InputInternallyWired(slot.name, this)).ToList();
}*
if (m_SubGraphAsset == null)
return;
public override void NodeUI(GraphGUI host)
{
EditorGUI.BeginChangeCheck();
m_SubGraphAsset = (MaterialSubGraph)EditorGUILayout.ObjectField(GUIContent.none, m_SubGraphAsset, typeof(MaterialSubGraph), false);
if (EditorGUI.EndChangeCheck() && m_SubGraphAsset != null)
var subGraphInputNode = m_SubGraphAsset.subGraph.inputNode;
foreach (var slot in subGraphInputNode.GetOutputSlots<MaterialSlot>())
SubGraphChanged(m_SubGraphAsset);
AddSlot(new MaterialSlot(slot.name, slot.displayName, SlotType.Input, slot.priority, slot.valueType, slot.defaultValue ));
}
private void SubGraphChanged(MaterialSubGraph sender)
{
RefreshSlots(SlotType.InputSlot, inputSlots.ToList(), sender.inputsNode.slots, (s) => true);
RefreshSlots(SlotType.OutputSlot, outputSlots.ToList(), sender.outputsNode.slots, sender.OutputInternallyWired);
pixelGraph.RevalidateGraph();
}
private void RefreshSlots(SlotType type, IEnumerable<Slot> current, IEnumerable<Slot> updated, Func<string, bool> slotFilter)
{
var innerOutputSlots = updated.Where(n => slotFilter(n.name)).ToArray();
foreach (var slot in innerOutputSlots)
var subGraphOutputNode = m_SubGraphAsset.subGraph.outputNode;
foreach (var slot in subGraphOutputNode.GetInputSlots<MaterialSlot>())
var s = current.FirstOrDefault(n => n.name == slot.name);
if (s != null)
s.title = slot.title;
// else
// AddSlot(new Slot(type, slot.name, slot.title));
AddSlot(new MaterialSlot(slot.name, slot.displayName, SlotType.Output, slot.priority, slot.valueType, slot.defaultValue));
var danglingSlots = current.Except(innerOutputSlots, (ls, rs) => ls.name == rs.name).ToArray();
foreach (var slot in danglingSlots)
RemoveSlot(slot);
}
public void GenerateNodeCode(ShaderGenerator shaderBodyVisitor, GenerationMode generationMode)

var outputString = new ShaderGenerator();
outputString.AddShaderChunk("// Subgraph for node " + GetOutputVariableNameForNode(), false);
outputString.AddShaderChunk("// Subgraph for node " + GetVariableNameForNode(), false);
var validOutputSlots = outputSlots.Where(x => x.edges.Count > 0);
foreach (var slot in validOutputSlots)
foreach (var slot in GetOutputSlots<MaterialSlot>())
var outDimension = ConvertConcreteSlotValueTypeToString(slot.concreteValueType);
"float4 "
+ GetOutputVariableNameForSlot(slot, generationMode)
+ " = float4(0, 0, 0, 0);", false);
"float"
+ outDimension
+ " "
+ GetOutputVariableNameForSlot(slot)
+ " = 0;", false);
}
// Step 2...

// 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
foreach (var slot in slots)
var subGraphInputNode = m_SubGraphAsset.subGraph.inputNode;
foreach (var slot in GetInputSlots<MaterialSlot>())
if (!slot.isInputSlot)
continue;
var varName = subGraphInputNode.GetOutputVariableNameForSlot(subGraphInputNode.FindOutputSlot<MaterialSlot>(slot.name));
var varValue = GetSlotValue(slot, generationMode);
// see if the input connects all the way though to the output
// if it does allow generation
var inputWired = m_SubGraphAsset.InputInternallyWired(slot.name, this);
if (!inputWired)
continue;
var varName = m_SubGraphAsset.GetInputVariableNameForSlotByName(slot.name, this, generationMode);
var varValue = "float4(0, 0, 0, 0);";
var slotDefaultValue = GetSlotDefaultValue(slot.name);
if (slotDefaultValue != null)
{
varValue = slotDefaultValue.GetDefaultValue(generationMode, concreteInputSlotValueTypes[slot.name]);
}
bool externallyWired = slot.edges.Count > 0;
if (externallyWired)
{
var fromSlot = slot.edges[0].fromSlot;
var fromNode = slot.edges[0].fromSlot.node as BaseMaterialNode;
varValue = fromNode.GetOutputVariableNameForSlot(fromSlot, generationMode);
}
outputString.AddShaderChunk("float4 " + varName + " = " + varValue + ";", false);
var outDimension = ConvertConcreteSlotValueTypeToString(slot.concreteValueType);
outputString.AddShaderChunk(
"float"
+ outDimension
+ " "
+ varName
+ " = "
+ varValue
+ ";", false);
m_SubGraphAsset.GenerateNodeCode(bodyGenerator, this);
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);
foreach (var slot in validOutputSlots)
foreach (var slot in GetOutputSlots<MaterialSlot>())
bool internallyWired = m_SubGraphAsset.OutputInternallyWired(slot.name);
if (internallyWired)
{
outputString.AddShaderChunk(
GetOutputVariableNameForSlot(slot, generationMode)
+ " = "
+ m_SubGraphAsset.GetOutputVariableNameForSlotByName(slot.name, this, generationMode)
+ ";", false);
}
var inputSlot = subGraphOutputNode.FindInputSlot<MaterialSlot>(slot.name);
var inputValue = subGraphOutputNode.GetSlotValue(inputSlot, generationMode);
outputString.AddShaderChunk(
GetOutputVariableNameForSlot(slot)
+ " = "
+ inputValue
+ ";", false);
}
outputString.Deindent();

shaderBodyVisitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
/* public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
m_SubGraphAsset.GenerateVertexToFragmentBlock(visitor, GenerationMode.SurfaceShader);
}

{
base.CollectPreviewMaterialProperties(properties);
properties.AddRange(m_SubGraphAsset.GetPreviewProperties());
}
}*/
}*/
}

18
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphOutputNode.cs


using System.Linq;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
public class SubGraphOutputNode : AbstractSubGraphIONode

name = "SubGraphOutputs";
}
public override void AddSlot()
{
var index = GetInputSlots<ISlot>().Count();
AddSlot(new MaterialSlot("Output" + index, "Output" + index, SlotType.Input, index, SlotValueType.Vector4, Vector4.zero));
}
public override void RemoveSlot()
{
var index = GetInputSlots<ISlot>().Count();
if (index == 0)
return;
RemoveSlot("Output" + (index - 1));
}
}
}

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


using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(SubGraphNode))]
public class SubgraphNodeUI : ICustomNodeUi
{
private SubGraphNode m_Node;
public float GetNodeUiHeight(float width)
{
return 1 * EditorGUIUtility.singleLineHeight;
}
public GUIModificationType Render(Rect area)
{
if (m_Node == null)
return GUIModificationType.None;
EditorGUI.BeginChangeCheck();
m_Node.subGraphAsset = (MaterialSubGraphAsset) EditorGUI.ObjectField(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight),
new GUIContent("SubGraph"),
m_Node.subGraphAsset,
typeof(MaterialSubGraphAsset), false);
if (EditorGUI.EndChangeCheck())
{
m_Node.UpdateNodeAfterDeserialization();
return GUIModificationType.ModelChanged;
}
return GUIModificationType.None;
}
public void SetNode(INode node)
{
if (node is SubGraphNode)
m_Node = (SubGraphNode) node;
}
public float GetNodeWidth()
{
return 200;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/SubGraphNodeUI.cs.meta


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