浏览代码

[material graph]Moving namespaces / extract things to interface

/main
Tim Cooper 9 年前
当前提交
404ea34c
共有 136 个文件被更改,包括 155 次插入3093 次删除
  1. 5
      UnityProject/Assets/UnityShaderEditor/Editor/Source/AbstractMaterialGraph.cs
  2. 9
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs
  3. 5
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs
  4. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/BaseLightFunction.cs
  5. 7
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbstractMaterialNode.cs
  6. 1
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function2Input.cs
  7. 1
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaterialSlot.cs
  8. 5
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs
  9. 1
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs
  10. 5
      UnityProject/Assets/UnityShaderEditor/Editor/Source/PixelGraph.cs
  11. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/Edge.cs
  12. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/GUIModificationType.cs
  13. 20
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs
  14. 49
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs
  15. 30
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs
  16. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs
  17. 11
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs
  18. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotType.cs
  19. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/ListPool.cs
  20. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/Logging.cs
  21. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/ObjectPool.cs
  22. 3
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/SerializationHelper.cs
  23. 3
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/ShaderGenerator.cs
  24. 1
      UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/AbstractMaterialGraphTests.cs
  25. 1
      UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs
  26. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/IEdge.cs
  27. 19
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/IGraph.cs
  28. 24
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/INode.cs
  29. 10
      UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/ISlot.cs
  30. 49
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/SimpleSpecularFunction.cs
  31. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/SimpleSpecularFunction.cs.meta
  32. 48
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/WrapLambertFunction.cs
  33. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/WrapLambertFunction.cs.meta
  34. 30
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbsoluteNode.cs
  35. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbsoluteNode.cs.meta
  36. 819
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs
  37. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs.meta
  38. 76
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BlendNode.cs
  39. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BlendNode.cs.meta
  40. 30
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ClampNode.cs
  41. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ClampNode.cs.meta
  42. 74
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorNode.cs
  43. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorNode.cs.meta
  44. 72
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorizeNode.cs
  45. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorizeNode.cs.meta
  46. 124
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/CombineNode.cs
  47. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/CombineNode.cs.meta
  48. 30
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/DivNode.cs
  49. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/DivNode.cs.meta
  50. 33
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/DotNode.cs
  51. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/DotNode.cs.meta
  52. 47
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Extensions.cs
  53. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Extensions.cs.meta
  54. 31
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/FresnelNode.cs
  55. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/FresnelNode.cs.meta
  56. 73
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function1Input.cs
  57. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function1Input.cs.meta
  58. 132
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function3Input.cs
  59. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function3Input.cs.meta
  60. 84
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/FunctionMultiInput.cs
  61. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/FunctionMultiInput.cs.meta
  62. 96
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/KaleidoscopeNode.cs
  63. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/KaleidoscopeNode.cs.meta
  64. 14
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/LengthNode.cs
  65. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/LengthNode.cs.meta
  66. 102
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MandelbrotNode.cs
  67. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MandelbrotNode.cs.meta
  68. 14
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaxNode.cs
  69. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaxNode.cs.meta
  70. 14
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MinNode.cs
  71. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MinNode.cs.meta
  72. 35
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MultiplyNode.cs
  73. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MultiplyNode.cs.meta
  74. 36
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/NormalNode.cs
  75. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/NormalNode.cs.meta
  76. 14
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/NormalizeNode.cs
  77. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/NormalizeNode.cs.meta
  78. 104
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PerlinNode.cs
  79. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PerlinNode.cs.meta
  80. 16
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PowerNode.cs
  81. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PowerNode.cs.meta
  82. 30
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/QuantizeNode.cs
  83. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/QuantizeNode.cs.meta
  84. 38
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ReflectNode.cs
  85. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ReflectNode.cs.meta
  86. 38
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ScreenPosNode.cs
  87. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ScreenPosNode.cs.meta
  88. 14
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinNode.cs
  89. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinNode.cs.meta
  90. 32
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinTimeNode.cs
  91. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinTimeNode.cs.meta
  92. 30
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SmoothStepNode.cs
  93. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SmoothStepNode.cs.meta
  94. 42
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphIOBaseNode.cs
  95. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphIOBaseNode.cs.meta
  96. 80
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphInputsNode.cs
  97. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphInputsNode.cs.meta
  98. 208
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphNode.cs
  99. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphNode.cs.meta
  100. 21
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphOutputsNode.cs

5
UnityProject/Assets/UnityShaderEditor/Editor/Source/AbstractMaterialGraph.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphing;
public abstract class AbstractMaterialGraph : SerializableGraph
public abstract class AbstractMaterialGraph : Graphing.SerializableGraph
{
[NonSerialized]
private PreviewRenderUtility m_PreviewUtility;

get { return nodes.Any(x => x is IRequiresTime); }
}
public override void AddNode(SerializableNode node)
public override void AddNode(INode node)
{
if (node is AbstractMaterialNode)
{

9
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs


using System.Linq;
using UnityEditor.Experimental;
using UnityEditor.Experimental.Graph;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.MaterialGraph

private bool MarkDirtyIfNeedsTime(CanvasElement element, Event e, Canvas2D parent)
{
var childrenNodes = ListPool<SerializableNode>.Get();
var childrenNodes = ListPool<INode>.Get();
ListPool<SerializableNode>.Release(childrenNodes);
ListPool<INode>.Release(childrenNodes);
return true;
}

public static void RepaintDependentNodes(AbstractMaterialNode bmn)
{
var dependentNodes = new List<SerializableNode>();
var dependentNodes = new List<INode>();
foreach (var node in dependentNodes)
foreach (var node in dependentNodes.OfType<SerializableNode>())
node.onNeedsRepaint();
}

5
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs


using System.Linq;
using UnityEditor.Experimental;
using UnityEditor.Experimental.Graph;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.MaterialGraph

public void DeleteElements(List<CanvasElement> elements)
{
var toRemoveEdge = new List<Edge>();
var toRemoveEdge = new List<IEdge>();
// delete selected edges first
foreach (var e in elements.Where(x => x is Edge<NodeAnchor>))
{

toRemoveEdge.Add(edge);
}
var toRemoveNode = new List<SerializableNode>();
var toRemoveNode = new List<INode>();
// now delete the nodes
foreach (var e in elements.Where(x => x is DrawableMaterialNode))
{

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


using UnityEditor.Graphs;
using SlotType = UnityEditor.Graphing.SlotType;
namespace UnityEditor.MaterialGraph
{

7
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbstractMaterialNode.cs


using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor.Graphing;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;

public static void UpdateMaterialProperties(AbstractMaterialNode target, Material material)
{
var childNodes = ListPool<SerializableNode>.Get();
var childNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(childNodes, target);
var pList = ListPool<PreviewProperty>.Get();

foreach (var prop in pList)
SetPreviewMaterialProperty(prop, material);
ListPool<SerializableNode>.Release(childNodes);
ListPool<INode>.Release(childNodes);
ListPool<PreviewProperty>.Release(pList);
}

return name + "_" + guid.ToString().Replace("-", "_");
}
public sealed override void AddSlot(SerializableSlot slot)
public sealed override void AddSlot(ISlot slot)
{
if (!(slot is MaterialSlot))
{

1
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function2Input.cs


using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.MaterialGraph

1
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.MaterialGraph

5
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs


using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor.Graphing;
namespace UnityEditor.MaterialGraph
{

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

(node as IGeneratesBodyCode).GenerateNodeCode(shaderBody, generationMode);
}
ListPool<SerializableNode>.Release(nodes);
ListPool<INode>.Release(nodes);
foreach (var slot in inputSlots)
{

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


using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.MaterialGraph

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


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

}
[NonSerialized]
private List<SerializableNode> m_ActiveNodes = new List<SerializableNode>();
private List<INode> m_ActiveNodes = new List<INode>();
public IEnumerable<AbstractMaterialNode> activeNodes
{
get

m_PixelMasterNode = null;
}
public override void AddNode(SerializableNode node)
public override void AddNode(INode node)
{
if (pixelMasterNode != null && node is PixelShaderNode)
{

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/Edge.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
public class Edge
public class Edge : IEdge
{
[SerializeField]
private SlotReference m_OutputSlot;

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/GUIModificationType.cs


namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
{
public enum GUIModificationType
{

20
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/NodeUtils.cs


using System.Linq;
using UnityEngine;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
{
internal class NodeUtils
{

public static List<SerializableSlot> GetSlotsThatOutputToNodeRecurse(SerializableNode fromNode, SerializableNode toNode)
public static List<ISlot> GetSlotsThatOutputToNodeRecurse(INode fromNode, INode toNode)
var foundUsedOutputSlots = new List<SerializableSlot>();
var foundUsedOutputSlots = new List<ISlot>();
public static void RecurseNodesToFindValidOutputSlots(SerializableNode fromNode, SerializableNode currentNode, ICollection<SerializableSlot> foundUsedOutputSlots)
public static void RecurseNodesToFindValidOutputSlots(INode fromNode, INode currentNode, ICollection<ISlot> foundUsedOutputSlots)
{
if (fromNode == null || currentNode == null)
{

var validSlots = ListPool<SerializableSlot>.Get();
var validSlots = ListPool<ISlot>.Get();
validSlots.AddRange(currentNode.inputSlots);
for (int index = 0; index < validSlots.Count; index++)
{

RecurseNodesToFindValidOutputSlots(fromNode, outputNode, foundUsedOutputSlots);
}
}
ListPool<SerializableSlot>.Release(validSlots);
ListPool<ISlot>.Release(validSlots);
}
// CollectNodesNodeFeedsInto looks at the current node and calculates

public static void DepthFirstCollectNodesFromNode(List<SerializableNode> nodeList, SerializableNode node, SerializableSlot slotToUse = null, bool includeSelf = true)
public static void DepthFirstCollectNodesFromNode(List<INode> nodeList, INode node, ISlot slotToUse = null, bool includeSelf = true)
{
// no where to start
if (node == null)

if (slotToUse != null && node.inputSlots.All(x => x.name != slotToUse.name))
return;
var validSlots = ListPool<SerializableSlot>.Get();
var validSlots = ListPool<ISlot>.Get();
if (slotToUse != null)
validSlots.Add(slotToUse);
else

if (includeSelf)
nodeList.Add(node);
ListPool<SerializableSlot>.Release(validSlots);
ListPool<ISlot>.Release(validSlots);
public static void CollectNodesNodeFeedsInto(List<SerializableNode> nodeList, SerializableNode node, bool includeSelf = true)
public static void CollectNodesNodeFeedsInto(List<INode> nodeList, INode node, bool includeSelf = true)
{
if (node == null)
return;

49
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableGraph.cs


using System.Linq;
using UnityEngine;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
public class SerializableGraph : ISerializationCallbackReceiver
public class SerializableGraph : IGraph, ISerializationCallbackReceiver
[SerializeField]
private List<Edge> m_Edges = new List<Edge>();
[NonSerialized]
private List<IEdge> m_Edges = new List<IEdge>();
private List<SerializableNode> m_Nodes = new List<SerializableNode>();
private List<INode> m_Nodes = new List<INode>();
public IEnumerable<SerializableNode> nodes
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableEdges = new List<SerializationHelper.JSONSerializedElement>();
public IEnumerable<INode> nodes
public IEnumerable<Edge> edges
public IEnumerable<IEdge> edges
public virtual void AddNode(SerializableNode node)
public virtual void AddNode(INode node)
public virtual void RemoveNode(SerializableNode node)
public virtual void RemoveNode(INode node)
{
if (!node.canDeleteNode)
return;

}
private void RemoveNodeNoValidate(SerializableNode node)
private void RemoveNodeNoValidate(INode node)
{
if (!node.canDeleteNode)
return;

public virtual Edge Connect(SlotReference fromSlotRef, SlotReference toSlotRef)
public virtual IEdge Connect(SlotReference fromSlotRef, SlotReference toSlotRef)
SerializableNode fromNode = GetNodeFromGuid(fromSlotRef.nodeGuid);
SerializableNode toNode = GetNodeFromGuid(toSlotRef.nodeGuid);
var fromNode = GetNodeFromGuid(fromSlotRef.nodeGuid);
var toNode = GetNodeFromGuid(toSlotRef.nodeGuid);
SerializableSlot fromSlot = fromNode.FindSlot(fromSlotRef.slotName);
SerializableSlot toSlot = toNode.FindSlot(toSlotRef.slotName);
var fromSlot = fromNode.FindSlot(fromSlotRef.slotName);
var toSlot = toNode.FindSlot(toSlotRef.slotName);
SlotReference outputSlot = null;
SlotReference inputSlot = null;

return newEdge;
}
public virtual void RemoveEdge(Edge e)
public virtual void RemoveEdge(IEdge e)
public void RemoveElements(IEnumerable<SerializableNode> nodes, IEnumerable<Edge> edges)
public void RemoveElements(IEnumerable<INode> nodes, IEnumerable<IEdge> edges)
{
foreach (var edge in edges.ToArray())
RemoveEdgeNoValidate(edge);

ValidateGraph();
}
private void RemoveEdgeNoValidate(Edge e)
private void RemoveEdgeNoValidate(IEdge e)
public SerializableNode GetNodeFromGuid(Guid guid)
public INode GetNodeFromGuid(Guid guid)
public IEnumerable<Edge> GetEdges(SlotReference s)
public IEnumerable<IEdge> GetEdges(SlotReference s)
{
if (s == null)
return new Edge[0];

public virtual void OnBeforeSerialize()
{
m_SerializableNodes = SerializationHelper.Serialize(m_Nodes);
m_SerializableEdges = SerializationHelper.Serialize(m_Edges);
m_Nodes = SerializationHelper.Deserialize<SerializableNode>(m_SerializableNodes, new object[] {this});
m_Nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes, new object[] { this });
m_Edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges, new object[] { });
m_SerializableEdges = null;
ValidateGraph();
}

30
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableNode.cs


using System.Linq;
using UnityEngine;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
public class SerializableNode : ISerializationCallbackReceiver
public class SerializableNode : ISerializationCallbackReceiver, INode
{
public delegate void NeedsRepaint();
public NeedsRepaint onNeedsRepaint;

private Rect m_Position;
[NonSerialized]
private List<SerializableSlot> m_Slots = new List<SerializableSlot>();
private List<ISlot> m_Slots = new List<ISlot>();
public SerializableGraph owner { get; set; }
public IGraph owner { get; set; }
public Guid guid
{

set { m_Position = value; }
}
public IEnumerable<SerializableSlot> inputSlots
public IEnumerable<ISlot> inputSlots
public IEnumerable<SerializableSlot> outputSlots
public IEnumerable<ISlot> outputSlots
public IEnumerable<SerializableSlot> slots
public IEnumerable<ISlot> slots
{
get { return m_Slots; }
}

m_Guid = Guid.NewGuid();
}
public virtual void AddSlot(SerializableSlot slot)
public virtual void AddSlot(ISlot slot)
{
if (slot == null)
return;

return new SlotReference(guid, name);
}
public SerializableSlot FindSlot(string name)
public ISlot FindSlot(string name)
{
var slot = slots.FirstOrDefault(x => x.name == name);
if (slot == null)

public SerializableSlot FindInputSlot(string name)
public ISlot FindInputSlot(string name)
{
var slot = inputSlots.FirstOrDefault(x => x.name == name);
if (slot == null)

public SerializableSlot FindOutputSlot(string name)
public ISlot FindOutputSlot(string name)
{
var slot = outputSlots.FirstOrDefault(x => x.name == name);
if (slot == null)

return modified;
}
public static bool DoSlotUI(SerializableNode node, SerializableSlot slot)
public static bool DoSlotUI(SerializableNode node, ISlot slot)
{
GUILayout.BeginHorizontal( /*EditorStyles.inspectorBig*/);
GUILayout.BeginVertical();

GUILayout.EndVertical();
GUILayout.EndHorizontal();
return slot.OnGUI();
//TODO: fix this
return false;
//return slot.OnGUI();
}
public virtual void OnBeforeSerialize()

else
m_Guid = Guid.NewGuid();
m_Slots = SerializationHelper.Deserialize<SerializableSlot>(m_SerializableSlots, new object[] { this });
m_Slots = SerializationHelper.Deserialize<ISlot>(m_SerializableSlots, new object[] { this });
m_SerializableSlots = null;
}
}

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SerializableSlot.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
public class SerializableSlot
public class SerializableSlot : ISlot
{
private const string kNotInit = "Not Initilaized";

11
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotReference.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
{
[Serializable]
public class SlotReference : ISerializationCallbackReceiver

m_NodeGUID = nodeGuid;
m_SlotName = slotName;
m_NodeGUIDSerialized = string.Empty;
}
public static SerializableSlot ToSerializableSlot(SerializableGraph graph, SlotReference slotRef)
{
var node = graph.GetNodeFromGuid(slotRef.nodeGuid);
if (node == null)
return null;
return node.FindSlot(slotRef.slotName);
}
public Guid nodeGuid

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/SlotType.cs


namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
{
public enum SlotType
{

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/ListPool.cs


using System.Collections.Generic;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
{
internal static class ListPool<T>
{

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/Logging.cs


using System;
using UnityEngine;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
{
public class ConsoleLogHandler : ILogHandler
{

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/ObjectPool.cs


using UnityEngine;
using UnityEngine.Events;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
{
internal class ObjectPool<T> where T : new()
{

3
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/SerializationHelper.cs


using System;
using System.Collections.Generic;
using System.Reflection;
namespace UnityEditor.MaterialGraph
namespace UnityEditor.Graphing
{
public static class SerializationHelper
{

3
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/ShaderGenerator.cs


using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.MaterialGraph

public static string GeneratePreviewShader(AbstractMaterialNode node, out PreviewMode generatedShaderMode)
{
// figure out what kind of preview we want!
var activeNodeList = ListPool<SerializableNode>.Get();
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
var generationMode = GenerationMode.Preview2D;
generatedShaderMode = PreviewMode.Preview2D;

1
UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/AbstractMaterialGraphTests.cs


using System.Linq;
using NUnit.Framework;
using UnityEditor.Graphing;
namespace UnityEditor.MaterialGraph.Tests
{

1
UnityProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/SerializedGraphTests.cs


using System;
using System.Linq;
using NUnit.Framework;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.MaterialGraph.Tests

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/IEdge.cs


namespace UnityEditor.Graphing
{
public interface IEdge
{
SlotReference outputSlot { get; }
SlotReference inputSlot { get; }
}
}

19
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/IGraph.cs


using System;
using System.Collections.Generic;
namespace UnityEditor.Graphing
{
public interface IGraph
{
IEnumerable<INode> nodes { get; }
IEnumerable<IEdge> edges { get; }
void AddNode(INode node);
void RemoveNode(INode node);
IEdge Connect(SlotReference fromSlotRef, SlotReference toSlotRef);
void RemoveEdge(IEdge e);
void RemoveElements(IEnumerable<INode> nodes, IEnumerable<IEdge> edges);
INode GetNodeFromGuid(Guid guid);
IEnumerable<IEdge> GetEdges(SlotReference s);
void ValidateGraph();
}
}

24
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/INode.cs


using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Graphing
{
public interface INode
{
IGraph owner { get; set; }
Guid guid { get; }
string name { get; set; }
bool canDeleteNode { get; }
Rect position { get; set; }
IEnumerable<ISlot> inputSlots { get; }
IEnumerable<ISlot> outputSlots { get; }
IEnumerable<ISlot> slots { get; }
void AddSlot(ISlot slot);
void RemoveSlot(string name);
SlotReference GetSlotReference(string name);
ISlot FindSlot(string name);
ISlot FindInputSlot(string name);
ISlot FindOutputSlot(string name);
}
}

10
UnityProject/Assets/UnityShaderEditor/Editor/Source/SerializableGraph/ISlot.cs


namespace UnityEditor.Graphing
{
public interface ISlot
{
string name { get; }
string displayName { get; set; }
bool isInputSlot { get; }
bool isOutputSlot { get; }
}
}

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


using UnityEditor.Graphs;
namespace UnityEditor.MaterialGraph
{
class SimpleSpecularFunction : BaseLightFunction
{
public const string kAlbedoSlotName = "Albedo";
public const string kAlphaSlotName = "Alpha";
public override string GetLightFunctionName() { return "SimpleSpecular"; }
public override string GetSurfaceOutputStructureName() {return "SurfaceOutput";}
public override void GenerateLightFunctionBody(ShaderGenerator visitor)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk("half4 Lighting" + GetLightFunctionName() + " (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("half3 h = normalize (lightDir + viewDir);", false);
outputString.AddShaderChunk("half diff = max (0, dot (s.Normal, lightDir));", false);
outputString.AddShaderChunk("half nh = max (0, dot (s.Normal, h));", false);
outputString.AddShaderChunk("half spec = pow (nh, 48.0);", false);
outputString.AddShaderChunk("half4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten * 2);", false);
outputString.AddShaderChunk("c.a = s.Alpha;", false);
outputString.AddShaderChunk("return c;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public override void DoSlotsForConfiguration(PixelShaderNode node)
{
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
node.RemoveSlotsNameNotMatching(
new[]
{
kAlbedoSlotName,
kNormalSlotName,
kAlphaSlotName
});
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/SimpleSpecularFunction.cs.meta


fileFormatVersion: 2
guid: 241a90386f89a7f4da1ca187a0dd3eb2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

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


using UnityEditor.Graphs;
namespace UnityEditor.MaterialGraph
{
class WrapLambertFunction : BaseLightFunction
{
public const string kAlbedoSlotName = "Albedo";
public const string kAlphaSlotName = "Alpha";
public override string GetLightFunctionName() { return "WrapLambert"; }
public override string GetSurfaceOutputStructureName() { return "SurfaceOutput"; }
public override void GenerateLightFunctionBody(ShaderGenerator visitor)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk("half4 Lighting" + GetLightFunctionName() + " (SurfaceOutput s, half3 lightDir, half atten)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("half NdotL = dot (s.Normal, lightDir);", false);
outputString.AddShaderChunk("half diff = NdotL * 0.5 + 0.5;", false);
outputString.AddShaderChunk("half4 c;", false);
outputString.AddShaderChunk("c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);", false);
outputString.AddShaderChunk("c.a = s.Alpha;", false);
outputString.AddShaderChunk("return c;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public override void DoSlotsForConfiguration(PixelShaderNode node)
{
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
node.RemoveSlotsNameNotMatching(new[]
{
kAlbedoSlotName,
kNormalSlotName,
kAlphaSlotName
});
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/WrapLambertFunction.cs.meta


fileFormatVersion: 2
guid: 4ed268fcd50cca74489ba39307e33e63
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

30
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbsoluteNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Absolute Node")]
class AbsoluteNode : Function1Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "AbsoluteNode";
base.OnCreate();
}
protected override string GetFunctionName() {return "unity_absolute_" + precision; }
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + outputDimension + " unity_absolute_" + precision + " (" + precision + outputDimension + " arg1)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return abs(arg1);", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/AbsoluteNode.cs.meta


fileFormatVersion: 2
guid: 4b496ffd32c22d94bb525897d152da05
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

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


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph
{
[Serializable]
public abstract class BaseMaterialNode : IGenerateProperties, ISerializationCallbackReceiver
{
[Serializable]
protected class NodeSpecificData
{ }
public delegate void NeedsRepaint();
private const int kPreviewWidth = 64;
private const int kPreviewHeight = 64;
private static readonly Mesh[] s_Meshes = {null, null, null, null};
[SerializeField]
private DrawMode m_DrawMode = DrawMode.Full;
protected PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D;
[NonSerialized]
private Guid m_GUID;
[SerializeField]
private string m_GUIDSerialized;
[NonSerialized]
private bool m_HasError;
[SerializeField]
private string m_LastShader;
[SerializeField]
private string m_Name;
[SerializeField]
private Rect m_Position;
[NonSerialized]
private Material m_PreviewMaterial;
[NonSerialized]
private Shader m_PreviewShader;
[SerializeField]
private List<Slot> m_Slots = new List<Slot>();
public NeedsRepaint onNeedsRepaint;
protected BaseMaterialNode(BaseMaterialGraph theOwner)
{
owner = theOwner;
m_GUID = Guid.NewGuid();
}
public Guid guid
{
get { return m_GUID; }
}
public string name
{
get { return m_Name; }
set { m_Name = value; }
}
public string precision
{
get { return "half"; }
}
public string[] m_PrecisionNames = { "half" };
public BaseMaterialGraph owner { get; set; }
public IEnumerable<Slot> inputSlots
{
get { return m_Slots.Where(x => x.isInputSlot); }
}
public IEnumerable<Slot> outputSlots
{
get { return m_Slots.Where(x => x.isOutputSlot); }
}
public IEnumerable<Slot> slots
{
get { return m_Slots; }
}
// 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; }
}
public DrawMode drawMode
{
get { return m_DrawMode; }
set { m_DrawMode = value; }
}
protected virtual bool generateDefaultInputs
{
get { return true; }
}
public virtual bool canDeleteNode
{
get { return true; }
}
public Material previewMaterial
{
get
{
if (m_PreviewMaterial == null)
{
m_PreviewMaterial = new Material(m_PreviewShader) {hideFlags = HideFlags.HideInHierarchy};
m_PreviewMaterial.hideFlags = HideFlags.HideInHierarchy;
}
return m_PreviewMaterial;
}
}
protected virtual int previewWidth
{
get { return kPreviewWidth; }
}
protected virtual int previewHeight
{
get { return kPreviewHeight; }
}
public bool hasError
{
get
{
return m_HasError;
}
protected set
{
if (m_HasError != value)
{
m_HasError = value;
ExecuteRepaint();
}
}
}
public Rect position
{
get
{
return m_Position;
}
set
{
m_Position = value;
}
}
public virtual void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
{}
public virtual void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
{
if (!generateDefaultInputs)
return;
if (!generationMode.IsPreview())
return;
foreach (var inputSlot in inputSlots)
{
var edges = owner.GetEdges(inputSlot);
if (edges.Any())
continue;
inputSlot.GeneratePropertyUsages(visitor, generationMode, inputSlot.concreteValueType, this);
}
}
public virtual void OnBeforeSerialize()
{
m_GUIDSerialized = m_GUID.ToString();
}
public virtual void OnAfterDeserialize()
{
if (!string.IsNullOrEmpty(m_GUIDSerialized))
m_GUID = new Guid(m_GUIDSerialized);
else
m_GUID = Guid.NewGuid();
//patch up the slot owner reference
foreach (var slot in slots)
slot.owner = this;
}
public virtual float GetNodeUIHeight(float width)
{
return 0;
}
public virtual GUIModificationType NodeUI(Rect drawArea)
{
return GUIModificationType.None;
}
protected virtual void OnPreviewGUI()
{
if (!ShaderUtil.hardwareSupportsRectRenderTexture)
return;
GUILayout.BeginHorizontal(GUILayout.MinWidth(previewWidth + 10), GUILayout.MinWidth(previewHeight + 10));
GUILayout.FlexibleSpace();
var rect = GUILayoutUtility.GetRect(previewWidth, previewHeight, GUILayout.ExpandWidth(false));
var preview = RenderPreview(rect);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GL.sRGBWrite = QualitySettings.activeColorSpace == ColorSpace.Linear;
GUI.DrawTexture(rect, preview, ScaleMode.StretchToFill, false);
GL.sRGBWrite = false;
}
public Slot FindInputSlot(string 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;
}
public Slot FindOutputSlot(string 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;
}
protected string GetSlotValue(Slot inputSlot, GenerationMode generationMode)
{
var edges = owner.GetEdges(inputSlot).ToArray();
if (edges.Length > 0)
{
var fromSocketRef = edges[0].outputSlot;
var fromNode = owner.GetNodeFromGUID(fromSocketRef.nodeGuid);
var slot = fromNode.FindOutputSlot(fromSocketRef.slotName);
return ShaderGenerator.AdaptNodeOutput(this, slot, generationMode, inputSlot.concreteValueType);
}
return inputSlot.GetDefaultValue(generationMode, inputSlot.concreteValueType, this);
}
public void RemoveSlotsNameNotMatching(string[] slotNames)
{
var invalidSlots = m_Slots.Select(x => x.name).Except(slotNames);
foreach (var invalidSlot in invalidSlots.ToList())
{
Debug.LogWarningFormat("Removing Invalid Slot: {0}", invalidSlot);
RemoveSlot(invalidSlot);
}
}
private ConcreteSlotValueType FindCommonChannelType(ConcreteSlotValueType @from, ConcreteSlotValueType to)
{
if (ImplicitConversionExists(@from, to))
return to;
return ConcreteSlotValueType.Error;
}
private static ConcreteSlotValueType ToConcreteType(SlotValueType svt)
{
switch (svt)
{
case SlotValueType.Vector1:
return ConcreteSlotValueType.Vector1;
case SlotValueType.Vector2:
return ConcreteSlotValueType.Vector2;
case SlotValueType.Vector3:
return ConcreteSlotValueType.Vector3;
case SlotValueType.Vector4:
return ConcreteSlotValueType.Vector4;
}
return ConcreteSlotValueType.Error;
}
private static bool ImplicitConversionExists(ConcreteSlotValueType from, ConcreteSlotValueType to)
{
return from >= to || from == ConcreteSlotValueType.Vector1;
}
protected virtual ConcreteSlotValueType ConvertDynamicInputTypeToConcrete(IEnumerable<ConcreteSlotValueType> inputTypes)
{
var concreteSlotValueTypes = inputTypes as IList<ConcreteSlotValueType> ?? inputTypes.ToList();
if (concreteSlotValueTypes.Any(x => x == ConcreteSlotValueType.Error))
return ConcreteSlotValueType.Error;
var inputTypesDistinct = concreteSlotValueTypes.Distinct().ToList();
switch (inputTypesDistinct.Count)
{
case 0:
return ConcreteSlotValueType.Vector1;
case 1:
return inputTypesDistinct.FirstOrDefault();
default:
// find the 'minumum' channel width excluding 1 as it can promote
inputTypesDistinct.RemoveAll(x => x == ConcreteSlotValueType.Vector1);
var ordered = inputTypesDistinct.OrderBy(x => x);
if (ordered.Any())
return ordered.FirstOrDefault();
break;
}
return ConcreteSlotValueType.Error;
}
public void ValidateNode()
{
var isInError = false;
// all children nodes needs to be updated first
// so do that here
foreach (var inputSlot in inputSlots)
{
var edges = owner.GetEdges(inputSlot);
foreach (var edge in edges)
{
var fromSocketRef = edge.outputSlot;
var outputNode = owner.GetNodeFromGUID(fromSocketRef.nodeGuid);
outputNode.ValidateNode();
if (outputNode.hasError)
isInError = true;
}
}
var dynamicInputSlotsToCompare = new Dictionary<Slot, ConcreteSlotValueType>();
var skippedDynamicSlots = new List<Slot>();
// iterate the input slots
foreach (var inputSlot in inputSlots)
{
var inputType = inputSlot.valueType;
// if there is a connection
var edges = owner.GetEdges(inputSlot).ToList();
if (!edges.Any())
{
if (inputType != SlotValueType.Dynamic)
inputSlot.concreteValueType = ToConcreteType(inputType);
else
skippedDynamicSlots.Add(inputSlot);
continue;
}
// get the output details
var outputSlotRef = edges[0].outputSlot;
var outputNode = owner.GetNodeFromGUID(outputSlotRef.nodeGuid);
var outputSlot = outputNode.FindOutputSlot(outputSlotRef.slotName);
var outputConcreteType = outputSlot.concreteValueType;
// if we have a standard connection... just check the types work!
if (inputType != SlotValueType.Dynamic)
{
var inputConcreteType = ToConcreteType(inputType);
inputSlot.concreteValueType = FindCommonChannelType(outputConcreteType, inputConcreteType);
continue;
}
// dynamic input... depends on output from other node.
// we need to compare ALL dynamic inputs to make sure they
// are compatable.
dynamicInputSlotsToCompare.Add(inputSlot, outputConcreteType);
}
// we can now figure out the dynamic slotType
// from here set all the
var dynamicType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
foreach (var dynamicKvP in dynamicInputSlotsToCompare)
dynamicKvP.Key.concreteValueType= dynamicType;
foreach (var skippedSlot in skippedDynamicSlots)
skippedSlot.concreteValueType = dynamicType;
var inputError = inputSlots.Any(x => x.concreteValueType == ConcreteSlotValueType.Error);
// configure the output slots now
// 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)
{
outputSlot.concreteValueType = ConcreteSlotValueType.Error;
continue;
}
if (outputSlot.valueType == SlotValueType.Dynamic)
{
outputSlot.concreteValueType = dynamicType;
continue;
}
outputSlot.concreteValueType = ToConcreteType(outputSlot.valueType);
}
isInError |= inputError;
isInError |= outputSlots.Any(x => x.concreteValueType == ConcreteSlotValueType.Error);
isInError |= CalculateNodeHasError();
hasError = isInError;
if (!hasError)
{
previewShaderNeedsUpdate = true;
}
}
public bool previewShaderNeedsUpdate { get; set; }
//True if error
protected virtual bool CalculateNodeHasError()
{
return false;
}
public static string ConvertConcreteSlotValueTypeToString(ConcreteSlotValueType slotValue)
{
switch (slotValue)
{
case ConcreteSlotValueType.Vector1:
return string.Empty;
case ConcreteSlotValueType.Vector2:
return "2";
case ConcreteSlotValueType.Vector3:
return "3";
case ConcreteSlotValueType.Vector4:
return "4";
default:
return "Error";
}
}
public virtual bool OnGUI()
{
GUILayout.Label("Slot Defaults", EditorStyles.boldLabel);
var modified = false;
foreach (var slot in inputSlots)
{
if (!owner.GetEdges(slot).Any())
modified |= DoSlotUI(this, slot);
}
return modified;
}
public static bool DoSlotUI(BaseMaterialNode node, Slot slot)
{
GUILayout.BeginHorizontal( /*EditorStyles.inspectorBig*/);
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("Slot " + slot.name, EditorStyles.largeLabel);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUILayout.EndHorizontal();
return slot.OnGUI();
}
public virtual bool DrawSlotDefaultInput(Rect rect, Slot inputSlot)
{
var inputSlotType = inputSlot.concreteValueType;
return inputSlot.OnGUI(rect, inputSlotType);
}
public virtual IEnumerable<Slot> GetDrawableInputProxies()
{
return inputSlots.Where(x => !owner.GetEdges(x).Any());
}
public void ExecuteRepaint()
{
if (onNeedsRepaint != null)
onNeedsRepaint();
}
// CollectDependentNodes looks at the current node and calculates
// which nodes further up the tree (parents) would be effected if this node was changed
// it also includes itself in this list
public IEnumerable<BaseMaterialNode> CollectDependentNodes()
{
var nodeList = new List<BaseMaterialNode>();
NodeUtils.CollectDependentNodes(nodeList, this);
return nodeList;
}
// CollectDependentNodes looks at the current node and calculates
// which child nodes it depends on for it's calculation.
// Results are returned depth first so by processing each node in
// order you can generate a valid code block.
public List<BaseMaterialNode> CollectChildNodesByExecutionOrder(List<BaseMaterialNode> nodeList, Slot slotToUse = null, bool includeSelf = true)
{
if (slotToUse != null && !m_Slots.Contains(slotToUse))
{
Debug.LogError("Attempting to collect nodes by execution order with an invalid slot on: " + name);
return nodeList;
}
NodeUtils.CollectChildNodesByExecutionOrder(nodeList, this, slotToUse);
if (!includeSelf)
nodeList.Remove(this);
return nodeList;
}
protected virtual bool UpdatePreviewShader()
{
if (hasError)
return false;
var resultShader = ShaderGenerator.GeneratePreviewShader(this, out m_GeneratedShaderMode);
return InternalUpdatePreviewShader(resultShader);
}
private static bool ShaderHasError(Shader shader)
{
var hasErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic);
var result = hasErrorsCall.Invoke(null, new object[] {shader});
return (int) result != 0;
}
protected bool InternalUpdatePreviewShader(string resultShader)
{
MaterialWindow.DebugMaterialGraph("RecreateShaderAndMaterial : " + name + "_" + guid.ToString().Replace("-","_") + "\n" + resultShader);
// workaround for some internal shader compiler weirdness
// if we are in error we sometimes to not properly clean
// clean out the error flags and will stay in error, even
// if we are now valid
if (m_PreviewShader && ShaderHasError(m_PreviewShader))
{
Object.DestroyImmediate(m_PreviewShader, true);
Object.DestroyImmediate(m_PreviewMaterial, true);
m_PreviewShader = null;
m_PreviewMaterial = null;
}
if (m_PreviewShader == null)
{
m_PreviewShader = ShaderUtil.CreateShaderAsset(resultShader);
m_PreviewShader.hideFlags = HideFlags.HideInHierarchy;
m_LastShader = resultShader;
}
else
{
if (string.CompareOrdinal(resultShader, m_LastShader) != 0)
{
ShaderUtil.UpdateShaderAsset(m_PreviewShader, resultShader);
m_LastShader = resultShader;
}
}
return !ShaderHasError(m_PreviewShader);
}
/// <summary>
/// RenderPreview gets called in OnPreviewGUI. Nodes can override
/// RenderPreview and do their own rendering to the render texture
/// </summary>
public Texture RenderPreview(Rect targetSize)
{
if (hasError)
return null;
if (previewShaderNeedsUpdate)
{
UpdatePreviewShader();
previewShaderNeedsUpdate = false;
}
UpdatePreviewProperties();
if (s_Meshes[0] == null)
{
var handleGo = (GameObject) EditorGUIUtility.LoadRequired("Previews/PreviewMaterials.fbx");
// @TODO: temp workaround to make it not render in the scene
handleGo.SetActive(false);
foreach (Transform t in handleGo.transform)
{
switch (t.name)
{
case "sphere":
s_Meshes[0] = ((MeshFilter) t.GetComponent("MeshFilter")).sharedMesh;
break;
case "cube":
s_Meshes[1] = ((MeshFilter) t.GetComponent("MeshFilter")).sharedMesh;
break;
case "cylinder":
s_Meshes[2] = ((MeshFilter) t.GetComponent("MeshFilter")).sharedMesh;
break;
case "torus":
s_Meshes[3] = ((MeshFilter) t.GetComponent("MeshFilter")).sharedMesh;
break;
default:
Debug.Log("Something is wrong, weird object found: " + t.name);
break;
}
}
}
var previewUtil = owner.previewUtility;
previewUtil.BeginPreview(targetSize, GUIStyle.none);
if (m_GeneratedShaderMode == PreviewMode.Preview3D)
{
previewUtil.m_Camera.transform.position = -Vector3.forward * 5;
previewUtil.m_Camera.transform.rotation = Quaternion.identity;
EditorUtility.SetCameraAnimateMaterialsTime(previewUtil.m_Camera, Time.realtimeSinceStartup);
var amb = new Color(.2f, .2f, .2f, 0);
previewUtil.m_Light[0].intensity = 1.0f;
previewUtil.m_Light[0].transform.rotation = Quaternion.Euler(50f, 50f, 0);
previewUtil.m_Light[1].intensity = 1.0f;
InternalEditorUtility.SetCustomLighting(previewUtil.m_Light, amb);
previewUtil.DrawMesh(s_Meshes[0], Vector3.zero, Quaternion.Euler(-20, 0, 0) * Quaternion.Euler(0, 0, 0), previewMaterial, 0);
var oldFog = RenderSettings.fog;
Unsupported.SetRenderSettingsUseFogNoDirty(false);
previewUtil.m_Camera.Render();
Unsupported.SetRenderSettingsUseFogNoDirty(oldFog);
InternalEditorUtility.RemoveCustomLighting();
}
else
{
EditorUtility.UpdateGlobalShaderProperties(Time.realtimeSinceStartup);
Graphics.Blit(null, previewMaterial);
}
return previewUtil.EndPreview();
}
private static void SetPreviewMaterialProperty(PreviewProperty previewProperty, Material mat)
{
switch (previewProperty.m_PropType)
{
case PropertyType.Texture2D:
mat.SetTexture(previewProperty.m_Name, previewProperty.m_Texture);
break;
case PropertyType.Color:
mat.SetColor(previewProperty.m_Name, previewProperty.m_Color);
break;
case PropertyType.Vector2:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector3:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector4:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Float:
mat.SetFloat(previewProperty.m_Name, previewProperty.m_Float);
break;
}
}
protected virtual void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
var validSlots = inputSlots.ToArray();
for (var index = 0; index < validSlots.Length; index++)
{
var s = validSlots[index];
var edges = owner.GetEdges(s);
if (edges.Any())
continue;
var pp = new PreviewProperty
{
m_Name = s.GetInputName(this),
m_PropType = PropertyType.Vector4,
m_Vector4 = s.currentValue
};
properties.Add(pp);
}
}
public static void UpdateMaterialProperties(BaseMaterialNode target, Material material)
{
var childNodes = ListPool<BaseMaterialNode>.Get();
target.CollectChildNodesByExecutionOrder(childNodes);
var pList = ListPool<PreviewProperty>.Get();
for (var index = 0; index < childNodes.Count; index++)
{
var node = childNodes[index];
node.CollectPreviewMaterialProperties(pList);
}
foreach (var prop in pList)
SetPreviewMaterialProperty(prop, material);
ListPool<BaseMaterialNode>.Release(childNodes);
ListPool<PreviewProperty>.Release(pList);
}
public void UpdatePreviewProperties()
{
if (!hasPreview)
return;
UpdateMaterialProperties(this, previewMaterial);
}
public virtual string GetOutputVariableNameForSlot(Slot s, GenerationMode generationMode)
{
if (s.isInputSlot) 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;
}
public virtual string GetOutputVariableNameForNode()
{
return name + "_" + guid.ToString().Replace("-", "_");
}
public virtual Vector4 GetNewSlotDefaultValue(SlotValueType type)
{
return Vector4.one;
}
public void AddSlot(Slot slot)
{
if (slot == null)
return;
// new slot, just add it, we cool
if (!m_Slots.Contains(slot))
{
m_Slots.Add(slot);
return;
}
// 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)
{
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 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;
foundSlot.defaultValue = slot.defaultValue;
foundSlot.valueType = slot.valueType;
}
public void RemoveSlot(string name)
{
m_Slots.RemoveAll(x => x.name == name);
}
public string GenerateSlotName(Slot.SlotType type)
{
var slotsToCheck = type == Slot.SlotType.Input ? inputSlots.ToArray() : outputSlots.ToArray();
var format = type == Slot.SlotType.Input ? "I{0:00}" : "O{0:00}";
var index = slotsToCheck.Count();
var slotName = string.Format(format, index);
if (slotsToCheck.All(x => x.name != slotName))
return slotName;
index = 0;
do
{
slotName = string.Format(format, index++);
} while (slotsToCheck.Any(x => x.name == slotName));
return slotName;
}
}
public enum GUIModificationType
{
None,
Repaint,
ModelChanged
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs.meta


fileFormatVersion: 2
guid: a4da4d7c02dcbdd4f9ef2d3b1106879a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

76
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BlendNode.cs


using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Art/Blend Node")]
class BlendNode : Function2Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "BlendNode";
base.OnCreate();
}
public enum Operation
{
Normal,
Additive,
}
[SerializeField]
private Operation m_Operation;
[SerializeField]
private float m_Blend = 0.5f;
private static readonly string[] kOpNames = {
"normal",
"add"
};
protected override string GetFunctionName() { return "unity_blend_" + kOpNames[(int)m_Operation] + "_" + precision; }
protected override string GetFunctionCallBody(string input1Value, string input2Value)
{
return GetFunctionName() + "(" + input1Value + ", " + input2Value + ", " + m_Blend + ")";
}
protected void AddOperationBody(ShaderGenerator visitor, string name, string body, string precision)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk("inline " + precision + outputDimension +" unity_blend_" + name + "_" + precision + " (" + precision + outputDimension + " arg1, " + precision + outputDimension + " arg2, " + precision + " blend)", false);
outputString.AddShaderChunk("{", false); outputString.Indent();
outputString.AddShaderChunk(body, false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public override float GetNodeUIHeight(float width)
{
return 2.0f * EditorGUIUtility.singleLineHeight;
}
public override GUIModificationType NodeUI(Rect drawArea)
{
base.NodeUI(drawArea);
EditorGUI.BeginChangeCheck();
m_Blend = GUI.HorizontalSlider(new Rect(drawArea.x, drawArea.y, drawArea.width, EditorGUIUtility.singleLineHeight), m_Blend, 0f, 1f);
m_Operation = (Operation) EditorGUI.EnumPopup(new Rect(drawArea.x, drawArea.y + EditorGUIUtility.singleLineHeight, drawArea.width, EditorGUIUtility.singleLineHeight), m_Operation);
if (EditorGUI.EndChangeCheck())
{
pixelGraph.RevalidateGraph();
return GUIModificationType.Repaint;
}
return GUIModificationType.None;
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var precision in m_PrecisionNames)
{
AddOperationBody(visitor, kOpNames[(int)Operation.Normal], "return lerp(arg1, arg2, blend);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.Additive], "return (arg1 + arg2) * blend;", precision);
}
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BlendNode.cs.meta


fileFormatVersion: 2
guid: 909ffbb62e82bfb4abbeeb93022c6e9b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

30
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ClampNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Clamp Node")]
class ClampNode : Function3Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "ClampNode";
base.OnCreate();;
}
protected override string GetFunctionName() {return "unity_clamp_" + precision; }
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_clamp_" + precision + " (" + precision + "4 arg1, " + precision + "4 minval, " + precision + "4 maxval)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return clamp(arg1, minval, maxval);", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ClampNode.cs.meta


fileFormatVersion: 2
guid: b58e88ce87f05b241b7dc5d9a31bac69
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

74
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorNode.cs


using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Input/Color Node")]
class ColorNode : PropertyNode, IGeneratesBodyCode
{
[SerializeField]
private Color m_Color;
private const string kOutputSlotName = "Color";
public override void OnCreate()
{
base.OnCreate();
name = "ColorNode";
}
public override void OnEnable()
{
base.OnEnable();
AddSlot(new MaterialGraphSlot(new Slot(SlotType.OutputSlot, kOutputSlotName), SlotValueType.Vector4));
}
public override PropertyType propertyType
{
get { return PropertyType.Color; }
}
public override string GetOutputVariableNameForSlot(Slot s, GenerationMode generationMode)
{
return propertyName;
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
{
if (exposed || generationMode.IsPreview())
visitor.AddShaderChunk("float4 " + propertyName + ";", true);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
// we only need to generate node code if we are using a constant... otherwise we can just refer to the property :)
if (exposed || generationMode.IsPreview())
return;
visitor.AddShaderChunk(precision + "4 " + propertyName + " = " + precision + "4 (" + m_Color.r + ", " + m_Color.g + ", " + m_Color.b + ", " + m_Color.a + ");", true);
}
public override GUIModificationType NodeUI(Rect drawArea)
{
base.NodeUI(drawArea);
EditorGUI.BeginChangeCheck();
m_Color = EditorGUI.ColorField(new Rect(drawArea.x, drawArea.y, drawArea.width, EditorGUIUtility.singleLineHeight), m_Color);
if (EditorGUI.EndChangeCheck())
return GUIModificationType.Repaint;
return GUIModificationType.None;
}
public override PreviewProperty GetPreviewProperty()
{
return new PreviewProperty
{
m_Name = propertyName,
m_PropType = PropertyType.Color,
m_Color = m_Color
};
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorNode.cs.meta


fileFormatVersion: 2
guid: 325c0e24c20746345a5f90dc201973f8
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

72
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorizeNode.cs


using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Art/Colorize Node")]
class ColorizeNode : Function1Input, IGeneratesFunction
{
[SerializeField]
private Color m_Color = Color.blue;
[SerializeField]
private float m_Colorization = 0.0f;
[SerializeField]
private float m_Brightness = 1.0f;
[SerializeField]
private float m_Contrast = 1.0f;
public override void OnCreate()
{
name = "ColorizeNode";
base.OnCreate();
}
protected override string GetFunctionName() {return ""; }
protected override string GetFunctionCallBody(string inputValue)
{
return "unity_colorize_" + precision + "(" + inputValue + ", " + precision + "4(" + m_Color.r + ", " + m_Color.g + ", " + m_Color.b + ", " + m_Color.a + "), " + m_Colorization + ", " + m_Brightness + ", " + m_Contrast + ")";
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var thePrecisision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + thePrecisision + "4 unity_colorize_" + thePrecisision + " (" + thePrecisision + "4 arg1, " + thePrecisision + "4 color, " + thePrecisision + " amount, " + thePrecisision + " brightness, " + thePrecisision + " contrast)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(thePrecisision + "4 x = lerp(arg1, arg1 * color, amount);", false);
outputString.AddShaderChunk("x *= brightness;", false);
outputString.AddShaderChunk("x = pow(x, contrast);", false);
outputString.AddShaderChunk("return x;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
static float Slider(string title, float value, float from, float to)
{
GUILayout.BeginHorizontal();
GUILayout.Label(title);
value = GUILayout.HorizontalSlider(value, from, to, GUILayout.Width(64));
GUILayout.EndHorizontal();
return value;
}
/*public override void NodeUI()
{
base.NodeUI();
EditorGUI.BeginChangeCheck();
m_Color = EditorGUILayout.ColorField("Tint", m_Color);
m_Colorization = Slider("Colorization", m_Colorization, 0f, 1f);
m_Brightness = Slider("Brightness", m_Brightness, 0f, 2f);
m_Contrast = Slider("Contrast", m_Contrast, 0.3f, 4f);
if (EditorGUI.EndChangeCheck())
RegeneratePreviewShaders();
}*/
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorizeNode.cs.meta


fileFormatVersion: 2
guid: eb2553e0542079a4b86f8abe5ad4045e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

124
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/CombineNode.cs


using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Art/Combine Node")]
class CombineNode : Function2Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "CombineNode";
base.OnCreate();
}
// Based on information from:
// http://photoblogstop.com/photoshop/photoshop-blend-modes-explained
// http://www.venture-ware.com/kevin/coding/lets-learn-math-photoshop-blend-modes/
// http://mouaif.wordpress.com/2009/01/05/photoshop-math-with-glsl-shaders/
// http://dunnbypaul.net/blends/
public enum Operation
{
Darken,
Multiply,
ColorBurn,
LinearBurn,
// TODO: DarkerColor (Darken, but based on luminosity)
Lighten,
Screen,
ColorDodge,
LinearDodge,
// TODO: LighterColor (Lighten, but based on luminosity)
Overlay,
SoftLight,
HardLight,
VividLight,
LinearLight,
PinLight,
HardMix,
Difference,
Exclusion,
Subtract,
Divide,
}
[SerializeField]
private Operation m_Operation;
private static readonly string[] kOpNames = {
"darken", "mul", "cburn", "lburn",
"lighten", "screen", "cdodge", "ldodge",
"overlay", "softl", "hardl", "vividl", "linearl", "pinl", "hardmix",
"diff", "excl", "sub", "div"
};
protected override string GetFunctionName() { return "unity_combine_" + kOpNames[(int)m_Operation] + "_" + precision; }
protected void AddOperationBody(ShaderGenerator visitor, string combineName, string body, string combinePrecision)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk("inline " + combinePrecision + "4 unity_combine_" + combineName + "_" + combinePrecision + " (" + combinePrecision + "4 arg1, " + combinePrecision + "4 arg2)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(body, false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public override float GetNodeUIHeight(float width)
{
return EditorGUIUtility.singleLineHeight * 1;
}
public override GUIModificationType NodeUI(Rect drawArea)
{
base.NodeUI(drawArea);
EditorGUI.BeginChangeCheck();
m_Operation = (Operation)EditorGUI.EnumPopup(drawArea, m_Operation);
if (EditorGUI.EndChangeCheck())
{
pixelGraph.RevalidateGraph();
return GUIModificationType.Repaint;
}
return GUIModificationType.None;
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var precision in m_PrecisionNames)
{
// Darken group
AddOperationBody(visitor, kOpNames[(int)Operation.Darken], "return min(arg1, arg2);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.Multiply], "return arg1 * arg2;", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.ColorBurn], "return 1 - (1-arg1)/(arg2+1e-5);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.LinearBurn], "return arg1 + arg2 - 1;", precision);
// Lighten group
AddOperationBody(visitor, kOpNames[(int)Operation.Lighten], "return max(arg1, arg2);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.Screen], "return 1- (1-arg1) * (1-arg2);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.ColorDodge], "return arg1/(1-arg2+1e-5);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.LinearDodge], "return arg1 + arg2;", precision);
// Contrast group
AddOperationBody(visitor, kOpNames[(int)Operation.Overlay], "return (arg1 < 0.5)? arg1*arg2*2: 1-(1-arg1)*(1-arg2)*2;", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.SoftLight],
"return (1-arg1)*arg1*arg2 + arg1*(1- (1-arg1)*(1-arg2));", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.HardLight], "return (arg2 < 0.5)? arg1*arg2*2: 1-(1-arg1)*(1-arg2)*2;", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.VividLight],
"return (arg2 < 0.5)? 1- (1-arg1)/(2*arg2+1e-5): arg1/(1-2*(arg2-0.5)+1e-5);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.LinearLight], "return (arg2 < 0.5)? arg1+(2*arg2)-1: arg1+2*(arg2-0.5);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.PinLight], "return (arg2 < 0.5)? min(arg1, 2*arg2): max(arg1, 2*(arg2-0.5));", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.HardMix], "return (arg2 < 1-arg1)? " + precision + "(0):" + precision + "(1);", precision);
// Inversion group
AddOperationBody(visitor, kOpNames[(int)Operation.Difference], "return abs(arg2-arg1);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.Exclusion], "return arg1 + arg2 - arg1*arg2*2;", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.Subtract], "return max(arg2-arg1, 0.0);", precision);
AddOperationBody(visitor, kOpNames[(int)Operation.Divide], "return arg1 / (arg2+1e-5);", precision);
}
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/CombineNode.cs.meta


fileFormatVersion: 2
guid: 3738e97908dea1f4bbc5e5a7cf562ecc
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

30
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/DivNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Div Node")]
class DivNode : Function2Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "DivNode";
base.OnCreate();;
}
protected override string GetFunctionName() {return "unity_div_" + precision; }
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_div_" + precision + " (" + precision + "4 arg1, " + precision + "4 arg2)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return arg1 / arg2;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/DivNode.cs.meta


fileFormatVersion: 2
guid: 8e9d13e64300d6942ad51651d39f9ac6
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

33
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/DotNode.cs


using UnityEditor.Graphs;
namespace UnityEditor.MaterialGraph
{
[Title("Math/Dot Node")]
class DotNode : Function2Input
{
public override void OnCreate()
{
name = "DotNode";
base.OnCreate();;
}
protected override string GetFunctionName() { return "dot"; }
protected override MaterialGraphSlot GetInputSlot1()
{
var slot = new Slot(SlotType.InputSlot, GetInputSlot1Name());
return new MaterialGraphSlot(slot, SlotValueType.Vector3);
}
protected override MaterialGraphSlot GetInputSlot2()
{
var slot = new Slot(SlotType.InputSlot, GetInputSlot2Name());
return new MaterialGraphSlot(slot, SlotValueType.Vector3);
}
protected override MaterialGraphSlot GetOutputSlot()
{
var slot = new Slot(SlotType.OutputSlot, GetOutputSlotName());
return new MaterialGraphSlot(slot, SlotValueType.Vector1);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/DotNode.cs.meta


fileFormatVersion: 2
guid: 97e1d998eea5d644095671979ecf2e54
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

47
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Extensions.cs


using System;
using System.Collections.Generic;
using System.Linq;
namespace UnityEditor.MaterialGraph
{
internal static class Extensions
{
public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second , Func<TSource, TSource, bool> comparer)
{
return first.Except(second, new LambdaComparer<TSource>(comparer));
}
public class LambdaComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> _lambdaComparer;
private readonly Func<T, int> _lambdaHash;
public LambdaComparer(Func<T, T, bool> lambdaComparer) :
this(lambdaComparer, o => 0)
{
}
public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash)
{
if (lambdaComparer == null)
throw new ArgumentNullException("lambdaComparer");
if (lambdaHash == null)
throw new ArgumentNullException("lambdaHash");
_lambdaComparer = lambdaComparer;
_lambdaHash = lambdaHash;
}
public bool Equals(T x, T y)
{
return _lambdaComparer(x, y);
}
public int GetHashCode(T obj)
{
return _lambdaHash(obj);
}
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Extensions.cs.meta


fileFormatVersion: 2
guid: adf5c8d21f606c848a855790481093b2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

31
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/FresnelNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Fresnel Node")]
class FresnelNode : Function2Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "FresnelNode";
base.OnCreate();;
}
protected override string GetFunctionName() { return "unity_fresnel_" + precision; }
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_fresnel_" + precision + " (" + precision + "4 arg1, " + precision + "4 arg2)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return (1.0 - dot (normalize (arg1.xyz), normalize (arg2.xyz))).xxxx;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/FresnelNode.cs.meta


fileFormatVersion: 2
guid: 06ab35c1dfe05414787df3ea2772d507
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

73
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function1Input.cs


using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
abstract class Function1Input : BaseMaterialNode, IGeneratesBodyCode
{
public override bool hasPreview
{
get { return true; }
}
public override void OnEnable()
{
base.OnEnable();
AddSlot(GetInputSlot());
AddSlot(GetOutputSlot());
RemoveSlotsNameNotMatching(validSlots);
}
protected string[] validSlots
{
get { return new[] {GetInputSlotName(), GetOutputSlotName()}; }
}
protected virtual MaterialGraphSlot GetInputSlot()
{
var slot = new Slot(SlotType.InputSlot, GetInputSlotName());
return new MaterialGraphSlot(slot, SlotValueType.Dynamic);
}
protected virtual MaterialGraphSlot GetOutputSlot()
{
var slot = new Slot(SlotType.OutputSlot, GetOutputSlotName());
return new MaterialGraphSlot(slot, SlotValueType.Dynamic);
}
protected virtual string GetInputSlotName() {return "Input"; }
protected virtual string GetOutputSlotName() {return "Output"; }
protected abstract string GetFunctionName();
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindOutputSlot(GetOutputSlotName());
var inputSlot = FindInputSlot(GetInputSlotName());
if (inputSlot == null || outputSlot == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return;
}
var inputValue = GetSlotValue(inputSlot, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + GetFunctionCallBody(inputValue) + ";", true);
}
protected virtual string GetFunctionCallBody(string inputValue)
{
return GetFunctionName() + " (" + inputValue + ")";
}
public string outputDimension
{
get { return ConvertConcreteSlotValueTypeToString(concreteOutputSlotValueTypes[GetOutputSlotName()]); }
}
public string input1Dimension
{
get { return ConvertConcreteSlotValueTypeToString(concreteInputSlotValueTypes[GetInputSlotName()]); }
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function1Input.cs.meta


fileFormatVersion: 2
guid: 9e8ba3e80e4d9e947a9377e9e73fdca9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

132
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function3Input.cs


using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
internal abstract class Function3Input : BaseMaterialNode, IGeneratesBodyCode
{
public override bool hasPreview
{
get { return true; }
}
public override void OnEnable()
{
base.OnEnable();
AddSlot(GetInputSlot1());
AddSlot(GetInputSlot2());
AddSlot(GetInputSlot3());
AddSlot(GetOutputSlot());
RemoveSlotsNameNotMatching(validSlots);
}
protected string[] validSlots
{
get { return new[] {GetInputSlot1Name(), GetInputSlot2Name(), GetInputSlot3Name(), GetOutputSlotName()}; }
}
protected virtual MaterialGraphSlot GetInputSlot1()
{
var slot = new Slot(SlotType.InputSlot, GetInputSlot1Name());
return new MaterialGraphSlot(slot, SlotValueType.Dynamic);
}
protected virtual MaterialGraphSlot GetInputSlot2()
{
var slot = new Slot(SlotType.InputSlot, GetInputSlot2Name());
return new MaterialGraphSlot(slot, SlotValueType.Dynamic);
}
protected virtual MaterialGraphSlot GetInputSlot3()
{
var slot = new Slot(SlotType.InputSlot, GetInputSlot3Name());
return new MaterialGraphSlot(slot, SlotValueType.Dynamic);
}
protected virtual MaterialGraphSlot GetOutputSlot()
{
var slot = new Slot(SlotType.OutputSlot, GetOutputSlotName());
return new MaterialGraphSlot(slot, SlotValueType.Dynamic);
}
protected virtual string GetInputSlot1Name()
{
return "Input1";
}
protected virtual string GetInputSlot2Name()
{
return "Input2";
}
protected virtual string GetInputSlot3Name()
{
return "Input3";
}
protected virtual string GetOutputSlotName()
{
return "Output";
}
protected abstract string GetFunctionName();
protected virtual string GetFunctionPrototype(string arg1Name, string arg2Name, string arg3Name)
{
return "inline " + precision + outputDimension + " " + GetFunctionName() + " ("
+ precision + input1Dimension + " " + arg1Name + ", "
+ precision + input2Dimension + " " + arg2Name + ", "
+ precision + input3Dimension + " " + arg3Name + ")";
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindOutputSlot(GetOutputSlotName());
var inputSlot1 = FindInputSlot(GetInputSlot1Name());
var inputSlot2 = FindInputSlot(GetInputSlot2Name());
var inputSlot3 = FindInputSlot(GetInputSlot3Name());
if (inputSlot1 == null || inputSlot2 == null || inputSlot3 == null || outputSlot == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return;
}
string input1Value = GetSlotValue(inputSlot1, generationMode);
string input2Value = GetSlotValue(inputSlot2, generationMode);
string input3Value = GetSlotValue(inputSlot3, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + GetFunctionCallBody(input1Value, input2Value, input3Value) + ";", true);
}
protected virtual string GetFunctionCallBody(string inputValue1, string inputValue2, string inputValue3)
{
return GetFunctionName() + " (" + inputValue1 + ", " + inputValue2 + ", " + inputValue3 + ")";
}
protected virtual string GetFunctionCallBody(string inputValue)
{
return GetFunctionName() + " (" + inputValue + ")";
}
public string outputDimension
{
get { return ConvertConcreteSlotValueTypeToString(concreteOutputSlotValueTypes[GetOutputSlotName()]); }
}
public string input1Dimension
{
get { return ConvertConcreteSlotValueTypeToString(concreteInputSlotValueTypes[GetInputSlot1Name()]); }
}
public string input2Dimension
{
get { return ConvertConcreteSlotValueTypeToString(concreteInputSlotValueTypes[GetInputSlot2Name()]); }
}
public string input3Dimension
{
get { return ConvertConcreteSlotValueTypeToString(concreteInputSlotValueTypes[GetInputSlot3Name()]); }
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function3Input.cs.meta


fileFormatVersion: 2
guid: e7d8fb926f570fb48b10d7d068d54123
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

84
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/FunctionMultiInput.cs


using System.Linq;
using UnityEngine;
using System.Collections.Generic;
using UnityEditor.Graphs;
namespace UnityEditor.MaterialGraph
{
/*public abstract class FunctionMultiInput : BaseMaterialNode, IGeneratesBodyCode
{
private const string kOutputSlotName = "Output";
private const string kBaseInputSlotName = "Input";
public override bool hasPreview { get { return true; } }
public override void OnCreate()
{
base.OnCreate();
AddSlot(new Slot(SlotType.OutputSlot, kOutputSlotName));
AddSlot(new Slot(SlotType.InputSlot, GetInputSlotName(0)));
AddSlot(new Slot(SlotType.InputSlot, GetInputSlotName(1)));
}
protected bool IsInputSlotConnected(int index)
{
var inputSlot = GetValidInputSlots().FirstOrDefault(x => x.name == GetInputSlotName(index));
if (inputSlot == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return false;
}
return inputSlot.edges.Count > 0;
}
private static string GetInputSlotName(int index) { return kBaseInputSlotName + (index); }
public override void InputEdgeChanged(Edge e)
{
base.InputEdgeChanged(e);
int inputSlotCount = GetValidInputSlots().Count();
if (IsInputSlotConnected(inputSlotCount - 1))
AddSlot(new Slot(SlotType.InputSlot, GetInputSlotName(inputSlotCount)));
else if (inputSlotCount > 2)
{
var lastSlot = inputSlots.FirstOrDefault(x => x.name == GetInputSlotName(inputSlotCount - 1));
if (lastSlot != null)
RemoveSlot(lastSlot);
}
}
protected abstract string GetFunctionName();
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = outputSlots.FirstOrDefault(x => x.name == kOutputSlotName);
if (outputSlot == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return;
}
var inputSlots = GetValidInputSlots();
int inputSlotCount = inputSlots.Count();
// build up a list of the valid input connections
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);
}
protected virtual string GetFunctionCallBody(List<string> inputValues)
{
string functionCall = inputValues[0];
for (int q = 1; q < inputValues.Count; ++q)
functionCall = GetFunctionName() + " (" + functionCall + ", " + inputValues[q] + ")";
return functionCall;
}
}*/
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/FunctionMultiInput.cs.meta


fileFormatVersion: 2
guid: 323a0eb1930dff241b4547716c8eb21f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

96
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/KaleidoscopeNode.cs


using System;
using System.Linq;
using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Fractal/Kaleidoscope Node")]
class KaleidoscopeNode : BaseMaterialNode, IGeneratesFunction, IGeneratesBodyCode
{
[SerializeField]
private int m_Iterations = 6;
private const string kPointInputName = "Point";
private const string kConstant1InputName = "Constant1";
private const string kConstant2InputName = "Constant2";
private const string kOutputSlotName = "Output";
public override bool hasPreview { get { return true; } }
public override void OnCreate()
{
name = "KaleidoscopeNode";
base.OnCreate();
// AddSlot(new Slot(SlotType.InputSlot, kPointInputName));
//AddSlot(new Slot(SlotType.InputSlot, kConstant1InputName));
//AddSlot(new Slot(SlotType.InputSlot, kConstant2InputName));
//AddSlot(new Slot(SlotType.OutputSlot, kOutputSlotName));
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_kaleidoscope_" + precision + " (" + precision + "2 p, " + precision + "4 c1, " + precision + "4 c2, int iterations)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("c1 = c1 * 2 - 1;", false);
outputString.AddShaderChunk("c2 = c2 * 2 - 1;", false);
outputString.AddShaderChunk("for (int n = 0; n < iterations; n++)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("p = c1.xy + p * c1.zw + " + precision + "2(dot(p, c2.xy), dot(p, c2.zw));", false);
outputString.AddShaderChunk("if(p.x < p.y) p.xy = -p.yx;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
outputString.AddShaderChunk("return " + precision + "4(p, 1, 1);", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindOutputSlot(kOutputSlotName);
var pointInput = FindInputSlot(kPointInputName);
var constant1Input = FindInputSlot(kConstant1InputName);
var constant2Input = FindInputSlot(kConstant2InputName);
if (outputSlot == null || pointInput == null || constant1Input == null || constant2Input == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return;
}
string pointInputValue = GetSlotValue(pointInput, generationMode);
string constant1InputValue = GetSlotValue(constant1Input, generationMode);
string constant2InputValue = GetSlotValue(constant2Input, generationMode);
string outName = GetOutputVariableNameForSlot(outputSlot, generationMode);
visitor.AddShaderChunk(precision + "4 " + outName + " = unity_kaleidoscope_" + precision + "(" + pointInputValue + ".xy, " + constant1InputValue + ", " + constant2InputValue + ", " + m_Iterations + ");", false);
}
static float Slider(string title, float value, float from, float to)
{
GUILayout.BeginHorizontal();
GUILayout.Label(title);
value = GUILayout.HorizontalSlider(value, from, to, GUILayout.Width(64));
GUILayout.EndHorizontal();
return value;
}
/*public override void NodeUI()
{
base.NodeUI();
EditorGUI.BeginChangeCheck();
m_Iterations = (int)Slider("Iterations", (float)m_Iterations, 1, 50);
if (EditorGUI.EndChangeCheck())
RegeneratePreviewShaders();
}*/
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/KaleidoscopeNode.cs.meta


fileFormatVersion: 2
guid: dfc00afcda39bfa4fbd9bd6176f53477
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

14
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/LengthNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Length Node")]
class LengthNode : Function1Input
{
public override void OnCreate()
{
name = "LengthNode";
base.OnCreate();;
}
protected override string GetFunctionName() { return "length"; }
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/LengthNode.cs.meta


fileFormatVersion: 2
guid: 52afae1b1271e864c9c6965dc738c2dd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

102
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MandelbrotNode.cs


using System;
using System.Linq;
using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Fractal/Mandelbrot Node")]
class MandelbrotNode : BaseMaterialNode, IGeneratesFunction, IGeneratesBodyCode
{
[SerializeField]
private int m_Iterations = 6;
private const string kPointInputName = "Point";
private const string kConstantInputName = "Constant";
private const string kOutputSlotName = "Output";
public override bool hasPreview { get { return true; } }
public override void OnCreate()
{
name = "MandelbrotNode";
base.OnCreate();
//AddSlot(new Slot(SlotType.InputSlot, kPointInputName));
//AddSlot(new Slot(SlotType.InputSlot, kConstantInputName));
//AddSlot(new Slot(SlotType.OutputSlot, kOutputSlotName));
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_mandelbrot_" + precision + " (" + precision + "2 p, " + precision + "2 c, float limit, float scale, int iterations)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(precision + " zr = p.x * 4 - 2, zi = p.y * 4 - 2, dzr = 1, dzi = 0, r = 0, len2;", false);
outputString.AddShaderChunk("for (int n = 0; n < iterations; n++)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(precision + " tmp1 = 2 * zr * zi + c.y; zr = zr * zr - zi * zi + c.x; zi = tmp1;", false);
outputString.AddShaderChunk(precision + " tmp2 = 2 * (dzr * zi + dzi * zr); dzr = 2 * (dzr * zr - dzi * zi) + 1; dzi = tmp2;", false);
outputString.AddShaderChunk("len2 = zr * zr + zi * zi;", false);
outputString.AddShaderChunk("if (len2 > 1000000 * limit) { r = n; break; }", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
outputString.AddShaderChunk("return scale * sqrt(len2 / (dzr * dzr + dzi * dzi)) * log(len2);", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var validSlots = ListPool<Slot>.Get();
GetValidInputSlots(validSlots);
var outputSlot = outputSlots.FirstOrDefault(x => x.name == kOutputSlotName);
var pointInput = validSlots.FirstOrDefault(x => x.name == kPointInputName);
var constantInput = validSlots.FirstOrDefault(x => x.name == kConstantInputName);
ListPool<Slot>.Release(validSlots);
if (outputSlot == null || pointInput == null || constantInput == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return;
}
//TODO: This will break if there is NO input connected, use default in that case
var pointProvider = pointInput.edges[0].fromSlot.node as BaseMaterialNode;
var pointName = pointProvider.GetOutputVariableNameForSlot(pointInput.edges[0].fromSlot, generationMode);
var constantProvider = constantInput.edges[0].fromSlot.node as BaseMaterialNode;
var constantName = constantProvider.GetOutputVariableNameForSlot(constantInput.edges[0].fromSlot, generationMode);
string outName = GetOutputVariableNameForSlot(outputSlot, generationMode);
visitor.AddShaderChunk(precision + "4 " + outName + " = unity_mandelbrot_" + precision + "(" + pointName + ".xy, " + constantName + ".xy, " + constantName + ".z, " + constantName + ".w, " + m_Iterations + ");", false);
}
static float Slider(string title, float value, float from, float to)
{
GUILayout.BeginHorizontal();
GUILayout.Label(title);
value = GUILayout.HorizontalSlider(value, from, to, GUILayout.Width(64));
GUILayout.EndHorizontal();
return value;
}
/*public override void NodeUI()
{
base.NodeUI();
EditorGUI.BeginChangeCheck();
m_Iterations = (int)Slider("Iterations", (float)m_Iterations, 1, 50);
if (EditorGUI.EndChangeCheck())
RegeneratePreviewShaders();
}*/
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MandelbrotNode.cs.meta


fileFormatVersion: 2
guid: 45896ba83118f8548bd9d2f9263bcde5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

14
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaxNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Maximum Node")]
class MaximumNode : Function2Input
{
public override void OnCreate()
{
name = "MaximumNode";
base.OnCreate();;
}
protected override string GetFunctionName() { return "max"; }
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MaxNode.cs.meta


fileFormatVersion: 2
guid: 1de46e012f3608843978529b36704c2b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

14
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MinNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Minimum Node")]
class MinimumNode : Function2Input
{
public override void OnCreate()
{
name = "MinimumNode";
base.OnCreate();;
}
protected override string GetFunctionName() { return "min"; }
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MinNode.cs.meta


fileFormatVersion: 2
guid: 79ffed9a70f191f4c966a6eb3ae10d07
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

35
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MultiplyNode.cs


using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Math/Multiply Node")]
internal class MultiplyNode : Function2Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "MultiplyNode";
base.OnCreate();
}
protected override string GetFunctionName()
{
return "unity_multiply_" + precision;
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + outputDimension + " " + GetFunctionName() + " (" + precision + input1Dimension + " arg1, " + precision + input2Dimension + " arg2)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return arg1 * arg2;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/MultiplyNode.cs.meta


fileFormatVersion: 2
guid: 088fb5bde3ece0f4190136b3ab43f7c4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

36
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/NormalNode.cs


using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Input/Normal Node")]
public class NormalNode : BaseMaterialNode
{
private const string kOutputSlotName = "Normal";
public override bool hasPreview { get { return true; } }
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; } }
public override void OnCreate()
{
base.OnCreate();
name = "Normal";
}
public override void OnEnable()
{
base.OnEnable();
AddSlot(new MaterialGraphSlot(new Slot(SlotType.OutputSlot, kOutputSlotName), SlotValueType.Vector3));
}
public override string GetOutputVariableNameForSlot(Slot slot, GenerationMode generationMode)
{
if (generationMode == GenerationMode.Preview2D)
Debug.LogError("Trying to generate 2D preview on a node that does not support it!");
return generationMode.Is2DPreview() ? "IN.Normal" : "o.Normal";
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/NormalNode.cs.meta


fileFormatVersion: 2
guid: 5b34601661908b3499c4c5e2ecd61f75
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

14
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/NormalizeNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Normalize Node")]
class NormalizeNode : Function1Input
{
public override void OnCreate()
{
name = "NormalizeNode";
base.OnCreate();;
}
protected override string GetFunctionName() { return "normalize"; }
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/NormalizeNode.cs.meta


fileFormatVersion: 2
guid: 7eb73d726827e2c41ae4d68018bc97e1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

104
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PerlinNode.cs


using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Fractal/Perlin Node")]
class PerlinNode : TextureNode, IGeneratesFunction, IGeneratesBodyCode
{
public override bool hasPreview { get { return true; } }
[SerializeField]
private int m_Iterations = 4;
[SerializeField]
private float m_Decay = 0.5f;
[SerializeField]
private float m_Frequency = 2.0f;
public override void OnCreate()
{
name = "Perlin";
base.OnCreate();
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_perlin_" + precision + " ("
+ "sampler2D textureID, "
+ "int iterations, "
+ precision + " decay, "
+ precision + " frequency, "
+ precision + "2 p"
+ ")", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(precision + "4 sum = " + precision + "4(0, 0, 0, 0);", false);
outputString.AddShaderChunk(precision + " amp = 0.5;", false);
outputString.AddShaderChunk("for(int n = 0; n < iterations; n++)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("sum += amp * tex2D (textureID, p);", false);
outputString.AddShaderChunk("p *= frequency;", false);
outputString.AddShaderChunk("amp *= decay;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
outputString.AddShaderChunk("return sum;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
/* public override void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindOutputSlot(kOutputSlotName);
if (outputSlot == null)
return;
var uvSlot = FindInputSlot(kUVSlotName);
if (uvSlot == null)
return;
var uvName = "IN.meshUV0";
if (uvSlot.edges.Count > 0)
{
var fromNode = uvSlot.edges[0].fromSlot.node as BaseMaterialNode;
uvName = fromNode.GetOutputVariableNameForSlot(uvSlot.edges[0].fromSlot, generationMode);
}
string body = "unity_perlin_" + precision + "(" + GetPropertyName() + ", " + m_Iterations + ", " + m_Decay + ", " + m_Frequency + ", " + uvName + ".xy)";
visitor.AddShaderChunk("float4 " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + body + ";", true);
}
*/
static float Slider(string title, float value, float from, float to)
{
GUILayout.BeginHorizontal();
GUILayout.Label(title);
value = GUILayout.HorizontalSlider(value, from, to, GUILayout.Width(64));
GUILayout.EndHorizontal();
return value;
}
/*
public override float GetNodeUIHeight()
{
return EditorGUIUtility.singleLineHeight;
}
public override bool NodeUI(Rect drawArea)
{
base.NodeUI(drawArea);
EditorGUI.BeginChangeCheck();
m_Iterations = (int)Slider("Iterations", (float)m_Iterations, 1, 8);
m_Decay = Slider("Decay", m_Decay, -1f, 1f);
m_Frequency = Slider("Frequency", m_Frequency, 0f, 5f);
if (EditorGUI.EndChangeCheck())
RegeneratePreviewShaders();
}*/
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PerlinNode.cs.meta


fileFormatVersion: 2
guid: 6388ec78711fae240b4d5c60bd70d36d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

16
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PowerNode.cs


using UnityEngine;
namespace UnityEditor.MaterialGraph
{
[Title("Math/Power Node")]
class PowerNode : Function2Input
{
public override void OnCreate()
{
name = "PowerNode";
base.OnCreate();;
}
protected override string GetFunctionName() { return "pow"; }
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PowerNode.cs.meta


fileFormatVersion: 2
guid: b2957c4e08e061444a7444a1a03fb584
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

30
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/QuantizeNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Quantize Node")]
class QuantizeNode : Function2Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "QuantizeNode";
base.OnCreate();;
}
protected override string GetFunctionName() {return "unity_quantize_" + precision; }
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_quantize_" + precision + " (" + precision + "4 input, " + precision + "4 stepsize)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return floor(input / stepsize) * stepsize;", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/QuantizeNode.cs.meta


fileFormatVersion: 2
guid: 4322ad8d0cd83df47afd741a6b97d57b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

38
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ReflectNode.cs


using System;
namespace UnityEditor.MaterialGraph
{
[Title("Math/Reflect Node")]
class ReflectNode : Function2Input, IGeneratesFunction
{
public override void OnCreate()
{
name = "ReflectNode";
base.OnCreate();;
}
protected override string GetInputSlot1Name() {return "Normal"; }
protected override string GetInputSlot2Name() {return "Direction"; }
protected override string GetOutputSlotName() {return "Reflection"; }
protected override string GetFunctionName() {return "unity_reflect_" + precision; }
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_reflect_" + precision + " (" + precision + "4 normal, " + precision + "4 direction)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(precision + "3 vn = normalize(normal.xyz);", false);
outputString.AddShaderChunk(precision + "3 vd = normalize(direction.xyz);", false);
outputString.AddShaderChunk("return half4 (2 * dot(vn, vd) * vn - vd, 1.0);", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ReflectNode.cs.meta


fileFormatVersion: 2
guid: 6af2205640e32994db6fd7de8aebf1de
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

38
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ScreenPosNode.cs


using UnityEditor.Graphs;
namespace UnityEditor.MaterialGraph
{
[Title("Input/Screen Pos Node")]
public class ScreenPosNode : BaseMaterialNode, IGeneratesVertexToFragmentBlock
{
private const string kOutputSlotName = "ScreenPos";
public override bool hasPreview { get { return true; } }
public override void OnCreate()
{
name = "ScreenPos";
base.OnCreate();
}
public override void OnEnable()
{
base.OnEnable();
AddSlot(new MaterialGraphSlot(new Slot(SlotType.InputSlot, kOutputSlotName), SlotValueType.Vector4));
}
public override string GetOutputVariableNameForSlot(Slot slot, GenerationMode generationMode)
{
return "IN.screenPos";
}
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
string temp = precision + "4 screenPos";
if (generationMode == GenerationMode.Preview2D)
temp += " : TEXCOORD1";
temp += ";";
visitor.AddShaderChunk(temp, true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ScreenPosNode.cs.meta


fileFormatVersion: 2
guid: e204c7999bfa0ee42a18d8a560a36244
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

14
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/Sin Node")]
class SinNode : Function1Input
{
public override void OnCreate()
{
name = "SinNode";
base.OnCreate();;
}
protected override string GetFunctionName() {return "sin"; }
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinNode.cs.meta


fileFormatVersion: 2
guid: 2b10d839969f5484cad9632519dc7324
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

32
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinTimeNode.cs


using UnityEditor.Graphs;
namespace UnityEditor.MaterialGraph
{
[Title("Input/Sine Time Node")]
public class SinTimeNode : BaseMaterialNode, IRequiresTime
{
private const string kOutputSlotName = "SinTime";
public override void OnCreate()
{
base.OnCreate();
name = "Sine Time";
}
public override void OnEnable()
{
base.OnEnable();
AddSlot(new MaterialGraphSlot(new Slot(SlotType.OutputSlot, kOutputSlotName), SlotValueType.Vector4));
}
public override bool hasPreview
{
get { return true; }
}
public override string GetOutputVariableNameForSlot(Slot s, GenerationMode generationMode)
{
return "_SinTime";
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinTimeNode.cs.meta


fileFormatVersion: 2
guid: f80af444cd4235c419b356216d784b57
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

30
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SmoothStepNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Math/SmoothStep Node")]
class SmoothStepNode : Function3Input, IGeneratesFunction
{
public override void OnCreate()
{
base.OnCreate();;
name = "SmoothStepNode";
}
protected override string GetFunctionName() {return "unity_smoothstep_" + precision; }
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
foreach (var precision in m_PrecisionNames)
{
outputString.AddShaderChunk("inline " + precision + "4 unity_smoothstep_" + precision + " (" + precision + "4 input, " + precision + "4 edge1, " + precision + "4 edge2)", false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("return smoothstep(edge1, edge2, input);", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SmoothStepNode.cs.meta


fileFormatVersion: 2
guid: a9ced96a233d64541b3c5d374a057d6b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

42
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphIOBaseNode.cs


using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
public class SubGraphIOBaseNode : BaseMaterialNode
{
GUIContent kTempContent = new GUIContent("+");
public virtual void AddSlot()
{
}
public void FooterUI(GraphGUI host)
{
// TODO: make it pretty
GUIStyle style = this is SubGraphOutputsNode ?
Styles.GetNodeStyle("shader in", Styles.Color.Aqua, false) :
Styles.GetNodeStyle("shader out", Styles.Color.Aqua, false);
var pos = GUILayoutUtility.GetRect(kTempContent, style);
int id = GUIUtility.GetControlID(FocusType.Passive);
Event evt = Event.current;
if (evt.type == EventType.Layout || evt.type == EventType.Used)
return;
switch (evt.GetTypeForControl(id))
{
case EventType.MouseUp:
if (pos.Contains(evt.mousePosition) && evt.button == 0)
{
AddSlot();
evt.Use();
}
break;
case EventType.Repaint:
style.Draw(pos, kTempContent, id);
break;
}
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphIOBaseNode.cs.meta


fileFormatVersion: 2
guid: 329dc46f2903e364da6c6d6500b0cfee
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

80
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphInputsNode.cs


using UnityEngine;
using System.Collections.Generic;
using UnityEditor.Graphs;
namespace UnityEditor.MaterialGraph
{
public class SubGraphInputsNode : SubGraphIOBaseNode, IGenerateProperties
{
public override void OnCreate()
{
name = "SubGraphInputs";
title = "Inputs";
// position = new Rect(BaseMaterialGraphGUI.kDefaultNodeWidth * 4, BaseMaterialGraphGUI.kDefaultNodeHeight * 2, Mathf.Max(300, position.width), position.height);
base.OnCreate();
}
public override void AddSlot()
{
//AddSlot(new Slot(SlotType.OutputSlot, GenerateSlotName(SlotType.OutputSlot)));
}
public override void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
{
base.GeneratePropertyBlock(visitor, generationMode);
if (!generationMode.IsPreview())
return;
foreach (var slot in outputSlots)
{
if (slot.edges.Count == 0)
continue;
var defaultValue = GetSlotDefaultValue(slot.name);
if (defaultValue != null)
defaultValue.GeneratePropertyBlock(visitor, generationMode);
}
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
{
base.GeneratePropertyUsages(visitor, generationMode, slotValueType);
if (!generationMode.IsPreview())
return;
foreach (var slot in outputSlots)
{
if (slot.edges.Count == 0)
continue;
var defaultValue = GetSlotDefaultValue(slot.name);
if (defaultValue != null)
defaultValue.GeneratePropertyUsages(visitor, generationMode, slotValueType);
}
}
protected override void CollectPreviewMaterialProperties (List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
foreach (var slot in outputSlots)
{
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);
}
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphInputsNode.cs.meta


fileFormatVersion: 2
guid: af738716871e4a345ac8edc429a3b665
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

208
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
//[Title("Sub-graph/Sub-graph Node")]
public class SubGraphNode : BaseMaterialNode, IGeneratesBodyCode, IGeneratesVertexToFragmentBlock, IGeneratesFunction, IGeneratesVertexShaderBlock
{
[SerializeField]
private MaterialSubGraph m_SubGraphAsset;
public MaterialSubGraph subGraphAsset { get { return m_SubGraphAsset; } }
public override PreviewMode previewMode
{
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;
}
}
public const int kMaxSlots = 16;
public override void OnCreate()
{
base.OnCreate();
name = "SubGraph";
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);
}
static string GetOutputSlotName(int n)
{
return string.Format("O{0:00}", n);
}
/* 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();
}*/
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)
{
SubGraphChanged(m_SubGraphAsset);
}
}
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 s = current.FirstOrDefault(n => n.name == slot.name);
if (s != null)
s.title = slot.title;
// else
// AddSlot(new Slot(type, slot.name, slot.title));
}
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)
{
if (m_SubGraphAsset == null)
return;
var outputString = new ShaderGenerator();
outputString.AddShaderChunk("// Subgraph for node " + GetOutputVariableNameForNode(), false);
// Step 1...
// find out which output slots are actually used
//TODO: Be smarter about this and only output ones that are actually USED, not just connected
//var validOutputSlots = NodeUtils.GetSlotsThatOutputToNodeRecurse(this, (graph as BaseMaterialGraph).masterNode);
var validOutputSlots = outputSlots.Where(x => x.edges.Count > 0);
foreach (var slot in validOutputSlots)
{
outputString.AddShaderChunk(
"float4 "
+ GetOutputVariableNameForSlot(slot, generationMode)
+ " = float4(0, 0, 0, 0);", false);
}
// Step 2...
// Go into the subgraph
outputString.AddShaderChunk("{", false);
outputString.Indent();
// 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)
{
if (!slot.isInputSlot)
continue;
// 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);
}
// Step 4...
// Using the inputs we can now generate the shader body :)
var bodyGenerator = new ShaderGenerator();
m_SubGraphAsset.GenerateNodeCode(bodyGenerator, this);
outputString.AddShaderChunk(bodyGenerator.GetShaderString(0), false);
// Step 5...
// Copy the outputs to the parent context name);
foreach (var slot in validOutputSlots)
{
bool internallyWired = m_SubGraphAsset.OutputInternallyWired(slot.name);
if (internallyWired)
{
outputString.AddShaderChunk(
GetOutputVariableNameForSlot(slot, generationMode)
+ " = "
+ m_SubGraphAsset.GetOutputVariableNameForSlotByName(slot.name, this, generationMode)
+ ";", false);
}
}
outputString.Deindent();
outputString.AddShaderChunk("}", false);
outputString.AddShaderChunk("// Subgraph ends", false);
shaderBodyVisitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
m_SubGraphAsset.GenerateVertexToFragmentBlock(visitor, GenerationMode.SurfaceShader);
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
m_SubGraphAsset.GenerateNodeFunction(visitor, GenerationMode.SurfaceShader);
}
public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
m_SubGraphAsset.GenerateVertexShaderBlock(visitor, GenerationMode.SurfaceShader);
}
public override void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode)
{
base.GeneratePropertyBlock(visitor, generationMode);
m_SubGraphAsset.GeneratePropertyBlock(visitor, GenerationMode.SurfaceShader);
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode, ConcreteSlotValueType slotValueType)
{
base.GeneratePropertyUsages(visitor, generationMode, slotValueType);
m_SubGraphAsset.GeneratePropertyUsages(visitor, GenerationMode.SurfaceShader, slotValueType);
}
protected override void CollectPreviewMaterialProperties (List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
properties.AddRange(m_SubGraphAsset.GetPreviewProperties());
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphNode.cs.meta


fileFormatVersion: 2
guid: 047e0841c1476e041935baac6d7bb652
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

21
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphOutputsNode.cs


using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
public class SubGraphOutputsNode : SubGraphIOBaseNode
{
public override void OnCreate()
{
base.OnCreate();
name = "SubGraphOutputs";
title = "Outputs";
//position = new Rect(BaseMaterialGraphGUI.kDefaultNodeWidth * 8, BaseMaterialGraphGUI.kDefaultNodeHeight * 2, Mathf.Max(300, position.width), position.height);
}
public override void AddSlot()
{
//AddSlot(new Slot(SlotType.InputSlot, GenerateSlotName(SlotType.InputSlot)));
}
}
}

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存