浏览代码

Merge remote-tracking branch 'origin/master' into graphview-styling-updates

# Conflicts:
#	MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs
/main
mathieum-unity 7 年前
当前提交
045d568e
共有 364 个文件被更改,包括 1527 次插入819 次删除
  1. 50
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraph.cs
  2. 9
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraphObject.cs
  3. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ColorBalanceNode.cs
  4. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ParallaxNode.cs
  5. 4
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/AACheckerBoard3dNode.cs
  6. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/MultiLayerParallaxNode.cs
  7. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/POMNode.cs
  8. 10
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/SphericalIndentationNode.cs
  9. 4
      MaterialGraphProject/Assets/SRP/PostProcessing/PostProcessing/Runtime/Utils/TextureFormatUtilities.cs
  10. 78
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs
  11. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/DynamicVectorMaterialSlot.cs
  12. 81
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs
  13. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs
  14. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Texture2DInputMaterialSlot.cs
  15. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/UVMaterialSlot.cs
  16. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector1MaterialSlot.cs
  17. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2MaterialSlot.cs
  18. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3MaterialSlot.cs
  19. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4MaterialSlot.cs
  20. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/AbstractMaterialNode.cs
  21. 26
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/CodeFunctionNode.cs
  22. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/PositionNode.cs
  23. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/UVNode.cs
  24. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/VertexColorNode.cs
  25. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ViewDirectionNode.cs
  26. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix2Node.cs
  27. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix3Node.cs
  28. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix4Node.cs
  29. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Time/SinTimeNode.cs
  30. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Time/TimeNode.cs
  31. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/AbsoluteNode.cs
  32. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/LengthNode.cs
  33. 70
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/LogNode.cs
  34. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/NegateNode.cs
  35. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/NormalizeNode.cs
  36. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/PosterizeNode.cs
  37. 55
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ReciprocalNode.cs
  38. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/AddNode.cs
  39. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs
  40. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/PowerNode.cs
  41. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/SquareRootNode.cs
  42. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/SubtractNode.cs
  43. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Interpolation/InverseLerpNode.cs
  44. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Interpolation/LerpNode.cs
  45. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/ClampNode.cs
  46. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/FractionNode.cs
  47. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/RemapNode.cs
  48. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/SaturateNode.cs
  49. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/FloorNode.cs
  50. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/RoundNode.cs
  51. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/SignNode.cs
  52. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/StepNode.cs
  53. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/TruncateNode.cs
  54. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Trigonometry/DegreesToRadiansNode.cs
  55. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Trigonometry/RadiansToDegreesNode.cs
  56. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/NoiseNode.cs
  57. 32
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/VoronoiNoise.cs
  58. 61
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/PropertyNode.cs
  59. 21
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/SpherizeNode.cs
  60. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/SpherizeNode.cs.meta
  61. 98
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/RotateNode.cs
  62. 19
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/SaturationNode.cs
  63. 103
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/HueNode.cs
  64. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraphNode.cs
  65. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/SubGraphNode.cs
  66. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/ShaderGenerator.cs
  67. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/DefaultControl.cs
  68. 26
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ObjectControl.cs
  69. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/PropertyControl.cs
  70. 59
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs
  71. 79
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/ShaderPropertyView.cs
  72. 30
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/StandardNodeEditorView.cs
  73. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/NodeCreator.cs
  74. 265
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs
  75. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphPreviewGenerator.cs
  76. 87
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs
  77. 63
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
  78. 45
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs
  79. 100
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs
  80. 34
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporterEditor.cs
  81. 137
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/ShaderGraphImporter.cs
  82. 37
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/ShaderSubGraphImporterEditor.cs
  83. 160
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss
  84. 2
      MaterialGraphProject/ProjectSettings/ProjectVersion.txt
  85. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/ConstantNode.cs.meta
  86. 24
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/RadialShearNode.cs
  87. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/Texture2DNode.cs
  88. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SamplerStateNode.cs
  89. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/ColorNode.cs
  90. 59
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ExponentialNode.cs
  91. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/CheckerboardNode.cs
  92. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/GradientRampNode.cs
  93. 4
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/LineNode.cs
  94. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/PulseNode.cs
  95. 2
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/UVPannerNode.cs
  96. 4
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/UVTileNode.cs
  97. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector1Node.cs
  98. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector2Node.cs
  99. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector3Node.cs
  100. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector4Node.cs

50
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraph.cs


ValidateGraph();
}
void AddNodeNoValidate(INode node)
protected void AddNodeNoValidate(INode node)
{
m_Nodes.Add(node.guid, node);
node.owner = this;

ValidateGraph();
}
void RemoveNodeNoValidate(INode node)
protected void RemoveNodeNoValidate(INode node)
{
if (!node.canDeleteNode)
return;

return new Dictionary<SerializationHelper.TypeSerializationInfo, SerializationHelper.TypeSerializationInfo>();
}
IEdge ConnectNoValidate(SlotReference fromSlotRef, SlotReference toSlotRef)
protected IEdge ConnectNoValidate(SlotReference fromSlotRef, SlotReference toSlotRef)
{
if (fromSlotRef == null || toSlotRef == null)
return null;

m_AddedEdges.Add(newEdge);
AddEdgeToNodeEdges(newEdge);
Debug.Log("Connected edge: " + newEdge);
Debug.LogFormat("Connected edge: {0} -> {1} ({2} -> {3})\n{4}", newEdge.outputSlot.nodeGuid, newEdge.inputSlot.nodeGuid, fromNode.name, toNode.name, Environment.StackTrace);
return newEdge;
}

ValidateGraph();
}
void RemoveEdgeNoValidate(IEdge e)
protected void RemoveEdgeNoValidate(IEdge e)
Assert.NotNull(e);
if (e == null)
throw new ArgumentException("Trying to remove an edge that does not exist.", "e");
m_Edges.Remove(e);
List<IEdge> inputNodeEdges;

foreach (var node in GetNodes<INode>())
node.ValidateNode();
foreach (var edge in m_AddedEdges.ToList())
{
if (!ContainsNodeGuid(edge.outputSlot.nodeGuid) || !ContainsNodeGuid(edge.inputSlot.nodeGuid))
{
Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}", edge.outputSlot.nodeGuid, edge.inputSlot.nodeGuid);
m_AddedEdges.Remove(edge);
}
}
other.ValidateGraph();
ValidateGraph();
// Current tactic is to remove all nodes and edges and then re-add them, such that depending systems
// will re-initialize with new references.
foreach (var edge in m_Edges)
{
// Remove the edge if it doesn't exist in the other graph.
if (!other.ContainsNodeGuid(edge.inputSlot.nodeGuid) || !other.GetEdges(edge.inputSlot).Any(otherEdge => otherEdge.outputSlot.Equals(edge.outputSlot)))
removedNodeEdges.Add(edge);
}
removedNodeEdges.AddRange(m_Edges);
// Remove all nodes and re-add them.
foreach (var node in m_Nodes.Values)
removedNodeGuids.Add(node.guid);
removedNodeGuids.AddRange(m_Nodes.Keys);
foreach (var nodeGuid in removedNodeGuids)
RemoveNodeNoValidate(m_Nodes[nodeGuid]);
}

// Add nodes from other graph which don't exist in this one.
{
if (!ContainsNodeGuid(node.guid))
AddNodeNoValidate(node);
}
AddNodeNoValidate(node);
// Add edges from other graph which don't exist in this one.
{
if (!GetEdges(edge.inputSlot).Any(otherEdge => otherEdge.outputSlot.Equals(edge.outputSlot)))
ConnectNoValidate(edge.outputSlot, edge.inputSlot);
}
ConnectNoValidate(edge.outputSlot, edge.inputSlot);
ValidateGraph();
}

9
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraphObject.cs


[SerializeField]
SerializationHelper.JSONSerializedElement m_SerializedGraph;
[SerializeField]
bool m_IsDirty;
IGraph m_Graph;
IGraph m_DeserializedGraph;

}
}
public bool isDirty
{
get { return m_IsDirty; }
}
m_IsDirty = true;
}
public void OnBeforeSerialize()

2
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ColorBalanceNode.cs


}
static string Unity_ColorBalance(
[Slot(0, Binding.None)] Vector4 inputColor,
[Slot(0, Binding.None)] Color inputColor,
[Slot(1, Binding.None)] Vector3 adjustRGB,
[Slot(2, Binding.None)] out Vector4 outColor)
{

2
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ParallaxNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("UV/Parallax")]
[Title("OLD/Parallax")]
public class ParallaxNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireViewDirection
{
protected const string kInputSlot1ShaderName = "Depth";

4
MaterialGraphProject/Assets/NewNodes/Editor/Kill/AACheckerBoard3dNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Procedural/AACheckerboard3d")]
[Title("OLD/AACheckerboard3d")]
public class AACheckerboard3dNode : CodeFunctionNode
{
protected override MethodInfo GetFunctionToConvert()

float3 blend_out = saturate((scale - aaTweak.zzz) / (aaTweak.yyy - aaTweak.zzz));
float3 vectorAlpha = clamp(distance3 * scale.xyz * blend_out.xyz, -1.0f, 1.0f);
float alpha = saturate(0.5f + 0.5f * vectorAlpha.x * vectorAlpha.y * vectorAlpha.z);
result= lerp(colorA, colorB, alpha.xxxx);;
result= lerp(colorA, colorB, alpha.xxxx);
}";
}
}

2
MaterialGraphProject/Assets/NewNodes/Editor/Kill/MultiLayerParallaxNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("UV/MultiLayerParallax")]
[Title("OLD/MultiLayerParallax")]
public class MultiLayerParallaxNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireViewDirection
{
protected const string kInputDepthShaderName = "Depth";

2
MaterialGraphProject/Assets/NewNodes/Editor/Kill/POMNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("UV/ParallaxOcclusionMapping")]
[Title("OLD/ParallaxOcclusionMapping")]
public class ParallaxOcclusionMappingNode : CodeFunctionNode
{
protected override MethodInfo GetFunctionToConvert()

10
MaterialGraphProject/Assets/NewNodes/Editor/Kill/SphericalIndentationNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("UV/SphericalIndentation")]
public class SphericalIndentationNode : CodeFunctionNode
/*
[Title("UV/Spherize 3D")]
public class SphericalIndentationNode : CodeFunctionNode
public SphericalIndentationNode()
{
name = "Spherize 3D";
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_SphericalIndentation", BindingFlags.Static | BindingFlags.NonPublic);

}";
}
}
*/
}

4
MaterialGraphProject/Assets/SRP/PostProcessing/PostProcessing/Runtime/Utils/TextureFormatUtilities.cs


{ TextureFormat.PVRTC_RGB4, RenderTextureFormat.ARGB32 },
{ TextureFormat.PVRTC_RGBA4, RenderTextureFormat.ARGB32 },
{ TextureFormat.ETC_RGB4, RenderTextureFormat.ARGB32 },
{ TextureFormat.ATC_RGB4, RenderTextureFormat.ARGB32 },
{ TextureFormat.ATC_RGBA8, RenderTextureFormat.ARGB32 },
{ TextureFormat.ETC_RGB4, RenderTextureFormat.ARGB32 },
{ TextureFormat.ETC2_RGBA8, RenderTextureFormat.ARGB32 },
{ TextureFormat.ETC2_RGB, RenderTextureFormat.ARGB32 },
{ TextureFormat.ETC2_RGBA1, RenderTextureFormat.ARGB32 },
{ TextureFormat.ETC2_RGBA8, RenderTextureFormat.ARGB32 },

78
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs


public void RemoveShaderProperty(Guid guid)
{
var propertyNodes = GetNodes<PropertyNode>().Where(x => x.propertyGuid == guid).ToArray();
foreach (var pNode in propertyNodes)
pNode.ReplaceWithConcreteNode();
RemoveShaderPropertyNoValidate(guid);
ValidateGraph();
}
void RemoveShaderPropertyNoValidate(Guid guid)
{
public void ReplacePropertyNodeWithConcreteNode(PropertyNode propertyNode)
{
var property = properties.FirstOrDefault(x => x.guid == propertyNode.propertyGuid);
if (property != null)
{
AbstractMaterialNode node = null;
int slotId = -1;
if (property is FloatShaderProperty)
{
var createdNode = new Vector1Node();
createdNode.value = ((FloatShaderProperty) property).value;
slotId = Vector1Node.OutputSlotId;
node = createdNode;
}
else if (property is Vector2ShaderProperty)
{
var createdNode = new Vector2Node();
createdNode.value = ((Vector2ShaderProperty) property).value;
slotId = Vector2Node.OutputSlotId;
node = createdNode;
}
else if (property is Vector3ShaderProperty)
{
var createdNode = new Vector3Node();
createdNode.value = ((Vector3ShaderProperty) property).value;
slotId = Vector3Node.OutputSlotId;
node = createdNode;
}
else if (property is Vector4ShaderProperty)
{
var createdNode = new Vector4Node();
createdNode.value = ((Vector4ShaderProperty) property).value;
slotId = Vector4Node.OutputSlotId;
node = createdNode;
}
else if (property is ColorShaderProperty)
{
var createdNode = new ColorNode();
createdNode.color = ((ColorShaderProperty) property).value;
slotId = ColorNode.OutputSlotId;
node = createdNode;
}
if (node == null)
return;
var slot = propertyNode.FindOutputSlot<MaterialSlot>(PropertyNode.OutputSlotId);
node.drawState = propertyNode.drawState;
AddNodeNoValidate(node);
foreach (var edge in GetEdges(slot.slotReference).ToArray())
ConnectNoValidate(node.GetSlotReference(slotId), edge.inputSlot);
RemoveNodeNoValidate(propertyNode);
}
}
public override void ValidateGraph()
{
var propertyNodes = GetNodes<PropertyNode>().Where(n => !m_Properties.Any(p => p.guid == n.propertyGuid)).ToArray();
foreach (var pNode in propertyNodes)
ReplacePropertyNodeWithConcreteNode(pNode);
base.ValidateGraph();
}
public override Dictionary<SerializationHelper.TypeSerializationInfo, SerializationHelper.TypeSerializationInfo> GetLegacyTypeRemapping()
{
var result = base.GetLegacyTypeRemapping();

{
fullName = "UnityEngine.MaterialGraph.NormalNode"
};
result[normalNode] = SerializationHelper.GetTypeSerializableAsString(typeof(NormalNode));
result[normalNode] = SerializationHelper.GetTypeSerializableAsString(typeof(NormalVectorNode));
var worldPosNode = new SerializationHelper.TypeSerializationInfo
{

foreach (var property in m_Properties)
removedPropertyGuids.Add(property.guid);
foreach (var propertyGuid in removedPropertyGuids)
RemoveShaderProperty(propertyGuid);
RemoveShaderPropertyNoValidate(propertyGuid);
}
foreach (var otherProperty in otherMG.properties)
{

float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 color : COLOR;
float4 texcoord0 : TEXCOORD0;
float4 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/DynamicVectorMaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph
{

{
get { return m_Value; }
set { m_Value = value; }
}
public override VisualElement InstantiateControl()
{
int components =
concreteValueType == ConcreteSlotValueType.Vector4 ? 4 :
concreteValueType == ConcreteSlotValueType.Vector3 ? 3 :
concreteValueType == ConcreteSlotValueType.Vector2 ? 2 :
concreteValueType == ConcreteSlotValueType.Vector1 ? 1 : 0;
return new MultiFloatSlotControlView(owner, components, () => value, (newValue) => value = newValue);
}

81
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs


using System;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph
{

{
m_ShaderOutputName = shaderOutputName;
this.shaderStage = shaderStage;
}
public virtual VisualElement InstantiateControl()
{
return null;
}
static string ConcreteSlotValueTypeAsString(ConcreteSlotValueType type)

set { m_HasError = value; }
}
public bool IsCompatibleWithInputSlotType(ConcreteSlotValueType inputType)
bool IsCompatibleWithInputSlotType(SlotValueType inputType)
switch (concreteValueType)
switch (valueType)
case ConcreteSlotValueType.SamplerState:
return inputType == ConcreteSlotValueType.SamplerState;
case ConcreteSlotValueType.Matrix4:
return inputType == ConcreteSlotValueType.Matrix4
|| inputType == ConcreteSlotValueType.Matrix3
|| inputType == ConcreteSlotValueType.Matrix2;
case ConcreteSlotValueType.Matrix3:
return inputType == ConcreteSlotValueType.Matrix3
|| inputType == ConcreteSlotValueType.Matrix2;
case ConcreteSlotValueType.Matrix2:
return inputType == ConcreteSlotValueType.Matrix2;
case ConcreteSlotValueType.Texture2D:
return inputType == ConcreteSlotValueType.Texture2D;
case ConcreteSlotValueType.Vector4:
return inputType == ConcreteSlotValueType.Vector4
|| inputType == ConcreteSlotValueType.Vector3
|| inputType == ConcreteSlotValueType.Vector2
|| inputType == ConcreteSlotValueType.Vector1;
case ConcreteSlotValueType.Vector3:
return inputType == ConcreteSlotValueType.Vector3
|| inputType == ConcreteSlotValueType.Vector2
|| inputType == ConcreteSlotValueType.Vector1;
case ConcreteSlotValueType.Vector2:
return inputType == ConcreteSlotValueType.Vector2
|| inputType == ConcreteSlotValueType.Vector1;
case ConcreteSlotValueType.Vector1:
return inputType == ConcreteSlotValueType.Vector4
|| inputType == ConcreteSlotValueType.Vector3
|| inputType == ConcreteSlotValueType.Vector2
|| inputType == ConcreteSlotValueType.Vector1;
case SlotValueType.SamplerState:
return inputType == SlotValueType.SamplerState;
case SlotValueType.Matrix4:
return inputType == SlotValueType.Matrix4
|| inputType == SlotValueType.Matrix3
|| inputType == SlotValueType.Matrix2;
case SlotValueType.Matrix3:
return inputType == SlotValueType.Matrix3
|| inputType == SlotValueType.Matrix2;
case SlotValueType.Matrix2:
return inputType == SlotValueType.Matrix2;
case SlotValueType.Texture2D:
return inputType == SlotValueType.Texture2D;
case SlotValueType.Dynamic:
case SlotValueType.Vector4:
return inputType == SlotValueType.Vector4
|| inputType == SlotValueType.Vector3
|| inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
case SlotValueType.Vector3:
return inputType == SlotValueType.Vector3
|| inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
case SlotValueType.Vector2:
return inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
case SlotValueType.Vector1:
return inputType == SlotValueType.Vector4
|| inputType == SlotValueType.Vector3
|| inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
}
return false;
}

return otherSlot != null
&& otherSlot.owner != owner
&& otherSlot.isInputSlot != isInputSlot
&& (isInputSlot
? otherSlot.IsCompatibleWithInputSlotType(concreteValueType)
: IsCompatibleWithInputSlotType(otherSlot.concreteValueType));
&& ((isInputSlot
? otherSlot.IsCompatibleWithInputSlotType(valueType)
: IsCompatibleWithInputSlotType(otherSlot.valueType)));
}
public virtual string GetDefaultValue(GenerationMode generationMode)

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs


public override string GetPropertyDeclarationString()
{
string ss = referenceName + "_"
+ Enum.GetName(typeof(TextureSamplerState.FilterMode), value.filter) + "_"
+ Enum.GetName(typeof(TextureSamplerState.WrapMode), value.wrap) + "_sampler;";
#endif", ss);
#endif", referenceName);
}
public override PreviewProperty GetPreviewMaterialProperty()

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Texture2DInputMaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph
{

bool hidden = false)
: base(slotId, displayName, shaderOutputName, SlotType.Input, shaderStage, hidden)
{}
public override VisualElement InstantiateControl()
{
return new TextureSlotControlView(this);
}
public override string GetDefaultValue(GenerationMode generationMode)
{

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/UVMaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph
{

: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector2.zero, shaderStage, hidden)
{
this.channel = channel;
}
public override VisualElement InstantiateControl()
{
return new UVSlotControlView(this);
}
public override string GetDefaultValue(GenerationMode generationMode)

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector1MaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph
{

{
get { return m_Value; }
set { m_Value = value; }
}
public override VisualElement InstantiateControl()
{
return new MultiFloatSlotControlView(owner, 1, () => new Vector4(value, 0f, 0f, 0f), (newValue) => value = newValue.x);
}
protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2MaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph
{

{
get { return m_Value; }
set { m_Value = value; }
}
public override VisualElement InstantiateControl()
{
return new MultiFloatSlotControlView(owner, 2, () => value, (newValue) => value = newValue);
}
protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3MaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph
{

{
get { return m_Value; }
set { m_Value = value; }
}
public override VisualElement InstantiateControl()
{
return new MultiFloatSlotControlView(owner, 3, () => value, (newValue) => value = newValue);
}
protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4MaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph
{

{
get { return m_Value; }
set { m_Value = value; }
}
public override VisualElement InstantiateControl()
{
return new MultiFloatSlotControlView(owner, 4, () => value, (newValue) => value = newValue);
}
protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/AbstractMaterialNode.cs


var slot = FindSlot<MaterialSlot>(slotId);
if (slot == null)
throw new ArgumentException(string.Format("Attempting to use MaterialSlot({0}) on node of type {1} where this slot can not be found", slotId, this), "slotId");
return GetVariableNameForNode() + "_" + slot.shaderOutputName;
return "_" + GetVariableNameForNode() + "_" + GetHLSLSafeName(slot.shaderOutputName);
return name + "_" + GuidEncoder.Encode(guid);
return GetHLSLSafeName(name) + "_" + GuidEncoder.Encode(guid);
}
public static string GetHLSLSafeName(string input)
{
char[] arr = input.ToCharArray();
arr = Array.FindAll<char>(arr, (c => (char.IsLetterOrDigit(c))));
return new string(arr);
}
public sealed override void AddSlot(ISlot slot)

26
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/CodeFunctionNode.cs


{
return SlotValueType.Vector4;
}
if (t == typeof(Color))
{
return SlotValueType.Vector4;
}
if (t == typeof(Texture2D))
{
return SlotValueType.Texture2D;

var attribute = GetSlotAttribute(par);
MaterialSlot s;
if (attribute.binding == Binding.None || par.IsOut)
{
if (attribute.binding == Binding.None && !par.IsOut && par.ParameterType == typeof(Color))
s = new ColorMaterialSlot(attribute.slotId, par.Name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, hidden: attribute.hidden);
else if (attribute.binding == Binding.None || par.IsOut)
ConvertTypeToSlotValueType(par),
attribute.slotId,
par.Name,
par.Name,
par.IsOut ? SlotType.Output : SlotType.Input,
attribute.defaultValue ?? Vector4.zero,
hidden: attribute.hidden);
}
ConvertTypeToSlotValueType(par),
attribute.slotId,
par.Name,
par.Name,
par.IsOut ? SlotType.Output : SlotType.Input,
attribute.defaultValue ?? Vector4.zero,
hidden: attribute.hidden);
{
}
slots.Add(s);
m_Slots.Add(attribute);

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/PositionNode.cs


public class PositionNode : GeometryNode, IMayRequirePosition
{
private const int kOutputSlotId = 0;
public const string kOutputSlotName = "Position";
public const string kOutputSlotName = "Out";
public PositionNode()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/UVNode.cs


public class UVNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotId = 0;
private const string kOutputSlotName = "UV";
private const string kOutputSlotName = "Out";
[SerializeField]
private UVChannel m_OutputChannel;

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/VertexColorNode.cs


public class VertexColorNode : AbstractMaterialNode, IMayRequireVertexColor
{
private const int kOutputSlotId = 0;
private const string kOutputSlotName = "VertexColor";
private const string kOutputSlotName = "Out";
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }

{
name = "VertexColor";
name = "Vertex Color";
UpdateNodeAfterDeserialization();
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ViewDirectionNode.cs


public class ViewDirectionNode : GeometryNode, IMayRequireViewDirection
{
private const int kOutputSlotId = 0;
public const string kOutputSlotName = "ViewDirection";
public const string kOutputSlotName = "Out";
name = "ViewDirection";
name = "View Direction";
UpdateNodeAfterDeserialization();
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix2Node.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input/Matrix/Matrix 2")]
[Title("Input/Matrix/Matrix 2x2")]
const string kOutputSlotName = "Value";
const string kOutputSlotName = "Out";
[SerializeField]
Vector2 m_Row0;

public Matrix2Node()
{
name = "Matrix2";
name = "Matrix 2x2";
UpdateNodeAfterDeserialization();
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix3Node.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input/Matrix/Matrix 3")]
[Title("Input/Matrix/Matrix 3x3")]
const string kOutputSlotName = "Value";
const string kOutputSlotName = "Out";
[SerializeField]
Vector3 m_Row0;

public Matrix3Node()
{
name = "Matrix3";
name = "Matrix 3x3";
UpdateNodeAfterDeserialization();
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix4Node.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input/Matrix/Matrix 4")]
[Title("Input/Matrix/Matrix 4x4")]
const string kOutputSlotName = "Value";
const string kOutputSlotName = "Out";
[SerializeField]
Vector4 m_Row0;

public Matrix4Node()
{
name = "Matrix4";
name = "Matrix 4x4";
UpdateNodeAfterDeserialization();
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Time/SinTimeNode.cs


namespace UnityEditor.ShaderGraph
{
/*
[Title("Input/Time/Sine Time")]
public class SinTimeNode : AbstractMaterialNode, IMayRequireTime
{

return true;
}
}
*/
}

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Time/TimeNode.cs


namespace UnityEditor.ShaderGraph
{
/*
private const string kOutputSlotNameX = "Time/20";
private const string kOutputSlotNameY = "Time";
private const string kOutputSlotNameZ = "Time * 2";
private const string kOutputSlotNameW = "Time * 3";
private const string kOutputSlotNameX = "T/20";
private const string kOutputSlotNameY = "T";
private const string kOutputSlotNameZ = "T*2";
private const string kOutputSlotNameW = "T*3";
public const int OutputSlotId = 0;
public const int OutputSlotIdX = 1;

return true;
}
}
*/
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/AbsoluteNode.cs


}
static string Unity_Absolute(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = abs(argument);
Out = abs(In);
}
";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/LengthNode.cs


}
static string Unity_Length(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = length(argument);
Out = length(In);
}
";
}

70
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/LogNode.cs


using System.Reflection;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
public enum LogBase
{
BaseE,
Base2,
Base10
};
[Title("Math/Advanced/Log")]
public class LogNode : CodeFunctionNode
{

}
[SerializeField]
private LogBase m_LogBase = LogBase.BaseE;
[EnumControl("Base")]
public LogBase logBase
{
get { return m_LogBase; }
set
{
if (m_LogBase == value)
return;
m_LogBase = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
return GetType().GetMethod("Unity_Log", BindingFlags.Static | BindingFlags.NonPublic);
switch (m_LogBase)
{
case LogBase.Base2:
return GetType().GetMethod("Unity_Log2", BindingFlags.Static | BindingFlags.NonPublic);
case LogBase.Base10:
return GetType().GetMethod("Unity_Log10", BindingFlags.Static | BindingFlags.NonPublic);
default:
return GetType().GetMethod("Unity_Log", BindingFlags.Static | BindingFlags.NonPublic);
}
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = log(In);
}
";
}
static string Unity_Log2(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = log2(In);
}
";
}
static string Unity_Log10(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = log(argument);
Out = log10(In);
}
";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/NegateNode.cs


}
static string Unity_Negate(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = -1 * argument;
Out = -1 * In;
}
";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/NormalizeNode.cs


}
static string Unity_Normalize(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = normalize(argument);
Out = normalize(In);
}
";
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/PosterizeNode.cs


}
static string Unity_Posterize(
[Slot(0, Binding.None)] DynamicDimensionVector input,
[Slot(1, Binding.None)] DynamicDimensionVector stepsize,
[Slot(2, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] DynamicDimensionVector Steps,
[Slot(2, Binding.None)] out DynamicDimensionVector Out)
result = floor(input / stepsize) * stepsize;;
Out = floor(In / (1 / Steps)) * (1 / Steps);
}
";
}

55
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ReciprocalNode.cs


using System.Reflection;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
public enum ReciprocalMethod
{
Default,
Fast
};
[Title("Math/Advanced/Reciprocal")]
public class ReciprocalNode : CodeFunctionNode
{

}
[SerializeField]
private ReciprocalMethod m_ReciprocalMethod = ReciprocalMethod.Default;
[EnumControl("Method")]
public ReciprocalMethod reciprocalMethod
{
get { return m_ReciprocalMethod; }
set
{
if (m_ReciprocalMethod == value)
return;
m_ReciprocalMethod = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
return GetType().GetMethod("Unity_Reciprocal", BindingFlags.Static | BindingFlags.NonPublic);
switch (m_ReciprocalMethod)
{
case ReciprocalMethod.Fast:
return GetType().GetMethod("Unity_Reciprocal_Fast", BindingFlags.Static | BindingFlags.NonPublic);
default:
return GetType().GetMethod("Unity_Reciprocal", BindingFlags.Static | BindingFlags.NonPublic);
}
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = 1.0/In;
}
";
}
static string Unity_Reciprocal_Fast(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = 1.0/argument;
Out = rcp(In);
}
";
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/AddNode.cs


}
static string Unity_Add(
[Slot(0, Binding.None)] DynamicDimensionVector first,
[Slot(1, Binding.None)] DynamicDimensionVector second,
[Slot(2, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(2, Binding.None)] out DynamicDimensionVector Out)
result = first + second;
Out = A + B;
}
";
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs


}
static string Unity_Multiply(
[Slot(0, Binding.None)] DynamicDimensionVector first,
[Slot(1, Binding.None)] DynamicDimensionVector second,
[Slot(2, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(2, Binding.None)] out DynamicDimensionVector Out)
result = first * second;
Out = A * B;
}
";
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/PowerNode.cs


protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Pow", BindingFlags.Static | BindingFlags.NonPublic);
return GetType().GetMethod("Unity_Power", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_Pow(
[Slot(0, Binding.None)] DynamicDimensionVector first,
[Slot(1, Binding.None)] DynamicDimensionVector second,
[Slot(2, Binding.None)] out DynamicDimensionVector result)
static string Unity_Power(
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(2, Binding.None)] out DynamicDimensionVector Out)
result = pow(first, second);
Out = pow(A, B);
}
";
}

14
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/SquareRootNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Math/Basic/SquareRoot")]
[Title("Math/Basic/Square Root")]
name = "SquareRoot";
name = "Square Root";
return GetType().GetMethod("Unity_Sqrt", BindingFlags.Static | BindingFlags.NonPublic);
return GetType().GetMethod("Unity_SquareRoot", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_Sqrt(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
static string Unity_SquareRoot(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = sqrt(argument);
Out = sqrt(In);
}
";
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/SubtractNode.cs


}
static string Unity_Subtract(
[Slot(0, Binding.None)] DynamicDimensionVector first,
[Slot(1, Binding.None)] DynamicDimensionVector second,
[Slot(2, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(2, Binding.None)] out DynamicDimensionVector Out)
result = first - second;
Out = A - B;
}
";
}

14
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Interpolation/InverseLerpNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Math/Interpolation/InverseLerp")]
[Title("Math/Interpolation/Inverse Lerp")]
name = "InverseLerp";
name = "Inverse Lerp";
}
protected override MethodInfo GetFunctionToConvert()

static string Unity_InverseLerp(
[Slot(0, Binding.None)] DynamicDimensionVector inputA,
[Slot(1, Binding.None)] DynamicDimensionVector inputB,
[Slot(2, Binding.None)] DynamicDimensionVector t,
[Slot(3, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(2, Binding.None)] DynamicDimensionVector T,
[Slot(3, Binding.None)] out DynamicDimensionVector Out)
result = (t - inputA)/(inputB - inputA);
Out = (T - A)/(B - A);
}";
}
}

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Interpolation/LerpNode.cs


}
static string Unity_Lerp(
[Slot(0, Binding.None)] DynamicDimensionVector inputA,
[Slot(1, Binding.None)] DynamicDimensionVector inputB,
[Slot(2, Binding.None)] DynamicDimensionVector t,
[Slot(3, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(2, Binding.None)] DynamicDimensionVector T,
[Slot(3, Binding.None)] out DynamicDimensionVector Out)
result = lerp(inputA, inputB, t);
Out = lerp(A, B, T);
}";
}
}

14
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/ClampNode.cs


protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Smoothstep", BindingFlags.Static | BindingFlags.NonPublic);
return GetType().GetMethod("Unity_Clamp", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_Smoothstep(
[Slot(0, Binding.None)] DynamicDimensionVector input,
[Slot(1, Binding.None)] DynamicDimensionVector min,
[Slot(2, Binding.None)] DynamicDimensionVector max,
[Slot(3, Binding.None)] out DynamicDimensionVector result)
static string Unity_Clamp(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] DynamicDimensionVector Min,
[Slot(2, Binding.None, 1, 1, 1, 1)] DynamicDimensionVector Max,
[Slot(3, Binding.None)] out DynamicDimensionVector Out)
result = clamp(input, min, max);
Out = clamp(In, Min, Max);
}";
}
}

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/FractionNode.cs


protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Frac", BindingFlags.Static | BindingFlags.NonPublic);
return GetType().GetMethod("Unity_Fraction", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_Frac(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
static string Unity_Fraction(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = frac(argument);
Out = frac(In);
}
";
}

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/RemapNode.cs


}
static string Unity_Remap(
[Slot(0, Binding.None)] DynamicDimensionVector input,
[Slot(1, Binding.None)] Vector2 inMinMax,
[Slot(2, Binding.None)] Vector2 outMinMax,
[Slot(3, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None, 0, 1, 0, 0)] Vector2 InMinMax,
[Slot(2, Binding.None, 0, 1, 0, 0)] Vector2 OutMinMax,
[Slot(3, Binding.None)] out DynamicDimensionVector Out)
result = outMinMax.x + (input - inMinMax.x) * (outMinMax.y - outMinMax.x) / (inMinMax.y - inMinMax.x);
Out = OutMinMax.x + (In - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
}
";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/SaturateNode.cs


}
static string Unity_Saturate(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = saturate(argument);
Out = saturate(In);
}
";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/FloorNode.cs


}
static string Unity_Floor(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = floor(argument);
Out = floor(In);
}
";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/RoundNode.cs


}
static string Unity_Round(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = round(argument);
Out = round(In);
}
";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/SignNode.cs


}
static string Unity_Sign(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = sign(argument);
Out = sign(In);
}
";
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/StepNode.cs


}
static string Unity_Step(
[Slot(0, Binding.None)] DynamicDimensionVector first,
[Slot(1, Binding.None)] DynamicDimensionVector second,
[Slot(2, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(2, Binding.None)] out DynamicDimensionVector Out)
result = step(first, second);
Out = step(A, B);
}
";
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Round/TruncateNode.cs


}
static string Unity_Truncate(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = truncate(argument);
Out = trunc(In);
}
";
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Trigonometry/DegreesToRadiansNode.cs


{
public DegreesToRadiansNode()
{
name = "DegreesToRadians";
name = "Degrees To Radians";
}
protected override MethodInfo GetFunctionToConvert()

static string Unity_DegreesToRadians(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = radians(argument);
Out = radians(In);
}
";
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Trigonometry/RadiansToDegreesNode.cs


{
public RadiansToDegreesNode()
{
name = "RadiansToDegrees";
name = "Radians To Degrees";
}
protected override MethodInfo GetFunctionToConvert()

static string Unity_RadiansToDegrees(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = degrees(argument);
Out = degrees(In);
}
";
}

9
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/NoiseNode.cs


}
static string Unity_Noise(
[Slot(0, Binding.MeshUV0)] Vector2 uv,
[Slot(1, Binding.None)] out Vector1 noise)
[Slot(0, Binding.MeshUV0)] Vector2 UV,
[Slot(1, Binding.None,500f,500f,500f,500f)] Vector1 Scale,
[Slot(2, Binding.None)] out Vector1 Out)
{
return
@"

{
float freq = pow(2.0, float(i));
float amp = pow(0.5, float(3-i));
t += unity_valueNoise(float2(uv.x/freq, uv.y/freq))*amp;
t += unity_valueNoise(float2(UV.x*Scale/freq, UV.y*Scale/freq))*amp;
noise = t;
Out = t;
}
";
}

32
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/VoronoiNoise.cs


namespace UnityEditor.ShaderGraph
{
[Title("Procedural/Voronoi Noise")]
[Title("Procedural/Voronoi")]
name = "VoronoiNoise";
name = "Voronoi";
}
protected override MethodInfo GetFunctionToConvert()

static string Unity_VoronoiNoise(
[Slot(0, Binding.MeshUV0)] Vector2 uv,
[Slot(1, Binding.None, 2.0f, 0, 0, 0)] Vector1 angleOffset,
[Slot(2, Binding.None)] out Vector1 n1,
[Slot(2, Binding.None)] out Vector1 n2,
[Slot(2, Binding.None)] out Vector1 n3)
[Slot(0, Binding.MeshUV0)] Vector2 UV,
[Slot(1, Binding.None, 2.0f, 0, 0, 0)] Vector1 AngleOffset,
[Slot(2, Binding.None,5.0f,5.0f,5.0f,5.0f)] Vector1 CellDensity,
[Slot(3, Binding.None)] out Vector1 Out,
[Slot(4, Binding.None)] out Vector1 Cells)
float2 g = floor(uv);
float2 f = frac(uv);
float2 g = floor(UV * CellDensity);
float2 f = frac(UV * CellDensity);
float t = 8.0;
float3 res = float3(8.0, 0.0, 0.0);

{
float2 lattice = float2(x,y);
float2 offset = unity_voronoi_noise_randomVector(lattice + g, angleOffset);
float2 offset = unity_voronoi_noise_randomVector(lattice + g, AngleOffset);
float d = distance(lattice + offset, f);
if(d < res.x)

n1 = res.x;
n2 = res.y;
n3 = 1.0 - res.x;
Out = res.x;
Cells = res.y;
}
";
}

var preamble = @"
inline float2 unity_voronoi_noise_randomVector (float2 uv, float offset)
inline float2 unity_voronoi_noise_randomVector (float2 UV, float offset)
uv = frac(sin(mul(uv, m)) * 46839.32);
return float2(sin(uv.y*+offset)*0.5+0.5, cos(uv.x*offset)*0.5+0.5);
UV = frac(sin(mul(UV, m)) * 46839.32);
return float2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
}
";
visitor.AddShaderChunk(preamble, true);

61
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/PropertyNode.cs


{
UpdateNode();
}
public void ReplaceWithConcreteNode()
{
var matGraph = owner as MaterialGraph;
if (matGraph == null)
return;
var property = matGraph.properties.FirstOrDefault(x => x.guid == propertyGuid);
if (property != null)
{
AbstractMaterialNode node = null;
int slotId = -1;
if (property is FloatShaderProperty)
{
var createdNode = new Vector1Node();
createdNode.value = ((FloatShaderProperty) property).value;
slotId = Vector1Node.OutputSlotId;
node = createdNode;
}
else if (property is Vector2ShaderProperty)
{
var createdNode = new Vector2Node();
createdNode.value = ((Vector2ShaderProperty) property).value;
slotId = Vector2Node.OutputSlotId;
node = createdNode;
}
else if (property is Vector3ShaderProperty)
{
var createdNode = new Vector3Node();
createdNode.value = ((Vector3ShaderProperty) property).value;
slotId = Vector3Node.OutputSlotId;
node = createdNode;
}
else if (property is Vector4ShaderProperty)
{
var createdNode = new Vector4Node();
createdNode.value = ((Vector4ShaderProperty) property).value;
slotId = Vector4Node.OutputSlotId;
node = createdNode;
}
else if (property is ColorShaderProperty)
{
var createdNode = new ColorNode();
createdNode.color = ((ColorShaderProperty) property).value;
slotId = ColorNode.OutputSlotId;
node = createdNode;
}
if (node == null)
return;
var slot = FindOutputSlot<MaterialSlot>(OutputSlotId);
node.drawState = drawState;
owner.AddNode(node);
foreach (var edge in owner.GetEdges(slot.slotReference).ToArray())
owner.Connect(node.GetSlotReference(slotId), edge.inputSlot);
owner.RemoveNode(this);
}
}
}
}

21
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/SpherizeNode.cs


{
name = "Spherize";
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Spherize", BindingFlags.Static | BindingFlags.NonPublic);

[Slot(0, Binding.MeshUV0)] Vector2 uv,
[Slot(1, Binding.None)] Vector2 position,
[Slot(2, Binding.None)] Vector2 radiusAndStrength,
[Slot(3, Binding.None)] out Vector2 result)
[Slot(0, Binding.MeshUV0)] Vector2 UV,
[Slot(1, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector2 Center,
[Slot(2, Binding.None, 10f, 10f, 10f, 10f)] Vector2 Strength,
[Slot(3, Binding.None)] Vector2 Offset,
[Slot(4, Binding.None)] out Vector2 Out)
result = Vector2.zero;
Out = Vector2.zero;
{precision}2 fromUVToPoint = position - uv;
{precision} dist = length(fromUVToPoint);
{precision} mag = ((1.0 - (dist / radiusAndStrength.x)) * radiusAndStrength.y) * step(dist, radiusAndStrength.x);
result = uv + (mag * fromUVToPoint);
float2 delta = UV - Center;
float delta2 = dot(delta.xy, delta.xy);
float delta4 = delta2 * delta2;
float2 delta_offset = delta4 * Strength;
Out = UV + delta * delta_offset + Offset;
}";
}
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/SpherizeNode.cs.meta


fileFormatVersion: 2
guid: 249d9b9165bdf234e84a85cdb8aca2aa
timeCreated: 1495555169
guid: dfd538e33eb01974fad49a2533f8cff8
timeCreated: 1495729511
licenseType: Pro
MonoImporter:
serializedVersion: 2

98
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/RotateNode.cs


using System.Reflection;
using UnityEngine;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEditor.Graphing;
[Title("UV/UV Rotator")]
public class UVRotatorNode : CodeFunctionNode
public enum RotationUnit
{
Radians,
Degrees
};
[Title("UV/Rotate")]
public class RotateNode : CodeFunctionNode
public UVRotatorNode()
[SerializeField]
private RotationUnit m_Unit = RotationUnit.Radians;
[EnumControl("Unit")]
public RotationUnit unit
{
get { return m_Unit; }
set
{
if (m_Unit == value)
return;
m_Unit = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
public RotateNode()
name = "UVRotator";
name = "Rotate";
return GetType().GetMethod("Unity_UVRotator", BindingFlags.Static | BindingFlags.NonPublic);
if(m_Unit == RotationUnit.Radians)
return GetType().GetMethod("Unity_Rotate_Radians", BindingFlags.Static | BindingFlags.NonPublic);
else
return GetType().GetMethod("Unity_Rotate_Degrees", BindingFlags.Static | BindingFlags.NonPublic);
static string Unity_UVRotator(
[Slot(0, Binding.MeshUV0)] Vector4 uv,
[Slot(1, Binding.None)] Vector1 rotation,
[Slot(2, Binding.None)] out Vector4 result)
static string Unity_Rotate_Radians(
[Slot(0, Binding.MeshUV0)] Vector2 UV,
[Slot(1, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector2 Center,
[Slot(2, Binding.None)] Vector1 Rotation,
[Slot(3, Binding.None)] out Vector2 Out)
result = Vector2.zero;
Out = Vector2.zero;
uv.xy -= 0.5;
{precision} s = sin(rotation);
{precision} c = cos(rotation);
UV -= Center;
{precision} s = sin(Rotation);
{precision} c = cos(Rotation);
//center rotation matrix
{precision}2x2 rMatrix = float2x2(c, -s, s, c);
rMatrix *= 0.5;
rMatrix += 0.5;
rMatrix = rMatrix*2 - 1;
//multiply the UVs by the rotation matrix
UV.xy = mul(UV.xy, rMatrix);
UV += Center;
Out = UV;
}";
}
static string Unity_Rotate_Degrees(
[Slot(0, Binding.MeshUV0)] Vector2 UV,
[Slot(1, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector2 Center,
[Slot(2, Binding.None)] Vector1 Rotation,
[Slot(3, Binding.None)] out Vector2 Out)
{
Out = Vector2.zero;
return @"
{
//rotation matrix
Rotation = Rotation * (3.1415926f/180.0f);
UV -= Center;
{precision} s = sin(Rotation);
{precision} c = cos(Rotation);
//center rotation matrix
{precision}2x2 rMatrix = float2x2(c, -s, s, c);

//multiply the UVs by the rotation matrix
uv.xy = mul(uv.xy, rMatrix);
uv.xy += 0.5;
result = uv;
UV.xy = mul(UV.xy, rMatrix);
UV += Center;
Out = UV;
}
}
}

19
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/SaturationNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Art/Adjustments/Saturation")]
[Title("Artistic/Adjustment/Saturation")]
public class SaturationNode : CodeFunctionNode
{
public SaturationNode()

}
static string Unity_Saturation(
[Slot(0, Binding.None)] Vector3 first,
[Slot(1, Binding.None)] Vector1 second,
[Slot(2, Binding.None)] out Vector3 result)
[Slot(0, Binding.None)] Vector3 In,
[Slot(1, Binding.None, 1, 1, 1, 1)] Vector1 Saturation,
[Slot(2, Binding.None)] out Vector3 Out)
result = Vector3.zero;
Out = Vector3.zero;
// RGB Saturation (closer to a vibrance effect than actual saturation)
// Recommended workspace: ACEScg (linear)
// Optimal range: [0.0, 2.0]
// From PostProcessing
{precision} luma = dot(first, {precision}3(0.2126729, 0.7151522, 0.0721750));
result = luma.xxx + first.xxx * (second - luma.xxx);
{precision} luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750));
Out = luma.xxx + Saturation.xxx * (In - luma.xxx);
}
";
}

103
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/HueNode.cs


using System.Reflection;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
[Title("Art/Adjustments/Hue")]
public enum HueMode
{
Degrees,
Normalized
};
[Title("Artistic/Adjustment/Hue")]
public class HueNode : CodeFunctionNode
{
public HueNode()

[SerializeField]
private HueMode m_HueMode = HueMode.Degrees;
[EnumControl("Range")]
public HueMode hueMode
{
get { return m_HueMode; }
set
{
if (m_HueMode == value)
return;
m_HueMode = value;
if(onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
return GetType().GetMethod("Unity_Hue", BindingFlags.Static | BindingFlags.NonPublic);
switch(m_HueMode)
{
case HueMode.Normalized:
return GetType().GetMethod("Unity_Hue_Normalized", BindingFlags.Static | BindingFlags.NonPublic);
default:
return GetType().GetMethod("Unity_Hue_Degrees", BindingFlags.Static | BindingFlags.NonPublic);
}
}
static string Unity_Hue_Degrees(
[Slot(0, Binding.None)] Vector3 In,
[Slot(1, Binding.None)] Vector1 Hue,
[Slot(2, Binding.None)] out Vector3 Out)
{
Out = Vector3.zero;
return
@"
{
// RGB to HSV
{precision}4 K = {precision}4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
{precision}4 P = lerp({precision}4(In.bg, K.wz), {precision}4(In.gb, K.xy), step(In.b, In.g));
{precision}4 Q = lerp({precision}4(P.xyw, In.r), {precision}4(In.r, P.yzx), step(P.x, In.r));
{precision} D = Q.x - min(Q.w, Q.y);
{precision} E = 1e-10;
{precision}3 hsv = {precision}3(abs(Q.z + (Q.w - Q.y)/(6.0 * D + E)), D / (Q.x + E), Q.x);
{precision} hue = hsv.x + Hue / 360;
hsv.x = (hue < 0)
? hue + 1
: (hue > 1)
? hue - 1
: hue;
// HSV to RGB
{precision}4 K2 = {precision}4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
{precision}3 P2 = abs(frac(hsv.xxx + K2.xyz) * 6.0 - K2.www);
Out = hsv.z * lerp(K2.xxx, saturate(P2 - K2.xxx), hsv.y);
}";
static string Unity_Hue(
[Slot(0, Binding.None)] Vector1 argument,
[Slot(1, Binding.None)] out Vector3 result)
static string Unity_Hue_Normalized(
[Slot(0, Binding.None)] Vector3 In,
[Slot(1, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector1 Hue,
[Slot(2, Binding.None)] out Vector3 Out)
result = Vector3.zero;
Out = Vector3.zero;
{precision}4 K = {precision}4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
{precision}3 P = abs(frac(argument.xxx + K.xyz) * 6.0 - K.www);
result = 1 * lerp(K.xxx, saturate(P - K.xxx), 1);
}
";
// RGB to HSV
{precision}4 K = {precision}4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
{precision}4 P = lerp({precision}4(In.bg, K.wz), {precision}4(In.gb, K.xy), step(In.b, In.g));
{precision}4 Q = lerp({precision}4(P.xyw, In.r), {precision}4(In.r, P.yzx), step(P.x, In.r));
{precision} D = Q.x - min(Q.w, Q.y);
{precision} E = 1e-10;
{precision}3 hsv = {precision}3(abs(Q.z + (Q.w - Q.y)/(6.0 * D + E)), D / (Q.x + E), Q.x);
{precision} hue = hsv.x + Hue;
hsv.x = (hue < 0)
? hue + 1
: (hue > 1)
? hue - 1
: hue;
// HSV to RGB
{precision}4 K2 = {precision}4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
{precision}3 P2 = abs(frac(hsv.xxx + K2.xyz) * 6.0 - K2.www);
Out = hsv.z * lerp(K2.xxx, saturate(P2 - K2.xxx), hsv.y);
}";
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraphNode.cs


{
foreach (var slot in subGraphOutputNode.GetInputSlots<MaterialSlot>())
{
AddSlot(MaterialSlot.CreateMaterialSlot( slot.valueType,slot.id, slot.RawDisplayName(), slot.shaderOutputName, SlotType.Output, Vector4.zero));
AddSlot(MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(), slot.shaderOutputName, SlotType.Output, Vector4.zero));
validNames.Add(slot.id);
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/SubGraphNode.cs


}
#if UNITY_EDITOR
[ObjectControl("Subgraph")]
[ObjectControl("")]
public MaterialSubGraphAsset subGraphAsset
{
get

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/ShaderGenerator.cs


if (combinedRequierments.requiresVertexColor)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.color;", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/DefaultControl.cs


return new ColorControlView(null, node, propertyInfo);
if (typeof(Enum).IsAssignableFrom(propertyInfo.PropertyType))
return new EnumControlView(null, node, propertyInfo);
if (propertyInfo.PropertyType == typeof(Gradient))
return new GradientControlView(null, node, propertyInfo);
if (propertyInfo.PropertyType == typeof(Texture2D))
return new TextureControlView(null, node, propertyInfo);
if (MultiFloatControlView.validTypes.Contains(propertyInfo.PropertyType))
return new MultiFloatControlView(null, "X", "Y", "Z", "W", node, propertyInfo);
if (typeof(Object).IsAssignableFrom(propertyInfo.PropertyType))

26
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ObjectControl.cs


using System;
using System.Reflection;
using UnityEditor.Experimental.UIElements;
using UnityEditor.ShaderGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.ShaderGraph.Drawing.Controls

{
AbstractMaterialNode m_Node;
PropertyInfo m_PropertyInfo;
GUIContent m_Label;
public ObjectControlView(string label, AbstractMaterialNode node, PropertyInfo propertyInfo)
{

m_PropertyInfo = propertyInfo;
m_Label = new GUIContent(label ?? propertyInfo.Name);
Add(new IMGUIContainer(OnGUIHandler));
label = label ?? propertyInfo.Name;
if (!string.IsNullOrEmpty(label))
Add(new Label{text = label});
var value = (Object) m_PropertyInfo.GetValue(m_Node, null);
var objectField = new ObjectField { objectType = propertyInfo.PropertyType, value = value };
objectField.OnValueChanged(OnValueChanged);
Add(objectField);
void OnGUIHandler()
void OnValueChanged(ChangeEvent<Object> evt)
using (var changeCheckScope = new EditorGUI.ChangeCheckScope())
if (evt.newValue != value)
value = EditorGUILayout.MiniThumbnailObjectField(m_Label, value, m_PropertyInfo.PropertyType);
if (changeCheckScope.changed)
{
m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);
m_PropertyInfo.SetValue(m_Node, value, null);
}
m_Node.owner.owner.RegisterCompleteObjectUndo("Change + " + m_Node.name);
m_PropertyInfo.SetValue(m_Node, evt.newValue, null);
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/PropertyControl.cs


var currentSelectedIndex = propertiesGUID.IndexOf(currentGUID);
using (var changeCheckScope = new EditorGUI.ChangeCheckScope())
{
var value = EditorGUILayout.Popup("Property", currentSelectedIndex, properties.Select(x => x.displayName).ToArray());
var value = EditorGUILayout.Popup(currentSelectedIndex, properties.Select(x => x.displayName).ToArray());
if (changeCheckScope.changed)
{
m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);

59
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs


using UnityEngine.Experimental.UIElements;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph;
using UnityEngine.AI;
[Serializable]
class PersistentMesh
{
[SerializeField]
Mesh m_Mesh;
public Mesh mesh
{
get { return m_Mesh; }
set { m_Mesh = value; }
}
}
public class GraphInspectorView : VisualElement, IDisposable
{
int m_SelectionHash;

VisualElement m_ContentContainer;
Experimental.UIElements.ObjectField m_PreviewMeshPicker;
ObjectField m_PreviewMeshPicker;
AbstractNodeEditorView m_EditorView;
TypeMapper m_TypeMapper;

List<INode> m_SelectedNodes;
PersistentMesh m_PersistentMasterNodePreviewMesh;
persistenceKey = "GraphInspector";
m_Graph = graph;
m_PreviewManager = previewManager;
m_SelectedNodes = new List<INode>();

m_PreviewTextureView = new PreviewTextureView {name = "preview", image = Texture2D.blackTexture};
bottomContainer.Add(m_PreviewTextureView);
m_PreviewMeshPicker = new Experimental.UIElements.ObjectField() { objectType = typeof(Mesh) };
m_PreviewMeshPicker = new ObjectField() { objectType = typeof(Mesh) };
m_PreviewMeshPicker.OnValueChanged(OnPreviewMeshChanged);
bottomContainer.Add(m_PreviewMeshPicker);
}
Add(bottomContainer);

if (m_MasterNode != null)
{
m_PreviewHandle = m_PreviewManager.GetPreview(m_MasterNode);
m_PreviewHandle.mesh = null;
m_PreviewHandle.onPreviewChanged += OnPreviewChanged;
}
}

void OnPreviewChanged()
{
m_PreviewTextureView.image = m_PreviewHandle.texture ?? Texture2D.blackTexture;
m_PreviewHandle.mesh = m_PreviewMeshPicker.value as Mesh;
}
void OnPreviewMeshChanged(ChangeEvent<UnityEngine.Object> changeEvent)
{
if (changeEvent.newValue == null)
{
m_PreviewHandle.mesh = null;
m_PersistentMasterNodePreviewMesh.mesh = null;
}
Mesh changedMesh = changeEvent.newValue as Mesh;
if (changedMesh)
{
m_PreviewHandle.mesh = changedMesh;
m_PersistentMasterNodePreviewMesh.mesh = changedMesh;
}
masterNode.onModified(masterNode, ModificationScope.Node);
SavePersistentData();
}
public override void OnPersistentDataReady()
{
base.OnPersistentDataReady();
string key = GetFullHierarchicalPersistenceKey();
m_PersistentMasterNodePreviewMesh = GetOrCreatePersistentData<PersistentMesh>(m_PersistentMasterNodePreviewMesh, key);
m_PreviewMeshPicker.SetValueAndNotify(m_PersistentMasterNodePreviewMesh.mesh);
}
public void UpdateSelection(IEnumerable<INode> nodes)

79
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/ShaderPropertyView.cs


using System;
using UnityEditor.Experimental.UIElements;
using Object = UnityEngine.Object;
namespace UnityEditor.ShaderGraph.Drawing.Inspector
{

this.graph = graph;
this.property = property;
var displayNameField = new TextField { name = "displayName", value = property.displayName };
displayNameField.OnValueChanged(OnDisplayNameChanged);
Add(displayNameField);
m_ValueAction = null;
if (property is FloatShaderProperty)
m_ValueAction = FloatField;

m_ValueAction = Vector3Field;
else if (property is Vector4ShaderProperty)
m_ValueAction = Vector4Field;
if (m_ValueAction != null)
{
Add(new IMGUIContainer(ValueField) { name = "value" });
}
m_ValueAction = ColorField;
{
var fProp = (ColorShaderProperty) property;
var colorField = new ColorField { name = "value", value = fProp.value };
colorField.OnValueChanged(OnColorChanged);
Add(colorField);
}
m_ValueAction = TextureField;
Assert.IsNotNull(m_ValueAction);
{
var fProp = (TextureShaderProperty) property;
var objectField = new ObjectField { name = "value", objectType = typeof(Texture), value = fProp.value.texture };
objectField.OnValueChanged(OnTextureChanged);
Add(objectField);
}
Add(new IMGUIContainer(DisplayNameField) { name = "displayName" });
Add(new IMGUIContainer(ValueField) { name = "value" });
void OnColorChanged(ChangeEvent<Color> evt)
{
var fProp = (ColorShaderProperty) property;
if (evt.newValue != fProp.value)
{
fProp.value = evt.newValue;
NotifyNodes();
}
}
void OnTextureChanged(ChangeEvent<Object> evt)
{
var fProp = (TextureShaderProperty) property;
var newValue = (Texture)evt.newValue;
if (newValue != fProp.value.texture)
{
fProp.value.texture = newValue;
NotifyNodes();
}
}
void OnDisplayNameChanged(ChangeEvent<string> evt)
{
if (evt.newValue != property.displayName)
{
property.displayName = evt.newValue;
NotifyNodes();
}
}
}
void DisplayNameField()
{
EditorGUI.BeginChangeCheck();
property.displayName = EditorGUILayout.DelayedTextField(property.displayName);
if (EditorGUI.EndChangeCheck())
NotifyNodes();
}
void ValueField()

{
var fProp = (Vector4ShaderProperty) property;
fProp.value = EditorGUILayout.Vector4Field("", fProp.value);
}
void ColorField()
{
var fProp = (ColorShaderProperty) property;
fProp.value = EditorGUILayout.ColorField("", fProp.value);
}
void TextureField()
{
var fProp = (TextureShaderProperty) property;
fProp.value.texture = EditorGUILayout.MiniThumbnailObjectField(new GUIContent("Texture"), fProp.value.texture, typeof(Texture), null) as Texture;
}
}
}

30
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/StandardNodeEditorView.cs


public class StandardNodeEditorView : AbstractNodeEditorView
{
NodeEditorHeaderView m_HeaderView;
VisualElement m_SlotsContainer;
VisualElement m_DefaultSlotValuesSection;
int m_SlotsHash;
public override INode node
{

m_HeaderView = new NodeEditorHeaderView() { type = "node" };
Add(m_HeaderView);
m_DefaultSlotValuesSection = new VisualElement();
m_DefaultSlotValuesSection.AddToClassList("section");
{
var sectionTitle = new VisualElement { text = "Default Slot Values" };
sectionTitle.AddToClassList("title");
m_DefaultSlotValuesSection.Add(sectionTitle);
m_SlotsContainer = new VisualElement { name = "slots" };
m_DefaultSlotValuesSection.Add(m_SlotsContainer);
}
Add(m_DefaultSlotValuesSection);
}
void OnModified(INode changedNode, ModificationScope scope)

m_HeaderView.title = node.name;
var slotsHash = UIUtilities.GetHashCode(node.GetInputSlots<MaterialSlot>().Select(s => UIUtilities.GetHashCode(s.slotReference.nodeGuid.GetHashCode(), s.slotReference.slotId)));
if (slotsHash != m_SlotsHash)
{
m_SlotsHash = slotsHash;
m_SlotsContainer.Clear();
foreach (var slot in node.GetInputSlots<MaterialSlot>())
m_SlotsContainer.Add(new IMGUISlotEditorView(slot));
if (m_SlotsContainer.Any())
m_DefaultSlotValuesSection.RemoveFromClassList("hidden");
else
m_DefaultSlotValuesSection.AddToClassList("hidden");
}
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/NodeCreator.cs


.OfType<PropertyNode>();
foreach (var propNode in slected)
propNode.ReplaceWithConcreteNode();
((AbstractMaterialGraph)propNode.owner).ReplacePropertyNodeWithConcreteNode(propNode);
}
private void OnConvertToProperty()

265
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs


using System.IO;
using System.Linq;
using System.Text;
using UnityEditor.Experimental.UIElements;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEditor.Graphing.Util;
using UnityEngine;

public class MaterialGraphEditWindow : EditorWindow
{
[SerializeField]
Object m_Selected;
string m_Selected;
[SerializeField]
SerializableGraphObject m_GraphObject;

m_GraphEditorView.onConvertToSubgraphClick += ToSubGraph;
m_GraphEditorView.onShowInProjectClick += PingAsset;
rootVisualContainer.Add(graphEditorView);
rootVisualContainer.parent.clippingOptions = VisualElement.ClippingOptions.ClipContents;
}
}
}

}
}
public Object selected
public string selectedGuid
{
get { return m_Selected; }
private set { m_Selected = value; }

if (materialGraph == null)
return;
if (graphEditorView == null)
graphEditorView = new GraphEditorView(materialGraph, selected) { persistenceKey = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(selected)) };
{
var asset = AssetDatabase.LoadAssetAtPath<Object>(AssetDatabase.GUIDToAssetPath(selectedGuid));
graphEditorView = new GraphEditorView(materialGraph, asset.name) {persistenceKey = AssetDatabase.AssetPathToGUID(AssetDatabase.GUIDToAssetPath(selectedGuid))};
}
graphEditorView.previewManager.HandleGraphChanges();
graphEditorView.previewManager.RenderPreviews();

void OnDestroy()
{
if (EditorUtility.DisplayDialog("Shader Graph Might Have Been Modified", "Do you want to save the changes you made in the shader graph?", "Save", "Don't Save"))
{
if (graphObject.isDirty && EditorUtility.DisplayDialog("Shader Graph Might Have Been Modified", "Do you want to save the changes you made in the shader graph?", "Save", "Don't Save"))
}
void OnGUI()
public void PingAsset()
if (graphEditorView == null)
return;
var e = Event.current;
var graphView = graphEditorView.graphView;
var graphViewHasSelection = graphView.selection.Any();
if (e.type == EventType.ValidateCommand && (
e.commandName == "Copy" && graphViewHasSelection
|| e.commandName == "Paste" && CopyPasteGraph.FromJson(EditorGUIUtility.systemCopyBuffer) != null
|| e.commandName == "Duplicate" && graphViewHasSelection
|| e.commandName == "Cut" && graphViewHasSelection
|| (e.commandName == "Delete" || e.commandName == "SoftDelete") && graphViewHasSelection))
if (selectedGuid != null)
e.Use();
var path = AssetDatabase.GUIDToAssetPath(selectedGuid);
var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
EditorGUIUtility.PingObject(asset);
if (e.type == EventType.ExecuteCommand)
{
if (e.commandName == "Copy")
{
EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(graphView.SelectionAsCopyPasteGraph(), true);
}
if (e.commandName == "Paste")
{
graphObject.RegisterCompleteObjectUndo("Paste");
graphView.InsertCopyPasteGraph(CopyPasteGraph.FromJson(EditorGUIUtility.systemCopyBuffer));
}
if (e.commandName == "Duplicate")
{
graphObject.RegisterCompleteObjectUndo("Duplicate");
graphView.InsertCopyPasteGraph(CopyPasteGraph.FromJson(JsonUtility.ToJson(graphView.SelectionAsCopyPasteGraph(), false)));
}
if (e.commandName == "Cut")
{
graphObject.RegisterCompleteObjectUndo("Cut");
EditorGUIUtility.systemCopyBuffer = JsonUtility.ToJson(graphView.SelectionAsCopyPasteGraph(), true);
graphObject.graph.RemoveElements(graphView.selection.OfType<MaterialNodeView>().Select(x => x.node as INode), graphView.selection.OfType<Edge>().Select(x => x.userData as IEdge));
graphObject.graph.ValidateGraph();
}
if (e.commandName == "Delete" || e.commandName == "SoftDelete")
{
graphObject.RegisterCompleteObjectUndo("Delete");
graphObject.graph.RemoveElements(graphView.selection.OfType<MaterialNodeView>().Select(x => x.node as INode), graphView.selection.OfType<Edge>().Select(x => x.userData as IEdge));
graphObject.graph.ValidateGraph();
}
}
if (e.type == EventType.KeyDown)
{
if (e.keyCode == KeyCode.A)
graphView.FrameAll();
if (e.keyCode == KeyCode.F)
graphView.FrameSelection();
if (e.keyCode == KeyCode.O)
graphView.FrameOrigin();
if (e.keyCode == KeyCode.Tab)
graphView.FrameNext();
if (e.keyCode == KeyCode.Tab && (e.modifiers & EventModifiers.Shift) > 0)
graphView.FramePrev();
}
}
public void PingAsset()
{
if (selected != null)
EditorGUIUtility.PingObject(selected);
if (selected != null && graphObject != null)
if (selectedGuid != null && graphObject != null)
var path = AssetDatabase.GetAssetPath(selected);
var path = AssetDatabase.GUIDToAssetPath(selectedGuid);
{
}
if (m_GraphObject.graph.GetType() == typeof(ShaderGraph.MaterialGraph))
if (m_GraphObject.graph.GetType() == typeof(MaterialGraph))
UpdateShaderGraphOnDisk(path);
if (m_GraphObject.graph.GetType() == typeof(LayeredShaderGraph))

if (m_GraphObject.graph.GetType() == typeof(MasterRemapGraph))
UpdateAbstractSubgraphOnDisk<MasterRemapGraph>(path);
var windows = Resources.FindObjectsOfTypeAll<MaterialGraphEditWindow>();
foreach (var materialGraphEditWindow in windows)
{
materialGraphEditWindow.Rebuild();
}
}
}

var graphView = graphEditorView.graphView;
var nodes = graphView.selection.OfType<MaterialNodeView>().Where(x => !(x.node is PropertyNode)).Select(x => x.node as INode).ToArray();
Vector2 middle = Vector2.zero;
foreach (var node in nodes)
{
middle += node.drawState.position.center;
}
middle /= nodes.Length;
var copyPasteGraph = new CopyPasteGraph(
graphView.selection.OfType<MaterialNodeView>().Where(x => !(x.node is PropertyNode)).Select(x => x.node as INode),
graphView.selection.OfType<Edge>().Select(x => x.userData as IEdge));

return;
var graph = new SubGraph();
graph.AddNode(new SubGraphOutputNode());
var subGraph = new SubGraph();
subGraph.AddNode(new SubGraphOutputNode());
var nodeGuidMap = new Dictionary<Guid, Guid>();
foreach (var node in deserialized.GetNodes<INode>())

nodeGuidMap[oldGuid] = newGuid;
graph.AddNode(node);
subGraph.AddNode(node);
// remap outputs to the subgraph
var onlyInputInternallyConnected = new List<IEdge>();
var onlyOutputInternallyConnected = new List<IEdge>();
// figure out what needs remapping
var externalOutputSlots = new List<IEdge>();
var externalInputSlots = new List<IEdge>();
foreach (var edge in deserialized.edges)
{
var outputSlot = edge.outputSlot;

Guid remappedInputNodeGuid;
var outputRemapExists = nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid);
var inputRemapExists = nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid);
var outputSlotExistsInSubgraph = nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid);
var inputSlotExistsInSubgraph = nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid);
if (outputRemapExists && inputRemapExists)
if (outputSlotExistsInSubgraph && inputSlotExistsInSubgraph)
graph.Connect(outputSlotRef, inputSlotRef);
subGraph.Connect(outputSlotRef, inputSlotRef);
else if (outputRemapExists)
else if (outputSlotExistsInSubgraph)
onlyOutputInternallyConnected.Add(edge);
externalInputSlots.Add(edge);
else if (inputRemapExists)
else if (inputSlotExistsInSubgraph)
onlyInputInternallyConnected.Add(edge);
externalOutputSlots.Add(edge);
var uniqueInputEdges = onlyOutputInternallyConnected.GroupBy(
// Find the unique edges coming INTO the graph
var uniqueIncomingEdges = externalOutputSlots.GroupBy(
(key, edges) => new { slotRef = key, edges = edges.ToList() });
foreach (var group in uniqueInputEdges)
(key, edges) => new {slotRef = key, edges = edges.ToList()});
var externalInputNeedingConnection = new List<KeyValuePair<IEdge, IShaderProperty>>();
foreach (var group in uniqueIncomingEdges)
IShaderProperty prop;
case ConcreteSlotValueType.SamplerState:
break;
case ConcreteSlotValueType.Matrix4:
break;
case ConcreteSlotValueType.Matrix3:
break;
case ConcreteSlotValueType.Matrix2:
break;
prop = new TextureShaderProperty();
prop = new Vector4ShaderProperty();
prop = new Vector3ShaderProperty();
prop = new Vector2ShaderProperty();
prop = new FloatShaderProperty();
if (prop != null)
{
subGraph.AddShaderProperty(prop);
var propNode = new PropertyNode();
subGraph.AddNode(propNode);
propNode.propertyGuid = prop.guid;
foreach (var edge in group.edges)
{
subGraph.Connect(
new SlotReference(propNode.guid, PropertyNode.OutputSlotId),
new SlotReference(nodeGuidMap[edge.inputSlot.nodeGuid], edge.inputSlot.slotId));
externalInputNeedingConnection.Add(new KeyValuePair<IEdge, IShaderProperty>(edge, prop));
}
}
var uniqueOutputEdges = onlyInputInternallyConnected.GroupBy(
var uniqueOutgoingEdges = externalInputSlots.GroupBy(
(key, edges) => new { slot = key, edges = edges.ToList() });
(key, edges) => new {slot = key, edges = edges.ToList()});
var outputsNeedingConnection = new List<KeyValuePair<IEdge, IEdge>>();
foreach (var group in uniqueOutputEdges)
var externalOutputsNeedingConnection = new List<KeyValuePair<IEdge, IEdge>>();
foreach (var group in uniqueOutgoingEdges)
var outputNode = graph.outputNode;
var outputNode = subGraph.outputNode;
var slotId = outputNode.AddSlot();
var inputSlotRef = new SlotReference(outputNode.guid, slotId);

var newEdge = graph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef);
outputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
var newEdge = subGraph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef);
externalOutputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
File.WriteAllText(path, EditorJsonUtility.ToJson(graph));
File.WriteAllText(path, EditorJsonUtility.ToJson(subGraph));
var subGraph = AssetDatabase.LoadAssetAtPath(path, typeof(MaterialSubGraphAsset)) as MaterialSubGraphAsset;
if (subGraph == null)
var loadedSubGraph = AssetDatabase.LoadAssetAtPath(path, typeof(MaterialSubGraphAsset)) as MaterialSubGraphAsset;
if (loadedSubGraph == null)
var ds = subGraphNode.drawState;
ds.position = new Rect(middle, Vector2.one);
subGraphNode.drawState = ds;
subGraphNode.subGraphAsset = subGraph;
subGraphNode.subGraphAsset = loadedSubGraph;
/* foreach (var edgeMap in inputsNeedingConnection)
{
graphObject.graph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode.guid, edgeMap.Value.outputSlot.slotId));
}*/
foreach (var edgeMap in externalInputNeedingConnection)
{
graphObject.graph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode.guid, edgeMap.Value.guid.GetHashCode()));
}
foreach (var edgeMap in outputsNeedingConnection)
foreach (var edgeMap in externalOutputsNeedingConnection)
{
graphObject.graph.Connect(new SlotReference(subGraphNode.guid, edgeMap.Value.inputSlot.slotId), edgeMap.Key.inputSlot);
}

List<PropertyCollector.TextureInfo> configuredTextures;
graph.GetShader(Path.GetFileNameWithoutExtension(path), GenerationMode.ForReals, out configuredTextures);
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderImporter;
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderGraphImporter;
var textureNames = new List<string>();
var textures = new List<Texture>();
foreach (var textureInfo in configuredTextures.Where(x => x.modifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetDefaultTextures(textureNames.ToArray(), textures.ToArray());
textureNames.Clear();
textures.Clear();
foreach (var textureInfo in configuredTextures.Where(x => !x.modifiable))
{
var texture = EditorUtility.InstanceIDToObject(textureInfo.textureId) as Texture;
if (texture == null)
continue;
textureNames.Add(textureInfo.name);
textures.Add(texture);
}
shaderImporter.SetNonModifiableTextures(textureNames.ToArray(), textures.ToArray());
public void ChangeSelection(Object newSelection, Type graphType)
private void Rebuild()
{
if (graphObject != null && graphObject.graph != null)
{
var subNodes = graphObject.graph.GetNodes<AbstractSubGraphNode>();
foreach (var node in subNodes)
node.UpdateSlots();
}
}
public void ChangeSelection(string newSelectionGuid, Type graphType)
if (!EditorUtility.IsPersistent(newSelection))
var asset = AssetDatabase.LoadAssetAtPath<Object>(AssetDatabase.GUIDToAssetPath(newSelectionGuid));
if (asset == null)
if (selected == newSelection)
if (!EditorUtility.IsPersistent(asset))
selected = newSelection;
if (selectedGuid == newSelectionGuid)
return;
var path = AssetDatabase.GetAssetPath(newSelection);
selectedGuid = newSelectionGuid;
var path = AssetDatabase.GetAssetPath(asset);
var textGraph = File.ReadAllText(path, Encoding.UTF8);
graphObject = CreateInstance<SerializableGraphObject>();
graphObject.hideFlags = HideFlags.HideAndDontSave;

graphEditorView = new GraphEditorView(m_GraphObject.graph as AbstractMaterialGraph, selected) { persistenceKey = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(selected)) };
graphEditorView = new GraphEditorView(m_GraphObject.graph as AbstractMaterialGraph, asset.name) { persistenceKey = AssetDatabase.GUIDToAssetPath(selectedGuid) };
titleContent = new GUIContent(selected.name);
titleContent = new GUIContent(asset.name);
Repaint();
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphPreviewGenerator.cs


Graphics.DrawMesh(
mode == PreviewMode.Preview3D ? previewMesh : quad,
Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one),
mode == PreviewMode.Preview3D ? Matrix4x4.TRS(-previewMesh.bounds.center, Quaternion.identity, Vector3.one) : Matrix4x4.identity,
mat,
1,
m_Camera,

87
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs


using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph;
using UnityEngine.Rendering;
using Object = UnityEngine.Object;
namespace UnityEditor.ShaderGraph.Drawing

HashSet<Guid> m_TimeDependentPreviews = new HashSet<Guid>();
Material m_PreviewMaterial;
MaterialPropertyBlock m_PreviewPropertyBlock;
MaterialGraphPreviewGenerator m_PreviewGenerator = new MaterialGraphPreviewGenerator();
PreviewSceneResources m_SceneResources;
Texture2D m_ErrorTexture;
DateTime m_LastUpdate;

m_ErrorTexture.SetPixel(1, 1, Color.magenta);
m_ErrorTexture.filterMode = FilterMode.Point;
m_ErrorTexture.Apply();
m_SceneResources = new PreviewSceneResources();
foreach (var node in m_Graph.GetNodes<INode>())
AddPreview(node);

{
var previewData = new PreviewData
{
node = node,
if (m_Previews.ContainsKey(node.guid))
{
Debug.LogWarningFormat("A preview already exists for {0} {1}", node.name, node.guid);
RemovePreview(node);
}
m_Previews.Add(node.guid, previewData);
m_DirtyShaders.Add(node.guid);
node.onModified += OnNodeModified;

m_DirtyShaders.Add(edge.inputSlot.nodeGuid);
}
List<PreviewData> m_RenderList2D = new List<PreviewData>();
List<PreviewData> m_RenderList3D = new List<PreviewData>();
public void RenderPreviews()
{
if (previewRate == PreviewRate.Off)

m_PreviewProperties.Clear();
}
var time = Time.realtimeSinceStartup;
if (previewData.shader == null)
{
previewData.texture = null;

previewData.texture = m_ErrorTexture;
continue;
}
var node = m_Graph.GetNodeFromGuid(nodeGuid);
if (previewData.previewMode == PreviewMode.Preview2D)
m_RenderList2D.Add(previewData);
else
m_RenderList3D.Add(previewData);
}
var time = Time.realtimeSinceStartup;
EditorUtility.SetCameraAnimateMaterialsTime(m_SceneResources.camera, time);
m_SceneResources.light0.enabled = true;
m_SceneResources.light0.intensity = 1.0f;
m_SceneResources.light0.transform.rotation = Quaternion.Euler(50f, 50f, 0);
m_SceneResources.light1.enabled = true;
m_SceneResources.light1.intensity = 1.0f;
m_SceneResources.camera.clearFlags = CameraClearFlags.Depth;
// Render 2D previews
m_SceneResources.camera.transform.position = -Vector3.forward * 2;
m_SceneResources.camera.transform.rotation = Quaternion.identity;
m_SceneResources.camera.orthographicSize = 1;
m_SceneResources.camera.orthographic = true;
foreach (var previewData in m_RenderList2D)
{
m_PreviewMaterial.shader = previewData.shader;
m_SceneResources.camera.targetTexture = previewData.renderTexture;
var previousRenderTexure = RenderTexture.active;
RenderTexture.active = previewData.renderTexture;
GL.Clear(true, true, Color.black);
Graphics.Blit(Texture2D.whiteTexture, previewData.renderTexture, m_SceneResources.checkerboardMaterial);
Graphics.DrawMesh(m_SceneResources.quad, Matrix4x4.identity, m_PreviewMaterial, 1, m_SceneResources.camera, 0, m_PreviewPropertyBlock, ShadowCastingMode.Off, false, null, false);
var previousUseSRP = Unsupported.useScriptableRenderPipeline;
Unsupported.useScriptableRenderPipeline = false;
m_SceneResources.camera.Render();
Unsupported.useScriptableRenderPipeline = previousUseSRP;
RenderTexture.active = previousRenderTexure;
previewData.texture = previewData.renderTexture;
}
m_RenderList2D.Clear();
// Render 3D previews
m_SceneResources.camera.transform.position = -Vector3.forward * 5;
m_SceneResources.camera.transform.rotation = Quaternion.identity;
m_SceneResources.camera.orthographic = false;
foreach (var previewData in m_RenderList3D)
{
m_PreviewGenerator.DoRenderPreview(previewData.renderTexture, m_PreviewMaterial, previewData.mesh, previewData.previewMode, node is IMasterNode, time, m_PreviewPropertyBlock);
m_SceneResources.camera.targetTexture = previewData.renderTexture;
var previousRenderTexure = RenderTexture.active;
RenderTexture.active = previewData.renderTexture;
GL.Clear(true, true, Color.black);
Graphics.Blit(Texture2D.whiteTexture, previewData.renderTexture, m_SceneResources.checkerboardMaterial);
var mesh = previewData.mesh ?? m_SceneResources.sphere;
Graphics.DrawMesh(mesh, Matrix4x4.TRS(-mesh.bounds.center, Quaternion.identity, Vector3.one), m_PreviewMaterial, 1, m_SceneResources.camera, 0, m_PreviewPropertyBlock, ShadowCastingMode.Off, false, null, false);
var previousUseSRP = Unsupported.useScriptableRenderPipeline;
Unsupported.useScriptableRenderPipeline = previewData.node is IMasterNode;
m_SceneResources.camera.Render();
Unsupported.useScriptableRenderPipeline = previousUseSRP;
RenderTexture.active = previousRenderTexure;
m_RenderList3D.Clear();
m_SceneResources.light0.enabled = false;
m_SceneResources.light1.enabled = false;
foreach (var nodeGuid in m_DirtyPreviews)
{

if (previewData.shader != null && MaterialGraphAsset.ShaderHasError(previewData.shader))
{
ShaderUtil.ClearShaderErrors(previewData.shader);
Object.DestroyImmediate(previewData.shader, true);
previewData.shader = null;
}

}
else
{
ShaderUtil.ClearShaderErrors(previewData.shader);
ShaderUtil.UpdateShaderAsset(previewData.shader, previewData.shaderString);
}

if (m_PreviewMaterial != null)
Object.DestroyImmediate(m_PreviewMaterial, true);
m_PreviewMaterial = null;
if (m_PreviewGenerator != null)
m_PreviewGenerator.Dispose();
m_PreviewGenerator = null;
if (m_SceneResources != null)
m_SceneResources.Dispose();
m_SceneResources = null;
var previews = m_Previews.ToList();
foreach (var kvp in previews)
DestroyPreview(kvp.Key, kvp.Value);

public class PreviewData
{
public INode node { get; set; }
public Shader shader { get; set; }
public Mesh mesh { get; set; }
public string shaderString { get; set; }

63
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs


ToolbarView m_ToolbarView;
ToolbarButtonView m_TimeButton;
ToolbarButtonView m_CopyToClipboardButton;
PreviewManager m_PreviewManager;
public Action onUpdateAssetClick { get; set; }

get { return m_GraphInspectorView; }
}
public GraphEditorView(AbstractMaterialGraph graph, Object asset)
public GraphEditorView(AbstractMaterialGraph graph, string assetName)
{
m_Graph = graph;
AddStyleSheetPath("Styles/MaterialGraph");

var textureInfo = new List<PropertyCollector.TextureInfo>();
PreviewMode previewMode;
string shader = graph.GetShader(copyFromNode, GenerationMode.ForReals, asset.name, out textureInfo, out previewMode);
string shader = graph.GetShader(copyFromNode, GenerationMode.ForReals, assetName, out textureInfo, out previewMode);
GUIUtility.systemCopyBuffer = shader;
}
));

m_GraphView.AddManipulator(new GraphDropTarget(graph));
content.Add(m_GraphView);
m_GraphInspectorView = new GraphInspectorView(asset.name, previewManager, graph) { name = "inspector" };
m_GraphInspectorView = new GraphInspectorView(assetName, previewManager, graph) { name = "inspector" };
m_GraphView.onSelectionChanged += m_GraphInspectorView.UpdateSelection;
content.Add(m_GraphInspectorView);

{
foreach (var edge in graphViewChange.edgesToCreate)
{
m_Graph.owner.RegisterCompleteObjectUndo("Connect Edge");
{
m_Graph.owner.RegisterCompleteObjectUndo("Connect Edge");
}
}
graphViewChange.edgesToCreate.Clear();
}

void OnNodeChanged(INode inNode, ModificationScope scope)
{
if (m_GraphView == null)
return;
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, inNode);
foreach (var node in dependentNodes)

nodesToUpdate.Add((MaterialNodeView)edgeView.input.node);
}
foreach (var node in nodesToUpdate)
node.UpdatePortInputVisibilities();
var nodeView = new MaterialNodeView(node as AbstractMaterialNode, m_PreviewManager) { userData = node };
node.onModified += OnNodeChanged;
var nodeView = new MaterialNodeView { userData = node };
nodeView.Initialize(m_GraphView, node as AbstractMaterialNode, m_PreviewManager);
node.onModified += OnNodeChanged;
if (sourceNode == null)
{
Debug.LogWarning("Source node is null");
return null;
}
if (targetNode == null)
{
Debug.LogWarning("Target node is null");
return null;
}
var sourceAnchor = sourceNodeView.outputContainer.Children().OfType<NodeAnchor>().FirstOrDefault(x => x.userData is ISlot && (x.userData as ISlot).Equals(sourceSlot));
var sourceAnchor = sourceNodeView.outputContainer.Children().OfType<Port>().FirstOrDefault(x => x.userData is ISlot && (x.userData as ISlot).Equals(sourceSlot));
var targetAnchor = targetNodeView.inputContainer.Children().OfType<NodeAnchor>().FirstOrDefault(x => x.userData is ISlot && (x.userData as ISlot).Equals(targetSlot));
var targetAnchor = targetNodeView.inputContainer.Children().OfType<Port>().FirstOrDefault(x => x.userData is ISlot && (x.userData as ISlot).Equals(targetSlot));
var edgeView = new GradientEdge
{

edgeView.output.Connect(edgeView);
edgeView.input.Connect(edgeView);
m_GraphView.AddElement(edgeView);
sourceNodeView.RefreshAnchors();
targetNodeView.RefreshAnchors();
sourceNodeView.RefreshPorts();
targetNodeView.RefreshPorts();
sourceNodeView.UpdatePortInputTypes();
targetNodeView.UpdatePortInputTypes();
return edgeView;
}

while (nodeStack.Any())
{
var nodeView = nodeStack.Pop();
foreach (var anchorView in nodeView.outputContainer.Children().OfType<NodeAnchor>())
nodeView.UpdatePortInputTypes();
foreach (var anchorView in nodeView.outputContainer.Children().OfType<Port>())
{
var sourceSlot = (MaterialSlot)anchorView.userData;
foreach (var edgeView in anchorView.connections.OfType<GradientEdge>())

}
}
}
foreach (var anchorView in nodeView.inputContainer.Children().OfType<NodeAnchor>())
foreach (var anchorView in nodeView.inputContainer.Children().OfType<Port>())
if (targetSlot.valueType != SlotValueType.Dynamic)
continue;
if (sourceSlot.valueType == SlotValueType.Dynamic)
edgeView.UpdateClasses(sourceSlot.concreteValueType, targetSlot.concreteValueType);
var connectedNodeView = edgeView.output.node as MaterialNodeView;
if (connectedNodeView != null && !nodeViews.Contains(connectedNodeView))
edgeView.UpdateClasses(sourceSlot.concreteValueType, targetSlot.concreteValueType);
var connectedNodeView = edgeView.output.node as MaterialNodeView;
if (connectedNodeView != null && !nodeViews.Contains(connectedNodeView))
{
nodeStack.Push(connectedNodeView);
nodeViews.Add(connectedNodeView);
}
nodeStack.Push(connectedNodeView);
nodeViews.Add(connectedNodeView);
}
}
}

45
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs


{
public AbstractMaterialGraph graph { get; private set; }
public override List<NodeAnchor> GetCompatibleAnchors(NodeAnchor startAnchor, NodeAdapter nodeAdapter)
public override List<Port> GetCompatiblePorts(Port startAnchor, NodeAdapter nodeAdapter)
var compatibleAnchors = new List<NodeAnchor>();
var compatibleAnchors = new List<Port>();
var startSlot = startAnchor.userData as MaterialSlot;
if (startSlot == null)
return compatibleAnchors;

startStage = NodeUtils.FindEffectiveShaderStage(startSlot.owner, startSlot.isOutputSlot);
foreach (var candidateAnchor in anchors.ToList())
foreach (var candidateAnchor in ports.ToList())
{
var candidateSlot = candidateAnchor.userData as MaterialSlot;
if (!startSlot.IsCompatibleWith(candidateSlot))

public OnSelectionChanged onSelectionChanged;
public MaterialGraphView(AbstractMaterialGraph graph)
public MaterialGraphView()
{
serializeGraphElements = SerializeGraphElementsImplementation;
canPasteSerializedData = CanPasteSerializedDataImplementation;
unserializeAndPaste = UnserializeAndPasteImplementation;
deleteSelection = DeleteSelectionImplementation;
}
public MaterialGraphView(AbstractMaterialGraph graph) : this()
{
this.graph = graph;
}

base.ClearSelection();
SelectionChanged();
}
}
string SerializeGraphElementsImplementation(IEnumerable<GraphElement> elements)
{
var graph = new CopyPasteGraph(elements.OfType<MaterialNodeView>().Select(x => (INode)x.node), elements.OfType<Edge>().Select(x => x.userData).OfType<IEdge>());
return JsonUtility.ToJson(graph, true);
}
bool CanPasteSerializedDataImplementation(string serializedData)
{
return CopyPasteGraph.FromJson(serializedData) != null;
}
public static class GraphViewExtensions
{
internal static CopyPasteGraph SelectionAsCopyPasteGraph(this MaterialGraphView graphView)
void UnserializeAndPasteImplementation(string operationName, string serializedData)
return new CopyPasteGraph(graphView.selection.OfType<MaterialNodeView>().Select(x => (INode) x.node), graphView.selection.OfType<Edge>().Select(x => x.userData).OfType<IEdge>());
graph.owner.RegisterCompleteObjectUndo(operationName);
var pastedGraph = CopyPasteGraph.FromJson(serializedData);
this.InsertCopyPasteGraph(pastedGraph);
void DeleteSelectionImplementation(string operationName, GraphView.AskUser askUser)
{
graph.owner.RegisterCompleteObjectUndo(operationName);
graph.RemoveElements(selection.OfType<MaterialNodeView>().Select(x => (INode)x.node), selection.OfType<Edge>().Select(x => x.userData).OfType<IEdge>());
}
}
public static class GraphViewExtensions
{
internal static void InsertCopyPasteGraph(this MaterialGraphView graphView, CopyPasteGraph copyGraph)
{
if (copyGraph == null)

100
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs


PreviewTextureView m_PreviewTextureView;
VisualElement m_ControlsContainer;
VisualElement m_PreviewContainer;
List<Attacher> m_Attachers;
GraphView m_GraphView;
public MaterialNodeView(AbstractMaterialNode inNode, PreviewManager previewManager)
public void Initialize(GraphView graphView, AbstractMaterialNode inNode, PreviewManager previewManager)
{
AddToClassList("MaterialNode");

m_GraphView = graphView;
persistenceKey = node.guid.ToString();
UpdateTitle();
m_ControlsContainer = new VisualElement

foreach (var propertyInfo in node.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
foreach (IControlAttribute attribute in propertyInfo.GetCustomAttributes(typeof(IControlAttribute), false))
m_ControlViews.Add(attribute.InstantiateControl(node, propertyInfo));
m_Attachers = new List<Attacher>(node.GetInputSlots<MaterialSlot>().Count());
AddSlots(node.GetSlots<ISlot>());
AddSlots(node.GetSlots<MaterialSlot>());
UpdatePortInputVisibilities();
SetPosition(new Rect(node.drawState.position.x, node.drawState.position.y, 0, 0));
UpdateControls();

UpdateSize();
}
clippingOptions = ClippingOptions.ClipContents;
mainContainer.clippingOptions = ClippingOptions.ClipContents;
}
public AbstractMaterialNode node { get; private set; }

}
UpdateControls();
UpdatePortInputVisibilities();
}
}

// Update slots to match node modification
if (scope == ModificationScope.Topological)
{
var slots = node.GetSlots<ISlot>().ToList();
var slots = node.GetSlots<MaterialSlot>().ToList();
if (!slots.Contains(anchor.userData as ISlot))
if (!slots.Contains(anchor.userData as MaterialSlot))
foreach (var ve in anchorsToRemove)
inputContainer.Remove(ve);
foreach (var anchorElement in anchorsToRemove)
{
inputContainer.Remove(anchorElement);
var attacher = m_Attachers.FirstOrDefault(a => a.target == anchorElement);
if (attacher != null)
{
attacher.Detach();
attacher.element.parent.Remove(attacher.element);
m_Attachers.Remove(attacher);
}
}
if (!slots.Contains(anchor.userData as ISlot))
if (!slots.Contains(anchor.userData as MaterialSlot))
AddSlots(slots.Except(inputContainer.Children().Concat(outputContainer.Children()).Select(data => data.userData as ISlot)));
foreach (var port in inputContainer.Union(outputContainer).OfType<Port>())
{
var slot = (MaterialSlot)port.userData;
port.portName = slot.displayName;
}
AddSlots(slots.Except(inputContainer.Children().Concat(outputContainer.Children()).Select(data => data.userData as MaterialSlot)));
inputContainer.Sort((x, y) => slots.IndexOf(x.userData as ISlot) - slots.IndexOf(y.userData as ISlot));
inputContainer.Sort((x, y) => slots.IndexOf(x.userData as MaterialSlot) - slots.IndexOf(y.userData as MaterialSlot));
outputContainer.Sort((x, y) => slots.IndexOf(x.userData as ISlot) - slots.IndexOf(y.userData as ISlot));
outputContainer.Sort((x, y) => slots.IndexOf(x.userData as MaterialSlot) - slots.IndexOf(y.userData as MaterialSlot));
UpdatePortInputVisibilities();
void AddSlots(IEnumerable<ISlot> slots)
void AddSlots(IEnumerable<MaterialSlot> slots)
{
foreach (var slot in slots)
{

var data = InstantiateNodeAnchor(slot.isInputSlot ? Direction.Input : Direction.Output, typeof(Vector4));
data.capabilities &= ~Capabilities.Movable;
data.anchorName = slot.displayName;
data.userData = slot;
var port = InstantiatePort(Orientation.Horizontal, slot.isInputSlot ? Direction.Input : Direction.Output, typeof(Vector4));
port.capabilities &= ~Capabilities.Movable;
port.portName = slot.displayName;
port.userData = slot;
outputContainer.Add(data);
{
outputContainer.Add(port);
}
inputContainer.Add(data);
{
inputContainer.Add(port);
var portInputView = new PortInputView(slot);
m_GraphView.AddElement(portInputView);
m_Attachers.Add(new Attacher(portInputView, port, SpriteAlignment.LeftCenter) { distance = 0f });
}
}
}
public void UpdatePortInputVisibilities()
{
foreach (var attacher in m_Attachers)
{
var slot = (MaterialSlot)attacher.target.userData;
attacher.element.visible = expanded && !node.owner.GetEdges(node.GetSlotReference(slot.id)).Any();
}
}
public void UpdatePortInputTypes()
{
foreach (var anchor in inputContainer.Concat(outputContainer).OfType<Port>())
{
var slot = (MaterialSlot) anchor.userData;
anchor.portName = slot.displayName;
}
foreach (var attacher in m_Attachers)
{
var portInputView = (PortInputView)attacher.element;
portInputView.UpdateSlotType();
}
}

public void Dispose()
{
foreach (var attacher in m_Attachers)
{
((PortInputView) attacher.element).Dispose();
attacher.Detach();
attacher.element.parent.Remove(attacher.element);
}
m_Attachers.Clear();
node = null;
if (m_PreviewData != null)
{

34
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporterEditor.cs


{
AssetImporter importer = target as AssetImporter;
Debug.Assert(importer != null, "importer != null");
ShowGraphEditWindow(importer.assetPath);
}
}
static bool ShowGraphEditWindow(string path)
{
var asset = AssetDatabase.LoadAssetAtPath<Object>(path) as MasterRemapGraphAsset;
if (asset == null)
return false;
var foundWindow = false;
foreach (var w in Resources.FindObjectsOfTypeAll<MaterialGraphEditWindow>())
{
if (w.selected == asset)
{
foundWindow = true;
w.Focus();
}
}
if (!foundWindow)
{
var window = CreateInstance<MaterialGraphEditWindow>();
window.Show();
window.ChangeSelection(asset, typeof(MasterRemapGraph));
ShaderGraphImporterEditor.ShowGraphEditWindow(importer.assetPath);
return true;
}
[OnOpenAsset]
static bool OnOpenAsset(int instanceID, int line)
{
var path = AssetDatabase.GetAssetPath(instanceID);
return ShowGraphEditWindow(path);
}
}

137
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/ShaderGraphImporter.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor.ShaderGraph.Drawing;
using Object = UnityEngine.Object;
using UnityEditor.Experimental.AssetImporters;
class ShaderGraphImporter : ICustomShaderImporter
[ScriptedImporter(1, "shadergraph")]
public class ShaderGraphImporter : ScriptedImporter
private static string GetShaderText<T>(string path) where T : IShaderGraph
private string errorShader = @"
Shader ""Hidden/GraphErrorShader2""
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#include ""UnityCG.cginc""
struct appdata_t {
float4 vertex : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(1,0,1,1);
}
ENDCG
}
}
Fallback Off
}";
public override void OnImportAsset(AssetImportContext ctx)
{
var oldShader = AssetDatabase.LoadAssetAtPath<Shader>(ctx.assetPath);
if (oldShader != null)
ShaderUtil.ClearShaderErrors(oldShader);
List<PropertyCollector.TextureInfo> configuredTextures;
var text = GetShaderText<MaterialGraph>(ctx.assetPath, out configuredTextures);
if (text == null)
text = errorShader;
var shader = ShaderUtil.CreateShaderAsset(text);
EditorMaterialUtility.SetShaderDefaults(
shader,
configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(),
configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
EditorMaterialUtility.SetShaderNonModifiableDefaults(
shader,
configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(),
configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray());
ctx.AddObjectToAsset("MainAsset", shader);
ctx.SetMainObject(shader);
}
private static string GetShaderText<T>(string path, out List<PropertyCollector.TextureInfo> configuredTextures) where T : IShaderGraph
{
try
{

var name = Path.GetFileNameWithoutExtension(path);
List<PropertyCollector.TextureInfo> configuredTextures;
var shaderString = graph.GetShader(string.Format("graphs/{0}", name), GenerationMode.ForReals, out configuredTextures);
Debug.Log(shaderString);
return shaderString;

// ignored
}
return null;
}
public string GetShaderText(string path)
{
if (path.EndsWith("LayeredShaderGraph", StringComparison.InvariantCultureIgnoreCase))
return GetShaderText<LayeredShaderGraph>(path);
if (path.EndsWith("shaderGraph", StringComparison.InvariantCultureIgnoreCase))
return GetShaderText<MaterialGraph>(path);
configuredTextures = new List<PropertyCollector.TextureInfo>();
}
public bool IsValidForPath(string path)
{
return
path.EndsWith("LayeredShaderGraph", StringComparison.InvariantCultureIgnoreCase)
|| path.EndsWith("shaderGraph", StringComparison.InvariantCultureIgnoreCase);
}
public void OpenAsset(string path)
{
ShowGraphEditWindow(path);
}
internal static void ShowGraphEditWindow(string path)
{
var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
var extension = Path.GetExtension(path);
Type graphType;
if (extension == ".ShaderGraph")
graphType = typeof(MaterialGraph);
else if (extension == ".LayeredShaderGraph")
graphType = typeof(LayeredShaderGraph);
else if (extension == ".ShaderSubGraph")
graphType = typeof(SubGraph);
else if (extension == ".ShaderRemapGraph")
graphType = typeof(MasterRemapGraph);
else
return;
var foundWindow = false;
foreach (var w in Resources.FindObjectsOfTypeAll<MaterialGraphEditWindow>())
{
if (w.selected == asset)
{
foundWindow = true;
w.Focus();
}
}
if (!foundWindow)
{
var window = ScriptableObject.CreateInstance<MaterialGraphEditWindow>();
window.Show();
window.ChangeSelection(asset, graphType);
}
}
}

37
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/ShaderSubGraphImporterEditor.cs


using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.ShaderGraph.Drawing;
using UnityEditor.ShaderGraph;
using Debug = System.Diagnostics.Debug;
[CustomEditor(typeof(ShaderSubGraphImporter))]

{
AssetImporter importer = target as AssetImporter;
Debug.Assert(importer != null, "importer != null");
ShowGraphEditWindow(importer.assetPath);
ShaderGraphImporterEditor.ShowGraphEditWindow(importer.assetPath);
}
private static bool ShowGraphEditWindow(string path)
{
var asset = AssetDatabase.LoadAssetAtPath<Object>(path) as MaterialSubGraphAsset;
if (asset == null)
return false;
var foundWindow = false;
foreach (var w in Resources.FindObjectsOfTypeAll<MaterialGraphEditWindow>())
{
if (w.selected == asset)
{
foundWindow = true;
w.Focus();
}
}
if (!foundWindow)
{
var window = CreateInstance<MaterialGraphEditWindow>();
window.Show();
window.ChangeSelection(asset, typeof(SubGraph));
}
return true;
}
[OnOpenAsset]
static bool OnOpenAsset(int instanceID, int line)
{
var path = AssetDatabase.GetAssetPath(instanceID);
return ShowGraphEditWindow(path);
}
}

160
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss


background-color: rgb(0, 225, 25);
}
PortInputView {
width: 212;
height: 22;
padding-top: 1;
flex-direction: row;
justify-content: flex-end;
}
PortInputView > #container > #slot {
width: 8;
height: 8;
background-color: #2B2B2B;
border-color: #232323;
border-top-width: 1;
border-bottom-width: 1;
border-left-width: 1;
border-right-width: 1;
border-radius: 4;
margin-left: 6;
margin-right: 6;
align-items: center;
justify-content: center;
}
PortInputView > #edge {
position-type: absolute;
position-right: 0;
position-top: 10.5;
height: 2;
width: 20;
background-color: #ff0000;
}
PortInputView > #container > #slot > #dot {
width: 4;
height: 4;
background-color: #ff0000;
border-radius: 4;
}
PortInputView.typeMatrix4 > #container > #slot > #dot,
PortInputView.typeMatrix3 > #container > #slot > #dot,
PortInputView.typeMatrix2 > #container > #slot > #dot {
background-color: #8FC1DF;
}
PortInputView.typeMatrix4,
PortInputView.typeMatrix3,
PortInputView.typeMatrix2 {
edge-color: #8FC1DF;
}
PortInputView.typeTexture2D > #container > #slot > #dot {
background-color: #FF8B8B;
}
PortInputView.typeTexture2D {
edge-color: #FF8B8B;
}
PortInputView.typeVector4 > #container > #slot > #dot {
background-color: #FBCBF4;
}
PortInputView.typeVector4 {
edge-color: #FBCBF4;
}
PortInputView.typeVector3 > #container > #slot > #dot {
background-color: #F6FF9A;
}
PortInputView.typeVector3 {
edge-color: #F6FF9A;
}
PortInputView.typeVector2 > #container > #slot > #dot {
background-color: #9AEF92;
}
PortInputView.typeVector2 {
edge-color: #9AEF92;
}
PortInputView.typeVector1 > #container > #slot > #dot {
background-color: #84E4E7;
}
PortInputView.typeVector1 {
edge-color: #84E4E7;
}
PortInputView > #container {
background-color: #393939;
flex-direction: row;
align-items: center;
padding-left: 8;
margin-right: 10;
border-left-width: 1;
border-top-width: 1;
border-right-width: 1;
border-bottom-width: 1;
border-color: rgba(25, 25, 25, 0.8);
border-radius: 2;
}
TextureSlotControlView {
flex-direction: row;
align-items: center;
}
TextureSlotControlView > ObjectField {
margin-top: 0;
margin-bottom: 0;
margin-left: 0;
margin-right: 0;
width: 100;
}
MultiFloatSlotControlView {
flex-direction: row;
align-items: center;
}
MultiFloatSlotControlView > Label {
margin-left: 0;
margin-right: 0;
}
MultiFloatSlotControlView > DoubleField {
width: 30;
margin-left: 0;
margin-right: 0;
}
UVSlotControlView > EnumField {
margin-top: 0;
margin-bottom: 0;
margin-left: 0;
margin-right: 0;
width: 40;
}
ColorSlotControlView {
flex-direction: row;
align-items: center;
}
ColorSlotControlView > ColorField {
width: 50;
}
.edge.fromMatrix4, .edge.fromMatrix3, .edge.fromMatrix2 {
edge-output-color: #8FC1DF;
}

margin-left: 0;
margin-right: 0;
}
ObjectControlView {
flex-direction: row;
}
ObjectControlView > ObjectField {
flex: 1;
}

2
MaterialGraphProject/ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2018.1.0a1
m_EditorVersion: 2018.1.0a4

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/ConstantNode.cs.meta


fileFormatVersion: 2
guid: fea1e18ab449c174d91a3f41a220aa4e
timeCreated: 1495448829
licenseType: Pro
guid: f48f68efc30ae334098ff30e88fbf9db
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0

24
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/UV/RadialShearNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("UV/RadialShearNode")]
[Title("UV/Radial Shear")]
public RadialShearNode()
{
name = "Radial Shear";
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_RadialShear", BindingFlags.Static | BindingFlags.NonPublic);

[Slot(0, Binding.MeshUV0)] Vector2 uv,
[Slot(1, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector2 center,
[Slot(2, Binding.None, 1f, 1f, 1f, 1f)] Vector2 shearAmount,
[Slot(3, Binding.None)] Vector2 offset,
[Slot(4, Binding.None)] out Vector2 result)
[Slot(0, Binding.MeshUV0)] Vector2 UV,
[Slot(1, Binding.None, 0.5f, 0.5f, 0.5f, 0.5f)] Vector2 Center,
[Slot(2, Binding.None, 10f, 10f, 10f, 10f)] Vector2 Strength,
[Slot(3, Binding.None)] Vector2 Offset,
[Slot(4, Binding.None)] out Vector2 Out)
result = Vector2.zero;
Out = Vector2.zero;
float2 delta = uv - center;
float2 delta = UV - Center;
float2 delta_offset = delta2 * shearAmount;
result = uv + float2(delta.y, -delta.x) * delta_offset + offset;
float2 delta_offset = delta2 * Strength;
Out = UV + float2(delta.y, -delta.x) * delta_offset + Offset;
}
";
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/Texture2DNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Texture/Sample 2D")]
public class Sample2DTexture : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
[Title("Input/Texture/Texture 2D")]
public class Texture2DNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireMeshUV
{
public const int OutputSlotRGBAId = 0;
public const int OutputSlotRId = 4;

public override bool hasPreview { get { return true; } }
public Sample2DTexture()
public Texture2DNode()
name = "Sample2DTexture";
name = "Texture 2D";
UpdateNodeAfterDeserialization();
}

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/SamplerStateNode.cs


public SamplerStateNode()
{
name = "SamplerState";
name = "Sampler State";
UpdateNodeAfterDeserialization();
}

private const string kOutputSlotName = "Sampler Output";
private const string kOutputSlotName = "Out";
public sealed override void UpdateNodeAfterDeserialization()
{

{
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,
value = new TextureSamplerState()
{
filter = m_filter,

public override string GetVariableNameForNode()
{
string ss = name + "_"
+ Enum.GetName(typeof(TextureSamplerState.FilterMode), filter) + "_"
+ Enum.GetName(typeof(TextureSamplerState.WrapMode), wrap) + "_sampler;";
string ss = GetHLSLSafeName(name) + "_"
+ Enum.GetName(typeof(TextureSamplerState.FilterMode), filter) + "_"
+ Enum.GetName(typeof(TextureSamplerState.WrapMode), wrap) + "_sampler";
return ss;
}
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/ColorNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input/Color")]
[Title("Input/Basic/Color")]
public class ColorNode : AbstractMaterialNode, IGeneratesBodyCode, IPropertyFromNode
{
[SerializeField]

private const string kOutputSlotName = "Color";
private const string kOutputSlotName = "Out";
public ColorNode()
{

59
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ExponentialNode.cs


using System.Reflection;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
[Title("Math/Basic/Exponential")]
public enum ExponentialBase
{
BaseE,
Base2
};
[Title("Math/Advanced/Exponential")]
public class ExponentialNode : CodeFunctionNode
{
public ExponentialNode()

[SerializeField]
private ExponentialBase m_ExponentialBase = ExponentialBase.BaseE;
[EnumControl("Base")]
public ExponentialBase exponentialBase
{
get { return m_ExponentialBase; }
set
{
if (m_ExponentialBase == value)
return;
m_ExponentialBase = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
return GetType().GetMethod("Unity_Exp", BindingFlags.Static | BindingFlags.NonPublic);
switch (m_ExponentialBase)
{
case ExponentialBase.Base2:
return GetType().GetMethod("Unity_Exponential2", BindingFlags.Static | BindingFlags.NonPublic);
default:
return GetType().GetMethod("Unity_Exponential", BindingFlags.Static | BindingFlags.NonPublic);
}
}
static string Unity_Exponential(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = exp(In);
}
";
static string Unity_Exp(
[Slot(0, Binding.None)] DynamicDimensionVector argument,
[Slot(1, Binding.None)] out DynamicDimensionVector result)
static string Unity_Exponential2(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out DynamicDimensionVector Out)
result = exp(argument);
Out = exp2(In);
}
";
}

2
MaterialGraphProject/Assets/NewNodes/Editor/Kill/CheckerboardNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Procedural/Checkerboard")]
[Title("OLD/Checkerboard")]
public class CheckerboardNode : CodeFunctionNode
{
public CheckerboardNode()

2
MaterialGraphProject/Assets/NewNodes/Editor/Kill/GradientRampNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Procedural/Gradient Ramp")]
[Title("OLD/Gradient Ramp")]
public class GradientRampNode : CodeFunctionNode
{
public GradientRampNode()

4
MaterialGraphProject/Assets/NewNodes/Editor/Kill/LineNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Procedural/Line")]
[Title("OLD/Line")]
public class LineNode : CodeFunctionNode
{
public LineNode()

{precision} t = dot(aTop, aTob) / dot(aTob, aTob);
t = clamp(t, 0.0, 1.0);
{precision} d = 1.0 / length(uv - (startPoint + aTob * t));
return clamp(d, 0.0, 1.0);
result = clamp(d, 0.0, 1.0);
}";
}
}

2
MaterialGraphProject/Assets/NewNodes/Editor/Kill/PulseNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Procedural/Pulse")]
[Title("OLD/Pulse")]
public class PulseNode : CodeFunctionNode
{
public PulseNode()

2
MaterialGraphProject/Assets/NewNodes/Editor/Kill/UVPannerNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("UV/UV Panner")]
[Title("OLD/UV Panner")]
public class PannerNode : CodeFunctionNode
{
public PannerNode()

4
MaterialGraphProject/Assets/NewNodes/Editor/Kill/UVTileNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("UV/UV Tile")]
[Title("OLD/UV Tile")]
public class UVTileNode : CodeFunctionNode
{
public UVTileNode()

return
@"
{
result uv * tileFactor;
result = uv * tileFactor;
}";
}
}

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector1Node.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input/Vector/Vector 1")]
[Title("Input/Basic/Vector 1")]
public const int OutputSlotId = 0;
private const string kOutputSlotName = "Out";
/*[SerializeField]
private FloatPropertyChunk.FloatType m_floatType;*/

public const int OutputSlotId = 0;
private const string kOutputSlotName = "Value";
name = "Vector1";
name = "Vector 1";
UpdateNodeAfterDeserialization();
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector2Node.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input/Vector/Vector 2")]
[Title("Input/Basic/Vector 2")]
public class Vector2Node : AbstractMaterialNode, IGeneratesBodyCode, IPropertyFromNode
{
[SerializeField]

private const string kOutputSlotName = "Value";
private const string kOutputSlotName = "Out";
name = "Vector2";
name = "Vector 2";
UpdateNodeAfterDeserialization();
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector3Node.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input/Vector/Vector 3")]
[Title("Input/Basic/Vector 3")]
public class Vector3Node : AbstractMaterialNode, IGeneratesBodyCode, IPropertyFromNode
{
[SerializeField]

private const string kOutputSlotName = "Value";
private const string kOutputSlotName = "Out";
name = "Vector3";
name = "Vector 3";
UpdateNodeAfterDeserialization();
}

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector4Node.cs


namespace UnityEditor.ShaderGraph
{
[Title("Input/Vector/Vector 4")]
[Title("Input/Basic/Vector 4")]
public class Vector4Node : AbstractMaterialNode, IGeneratesBodyCode, IPropertyFromNode
{
[SerializeField]

private const string kOutputSlotName = "Value";
private const string kOutputSlotName = "Out";
name = "Vector4";
name = "Vector 4";
UpdateNodeAfterDeserialization();
}

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

正在加载...
取消
保存