浏览代码

Merge branch 'master' into node-matrix

/main
Matt Dean 7 年前
当前提交
c0c00ec0
共有 457 个文件被更改,包括 2028 次插入1500 次删除
  1. 2
      LICENSE
  2. 8
      MaterialGraphProject/Assets/LightweightAsset.asset
  3. 3
      MaterialGraphProject/Assets/NewNodes/Editor/FunctionNAddNode.cs
  4. 6
      MaterialGraphProject/Assets/NewNodes/Editor/Keep/ConvolutionFilterNode.cs
  5. 5
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/ScatterNode.cs
  6. 5
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/ToggleNode.cs
  7. 5
      MaterialGraphProject/Assets/NewNodes/Editor/Kill/UVTransform.cs
  8. 5
      MaterialGraphProject/Assets/NewNodes/Editor/SceneDepthNode.cs
  9. 5
      MaterialGraphProject/Assets/NewNodes/Editor/SceneVelocityNode.cs
  10. 11
      MaterialGraphProject/Assets/UnityShaderEditor.meta
  11. 908
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs
  12. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractShaderProperty.cs
  13. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/BitangentMaterialSlot.cs
  14. 39
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorMaterialSlot.cs
  15. 42
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorRGBMaterialSlot.cs
  16. 25
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorShaderProperty.cs
  17. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapInputMaterialSlot.cs
  18. 18
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapShaderProperty.cs
  19. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/DynamicMatrixMaterialSlot.cs
  20. 22
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/DynamicVectorMaterialSlot.cs
  21. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IShaderProperty.cs
  22. 53
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialGraphAsset.cs
  23. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialGraphAsset.cs.meta
  24. 150
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs
  25. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix2MaterialSlot.cs
  26. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix2ShaderProperty.cs
  27. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix3MaterialSlot.cs
  28. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix3ShaderProperty.cs
  29. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix4MaterialSlot.cs
  30. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix4ShaderProperty.cs
  31. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MatrixShaderProperty.cs
  32. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/NormalMaterialSlot.cs
  33. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/PositionMaterialSlot.cs
  34. 157
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/PreviewProperty.cs
  35. 13
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs
  36. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ScreenPositionMaterialSlot.cs
  37. 36
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SerializableCubemap.cs
  38. 35
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SerializableTexture.cs
  39. 49
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ShaderGraphRequirements.cs
  40. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TangentMaterialSlot.cs
  41. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Texture2DInputMaterialSlot.cs
  42. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureSamplerState.cs
  43. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureShaderProperty.cs
  44. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/UVMaterialSlot.cs
  45. 13
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector1MaterialSlot.cs
  46. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2MaterialSlot.cs
  47. 15
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2ShaderProperty.cs
  48. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3MaterialSlot.cs
  49. 16
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3ShaderProperty.cs
  50. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4MaterialSlot.cs
  51. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4ShaderProperty.cs
  52. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/VectorShaderProperty.cs
  53. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/VertexColorMaterialSlot.cs
  54. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ViewDirectionMaterialSlot.cs
  55. 94
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector1ShaderProperty.cs
  56. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IMaterialSlotHasValue.cs.meta
  57. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/IGeneratesFunction.cs
  58. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/NeededCoordinateSpace.cs
  59. 127
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightPBRSubShader.cs
  60. 65
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightUnlitSubShader.cs
  61. 287
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/AbstractMaterialNode.cs
  62. 68
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs
  63. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/HueNode.cs
  64. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Blend/BlendMode.cs
  65. 159
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Blend/BlendNode.cs
  66. 106
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Mask/ChannelMaskNode.cs
  67. 118
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalCreateNode.cs
  68. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalStrengthNode.cs
  69. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalUnpackNode.cs
  70. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Utility/ColorspaceConversion.cs
  71. 103
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs
  72. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SplitNode.cs
  73. 111
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SwizzleNode.cs
  74. 43
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/CodeFunctionNode.cs
  75. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/GeometryNode.cs
  76. 61
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/ColorNode.cs
  77. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/ConstantNode.cs
  78. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/TimeNode.cs
  79. 50
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector1Node.cs
  80. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector2Node.cs
  81. 18
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector3Node.cs
  82. 19
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/Vector4Node.cs
  83. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/BitangentVectorNode.cs
  84. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/NormalVectorNode.cs
  85. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/PositionNode.cs
  86. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ScreenPositionNode.cs
  87. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/TangentVectorNode.cs
  88. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/UVNode.cs
  89. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/VertexColorNode.cs
  90. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ViewDirectionNode.cs
  91. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix2Node.cs
  92. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix3Node.cs
  93. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/Matrix4Node.cs
  94. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/TransformationMatrixNode.cs
  95. 37
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/PropertyNode.cs
  96. 23
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/AmbientNode.cs
  97. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/CameraNode.cs
  98. 102
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/FogNode.cs
  99. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ReflectionProbeNode.cs
  100. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Texture/CubemapAssetNode.cs

2
LICENSE


Unity Companion License (“License”)
Software Copyright © 2017 Unity Technologies ApS
Software Copyright © 2018 Unity Technologies ApS
Unity Technologies ApS (“Unity”) grants to you a worldwide, non-exclusive,
no-charge, and royalty-free copyright license to reproduce, prepare derivative

8
MaterialGraphProject/Assets/LightweightAsset.asset


m_EditorClassIdentifier:
m_MaxPixelLights: 4
m_SupportsVertexLight: 0
m_SupportSoftParticles: 0
m_RequireCameraDepthTexture: 0
m_MSAA: 4
m_RenderScale: 1
m_ShadowType: 1

m_DefaultShader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_BlitShader: {fileID: 4800000, guid: c17132b1f77d20942aa75f8429c0f8bc, type: 3}
m_CopyDepthShader: {fileID: 4800000, guid: d6dae50ee9e1bfa4db75f19f99355220, type: 3}
m_DefaultMaterial: {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
m_DefaultParticleMaterial: {fileID: 2100000, guid: e823cd5b5d27c0f4b8256e7c12ee3e6d,
type: 2}
m_DefaultTerrainMaterial: {fileID: 2100000, guid: 594ea882c5a793440b60ff72d896021e,
type: 2}
m_ResourceAsset: {fileID: 11400000, guid: c8afc0a27fb8c0b4da18151c689a1082, type: 2}

3
MaterialGraphProject/Assets/NewNodes/Editor/FunctionNAddNode.cs


public void OnModified()
{
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
}
protected override string GetFunctionName()

6
MaterialGraphProject/Assets/NewNodes/Editor/Keep/ConvolutionFilterNode.cs


m_ConvolutionFilter[6].w = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
}
public float GetConvolutionWeight(int row, int col)

default: m_ConvolutionFilter[vectorIndex].w = value; break;
}
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
}
protected override string GetFunctionName()

5
MaterialGraphProject/Assets/NewNodes/Editor/Kill/ScatterNode.cs


}
m_num = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

5
MaterialGraphProject/Assets/NewNodes/Editor/Kill/ToggleNode.cs


return;
m_ToggleState = value;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
Dirty(ModificationScope.Node);
}
}

5
MaterialGraphProject/Assets/NewNodes/Editor/Kill/UVTransform.cs


return;
m_constant = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}
public UVTransform()

5
MaterialGraphProject/Assets/NewNodes/Editor/SceneDepthNode.cs


return;
m_SceneDepthMode = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

5
MaterialGraphProject/Assets/NewNodes/Editor/SceneVelocityNode.cs


return;
m_SceneVelocityMode = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

11
MaterialGraphProject/Assets/UnityShaderEditor.meta


fileFormatVersion: 2
guid: b100142c357c2d745b9707d6e2f987fd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 0b601fe23f0347ab8e4892edf2cf76d7
timeCreated: 1513757926

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


using System.Text.RegularExpressions;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Util;
public abstract class AbstractMaterialGraph : SerializableGraph, IGenerateProperties
public abstract class AbstractMaterialGraph : IGraph, ISerializationCallbackReceiver, IGenerateProperties
public IGraphObject owner { get; set; }
#region Property data
public IEnumerable<IShaderProperty> properties
{
get { return m_Properties; }
}
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializedProperties = new List<SerializationHelper.JSONSerializedElement>();

public IEnumerable<IShaderProperty> addedProperties
{
get { return m_AddedProperties; }
}
public IEnumerable<Guid> removedProperties
{
get { return m_RemovedProperties; }
}
public InspectorPreviewData previewData = new InspectorPreviewData();
List<IShaderProperty> m_MovedProperties = new List<IShaderProperty>();
public Mesh previewMesh
public IEnumerable<IShaderProperty> movedProperties
get { return previewData.mesh; }
set { previewData.mesh = value; }
get { return m_MovedProperties; }
public IEnumerable<IShaderProperty> properties
[SerializeField]
SerializableGuid m_GUID = new SerializableGuid();
public Guid guid
get { return m_Properties; }
get { return m_GUID.guid; }
public IEnumerable<IShaderProperty> addedProperties
#endregion
#region Node data
[NonSerialized]
Stack<Identifier> m_FreeNodeTempIds = new Stack<Identifier>();
[NonSerialized]
List<AbstractMaterialNode> m_Nodes = new List<AbstractMaterialNode>();
[NonSerialized]
Dictionary<Guid, INode> m_NodeDictionary = new Dictionary<Guid, INode>();
public IEnumerable<T> GetNodes<T>() where T : INode
get { return m_AddedProperties; }
return m_Nodes.Where(x => x != null).OfType<T>();
public IEnumerable<Guid> removedProperties
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableNodes = new List<SerializationHelper.JSONSerializedElement>();
[NonSerialized]
List<INode> m_AddedNodes = new List<INode>();
public IEnumerable<INode> addedNodes
get { return m_RemovedProperties; }
get { return m_AddedNodes; }
}
[NonSerialized]
List<INode> m_RemovedNodes = new List<INode>();
public IEnumerable<INode> removedNodes
{
get { return m_RemovedNodes; }
}
#endregion
#region Edge data
[NonSerialized]
List<IEdge> m_Edges = new List<IEdge>();
public IEnumerable<IEdge> edges
{
get { return m_Edges; }
}
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableEdges = new List<SerializationHelper.JSONSerializedElement>();
[NonSerialized]
Dictionary<Guid, List<IEdge>> m_NodeEdges = new Dictionary<Guid, List<IEdge>>();
[NonSerialized]
List<IEdge> m_AddedEdges = new List<IEdge>();
public IEnumerable<IEdge> addedEdges
{
get { return m_AddedEdges; }
}
[NonSerialized]
List<IEdge> m_RemovedEdges = new List<IEdge>();
public IEnumerable<IEdge> removedEdges
{
get { return m_RemovedEdges; }
}
#endregion
[SerializeField]
InspectorPreviewData m_PreviewData = new InspectorPreviewData();
public InspectorPreviewData previewData
{
get { return m_PreviewData; }
set { m_PreviewData = value; }
public override void ClearChanges()
public void ClearChanges()
base.ClearChanges();
m_AddedNodes.Clear();
m_RemovedNodes.Clear();
m_AddedEdges.Clear();
m_RemovedEdges.Clear();
m_MovedProperties.Clear();
public override void AddNode(INode node)
public virtual void AddNode(INode node)
base.AddNode(node);
AddNodeNoValidate(node);
ValidateGraph();
}
else
{

public virtual void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
void AddNodeNoValidate(INode node)
foreach (var prop in properties)
collector.AddShaderProperty(prop);
var materialNode = (AbstractMaterialNode)node;
materialNode.owner = this;
if (m_FreeNodeTempIds.Any())
{
var id = m_FreeNodeTempIds.Pop();
id.IncrementVersion();
materialNode.tempId = id;
m_Nodes[id.index] = materialNode;
}
else
{
var id = new Identifier(m_Nodes.Count);
materialNode.tempId = id;
m_Nodes.Add(materialNode);
}
m_NodeDictionary.Add(materialNode.guid, materialNode);
m_AddedNodes.Add(materialNode);
public virtual void AddShaderProperty(IShaderProperty property)
public void RemoveNode(INode node)
if (property == null)
if (!node.canDeleteNode)
RemoveNodeNoValidate(node);
ValidateGraph();
}
if (m_Properties.Contains(property))
void RemoveNodeNoValidate(INode node)
{
var materialNode = (AbstractMaterialNode)node;
if (!materialNode.canDeleteNode)
property.displayName = property.displayName.Trim();
if (m_Properties.Any(p => p.displayName == property.displayName))
{
var regex = new Regex(@"^" + Regex.Escape(property.displayName) + @" \((\d+)\)$");
var existingDuplicateNumbers = m_Properties.Select(p => regex.Match(p.displayName)).Where(m => m.Success).Select(m => int.Parse(m.Groups[1].Value)).Where(n => n > 0).ToList();
var duplicateNumber = 1;
existingDuplicateNumbers.Sort();
if (existingDuplicateNumbers.Any() && existingDuplicateNumbers.First() == 1)
{
duplicateNumber = existingDuplicateNumbers.Last() + 1;
for (var i = 1; i < existingDuplicateNumbers.Count; i++)
{
if (existingDuplicateNumbers[i - 1] != existingDuplicateNumbers[i] - 1)
{
duplicateNumber = existingDuplicateNumbers[i - 1] + 1;
break;
}
}
}
property.displayName = string.Format("{0} ({1})", property.displayName, duplicateNumber);
}
m_Properties.Add(property);
m_AddedProperties.Add(property);
m_Nodes[materialNode.tempId.index] = null;
m_FreeNodeTempIds.Push(materialNode.tempId);
m_NodeDictionary.Remove(materialNode.guid);
m_RemovedNodes.Add(materialNode);
public void RemoveShaderProperty(Guid guid)
void AddEdgeToNodeEdges(IEdge edge)
RemoveShaderPropertyNoValidate(guid);
ValidateGraph();
List<IEdge> inputEdges;
if (!m_NodeEdges.TryGetValue(edge.inputSlot.nodeGuid, out inputEdges))
m_NodeEdges[edge.inputSlot.nodeGuid] = inputEdges = new List<IEdge>();
inputEdges.Add(edge);
List<IEdge> outputEdges;
if (!m_NodeEdges.TryGetValue(edge.outputSlot.nodeGuid, out outputEdges))
m_NodeEdges[edge.outputSlot.nodeGuid] = outputEdges = new List<IEdge>();
outputEdges.Add(edge);
void RemoveShaderPropertyNoValidate(Guid guid)
IEdge ConnectNoValidate(SlotReference fromSlotRef, SlotReference toSlotRef)
var propertyNodes = GetNodes<PropertyNode>().Where(x => x.propertyGuid == guid).ToList();
var fromNode = GetNodeFromGuid(fromSlotRef.nodeGuid);
var toNode = GetNodeFromGuid(toSlotRef.nodeGuid);
foreach (var propNode in propertyNodes)
ReplacePropertyNodeWithConcreteNode(propNode);
if (fromNode == null || toNode == null)
return null;
if (m_Properties.RemoveAll(x => x.guid == guid) > 0)
m_RemovedProperties.Add(guid);
}
// if fromNode is already connected to toNode
// do now allow a connection as toNode will then
// have an edge to fromNode creating a cycle.
// if this is parsed it will lead to an infinite loop.
var dependentNodes = new List<INode>();
NodeUtils.CollectNodesNodeFeedsInto(dependentNodes, toNode);
if (dependentNodes.Contains(fromNode))
return null;
static List<IEdge> s_TempEdges = new List<IEdge>();
var fromSlot = fromNode.FindSlot<ISlot>(fromSlotRef.slotId);
var toSlot = toNode.FindSlot<ISlot>(toSlotRef.slotId);
public void ReplacePropertyNodeWithConcreteNode(PropertyNode propertyNode)
{
var property = properties.FirstOrDefault(x => x.guid == propertyNode.propertyGuid);
if (property != null)
if (fromSlot.isOutputSlot == toSlot.isOutputSlot)
return null;
var outputSlot = fromSlot.isOutputSlot ? fromSlotRef : toSlotRef;
var inputSlot = fromSlot.isInputSlot ? fromSlotRef : toSlotRef;
s_TempEdges.Clear();
GetEdges(inputSlot, s_TempEdges);
// remove any inputs that exits before adding
foreach (var edge in s_TempEdges)
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;
}
else if (property is TextureShaderProperty)
{
var createdNode = new Texture2DAssetNode();
createdNode.texture = ((TextureShaderProperty)property).value.texture;
slotId = Texture2DAssetNode.OutputSlotId;
node = createdNode;
}
else if (property is CubemapShaderProperty)
{
var createdNode = new CubemapAssetNode();
createdNode.cubemap = ((CubemapShaderProperty)property).value.cubemap;
slotId = CubemapAssetNode.OutputSlotId;
node = createdNode;
}
RemoveEdgeNoValidate(edge);
}
if (node == null)
return;
var newEdge = new Edge(outputSlot, inputSlot);
m_Edges.Add(newEdge);
m_AddedEdges.Add(newEdge);
AddEdgeToNodeEdges(newEdge);
var slot = propertyNode.FindOutputSlot<MaterialSlot>(PropertyNode.OutputSlotId);
node.drawState = propertyNode.drawState;
AddNodeNoValidate(node);
//Debug.LogFormat("Connected edge: {0} -> {1} ({2} -> {3})\n{4}", newEdge.outputSlot.nodeGuid, newEdge.inputSlot.nodeGuid, fromNode.name, toNode.name, Environment.StackTrace);
return newEdge;
}
s_TempEdges.Clear();
GetEdges(slot.slotReference, s_TempEdges);
foreach (var edge in s_TempEdges)
ConnectNoValidate(node.GetSlotReference(slotId), edge.inputSlot);
public virtual IEdge Connect(SlotReference fromSlotRef, SlotReference toSlotRef)
{
var newEdge = ConnectNoValidate(fromSlotRef, toSlotRef);
ValidateGraph();
return newEdge;
}
RemoveNodeNoValidate(propertyNode);
}
public virtual void RemoveEdge(IEdge e)
{
RemoveEdgeNoValidate(e);
ValidateGraph();
public override void ValidateGraph()
public void RemoveElements(IEnumerable<INode> nodes, IEnumerable<IEdge> edges)
var propertyNodes = GetNodes<PropertyNode>().Where(n => !m_Properties.Any(p => p.guid == n.propertyGuid)).ToArray();
foreach (var pNode in propertyNodes)
ReplacePropertyNodeWithConcreteNode(pNode);
base.ValidateGraph();
foreach (var edge in edges.ToArray())
RemoveEdgeNoValidate(edge);
foreach (var serializableNode in nodes.ToArray())
RemoveNodeNoValidate(serializableNode);
ValidateGraph();
public override Dictionary<SerializationHelper.TypeSerializationInfo, SerializationHelper.TypeSerializationInfo> GetLegacyTypeRemapping()
protected void RemoveEdgeNoValidate(IEdge e)
var result = base.GetLegacyTypeRemapping();
var viewNode = new SerializationHelper.TypeSerializationInfo
{
fullName = "UnityEngine.MaterialGraph.ViewDirectionNode"
};
result[viewNode] = SerializationHelper.GetTypeSerializableAsString(typeof(ViewDirectionNode));
e = m_Edges.FirstOrDefault(x => x.Equals(e));
if (e == null)
throw new ArgumentException("Trying to remove an edge that does not exist.", "e");
m_Edges.Remove(e);
var normalNode = new SerializationHelper.TypeSerializationInfo
{
fullName = "UnityEngine.MaterialGraph.NormalNode"
};
result[normalNode] = SerializationHelper.GetTypeSerializableAsString(typeof(NormalVectorNode));
List<IEdge> inputNodeEdges;
if (m_NodeEdges.TryGetValue(e.inputSlot.nodeGuid, out inputNodeEdges))
inputNodeEdges.Remove(e);
var worldPosNode = new SerializationHelper.TypeSerializationInfo
{
fullName = "UnityEngine.MaterialGraph.WorldPosNode"
};
result[worldPosNode] = SerializationHelper.GetTypeSerializableAsString(typeof(PositionNode));
List<IEdge> outputNodeEdges;
if (m_NodeEdges.TryGetValue(e.outputSlot.nodeGuid, out outputNodeEdges))
outputNodeEdges.Remove(e);
return result;
m_RemovedEdges.Add(e);
public override void ReplaceWith(IGraph other)
public INode GetNodeFromGuid(Guid guid)
var otherMG = other as AbstractMaterialGraph;
if (otherMG != null)
{
using (var removedPropertiesPooledObject = ListPool<Guid>.GetDisposable())
{
var removedPropertyGuids = removedPropertiesPooledObject.value;
foreach (var property in m_Properties)
removedPropertyGuids.Add(property.guid);
foreach (var propertyGuid in removedPropertyGuids)
RemoveShaderPropertyNoValidate(propertyGuid);
}
foreach (var otherProperty in otherMG.properties)
{
if (!properties.Any(p => p.guid == otherProperty.guid))
AddShaderProperty(otherProperty);
}
}
base.ReplaceWith(other);
INode node;
m_NodeDictionary.TryGetValue(guid, out node);
return node;
public override void OnBeforeSerialize()
public INode GetNodeFromTempId(Identifier tempId)
base.OnBeforeSerialize();
m_SerializedProperties = SerializationHelper.Serialize<IShaderProperty>(m_Properties);
var node = m_Nodes[tempId.index];
if (node == null)
throw new Exception("Index does not contain a node.");
if (node.tempId.version != tempId.version)
throw new Exception("Trying to retrieve a node that was removed from the graph.");
return node;
public override void OnAfterDeserialize()
public bool ContainsNodeGuid(Guid guid)
// have to deserialize 'globals' before nodes
m_Properties = SerializationHelper.Deserialize<IShaderProperty>(m_SerializedProperties, null);
base.OnAfterDeserialize();
return m_NodeDictionary.ContainsKey(guid);
internal static ShaderGraphRequirements GetRequirements(List<INode> nodes)
public T GetNodeFromGuid<T>(Guid guid) where T : INode
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal());
NeededCoordinateSpace requiresBitangent = nodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresBitangent());
NeededCoordinateSpace requiresTangent = nodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent());
NeededCoordinateSpace requiresViewDir = nodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresViewDirection());
NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition());
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
var node = GetNodeFromGuid(guid);
if (node is T)
return (T)node;
return default(T);
}
var meshUV = new List<UVChannel>();
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
public void GetEdges(SlotReference s, List<IEdge> foundEdges)
{
var node = GetNodeFromGuid(s.nodeGuid);
if (node == null)
var channel = (UVChannel)uvIndex;
if (nodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
meshUV.Add(channel);
Debug.LogWarning("Node does not exist");
return;
ISlot slot = node.FindSlot<ISlot>(s.slotId);
// if anything needs tangentspace we have make
// sure to have our othonormal basis!
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition
| requiresTangent | requiresViewDir | requiresPosition
| requiresNormal;
List<IEdge> candidateEdges;
if (!m_NodeEdges.TryGetValue(s.nodeGuid, out candidateEdges))
return;
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
if (needsTangentSpace)
foreach (var edge in candidateEdges)
requiresBitangent |= NeededCoordinateSpace.Object;
requiresNormal |= NeededCoordinateSpace.Object;
requiresTangent |= NeededCoordinateSpace.Object;
var cs = slot.isInputSlot ? edge.inputSlot : edge.outputSlot;
if (cs.nodeGuid == s.nodeGuid && cs.slotId == s.slotId)
foundEdges.Add(edge);
var reqs = new ShaderGraphRequirements()
{
requiresNormal = requiresNormal,
requiresBitangent = requiresBitangent,
requiresTangent = requiresTangent,
requiresViewDir = requiresViewDir,
requiresPosition = requiresPosition,
requiresScreenPosition = requiresScreenPosition,
requiresVertexColor = requiresVertexColor,
requiresMeshUVs = meshUV
};
}
return reqs;
public virtual void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
{
foreach (var prop in properties)
collector.AddShaderProperty(prop);
public string GetPreviewShader(AbstractMaterialNode node, out PreviewMode previewMode)
public void AddShaderProperty(IShaderProperty property)
List<PropertyCollector.TextureInfo> configuredTextures;
FloatShaderProperty outputIdProperty;
return GetShader(node, GenerationMode.Preview, string.Format("hidden/preview/{0}", node.GetVariableNameForNode()), out configuredTextures, out previewMode, out outputIdProperty);
if (property == null)
return;
if (m_Properties.Contains(property))
return;
property.displayName = property.displayName.Trim();
if (m_Properties.Any(p => p.displayName == property.displayName))
{
var regex = new Regex(@"^" + Regex.Escape(property.displayName) + @" \((\d+)\)$");
var existingDuplicateNumbers = m_Properties.Select(p => regex.Match(p.displayName)).Where(m => m.Success).Select(m => int.Parse(m.Groups[1].Value)).Where(n => n > 0).ToList();
var duplicateNumber = 1;
existingDuplicateNumbers.Sort();
if (existingDuplicateNumbers.Any() && existingDuplicateNumbers.First() == 1)
{
duplicateNumber = existingDuplicateNumbers.Last() + 1;
for (var i = 1; i < existingDuplicateNumbers.Count; i++)
{
if (existingDuplicateNumbers[i - 1] != existingDuplicateNumbers[i] - 1)
{
duplicateNumber = existingDuplicateNumbers[i - 1] + 1;
break;
}
}
}
property.displayName = string.Format("{0} ({1})", property.displayName, duplicateNumber);
}
m_Properties.Add(property);
m_AddedProperties.Add(property);
public string GetUberPreviewShader(Dictionary<Guid, int> ids, out FloatShaderProperty outputIdProperty)
public void RemoveShaderProperty(Guid guid)
List<PropertyCollector.TextureInfo> configuredTextures;
PreviewMode previewMode;
return GetShader(null, GenerationMode.Preview, "hidden/preview", out configuredTextures, out previewMode, out outputIdProperty, ids);
var propertyNodes = GetNodes<PropertyNode>().Where(x => x.propertyGuid == guid).ToList();
foreach (var propNode in propertyNodes)
ReplacePropertyNodeWithConcreteNodeNoValidate(propNode);
RemoveShaderPropertyNoValidate(guid);
ValidateGraph();
internal static void GenerateSurfaceDescriptionStruct(ShaderGenerator surfaceDescriptionStruct, List<MaterialSlot> slots, bool isMaster)
public void MoveShaderProperty(IShaderProperty property, int newIndex)
surfaceDescriptionStruct.AddShaderChunk("struct SurfaceDescription{", false);
surfaceDescriptionStruct.Indent();
if (isMaster)
{
foreach (var slot in slots)
surfaceDescriptionStruct.AddShaderChunk(string.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), AbstractMaterialNode.GetHLSLSafeName(slot.shaderOutputName)), false);
surfaceDescriptionStruct.Deindent();
}
if (newIndex > m_Properties.Count || newIndex < 0)
throw new ArgumentException("New index is not within properties list.");
var currentIndex = m_Properties.IndexOf(property);
if (currentIndex == -1)
throw new ArgumentException("Property is not in graph.");
if (newIndex == currentIndex)
return;
m_Properties.RemoveAt(currentIndex);
if (newIndex > currentIndex)
newIndex--;
var isLast = newIndex == m_Properties.Count;
if (isLast)
m_Properties.Add(property);
{
surfaceDescriptionStruct.AddShaderChunk("float4 PreviewOutput;", false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
m_Properties.Insert(newIndex, property);
if (!m_MovedProperties.Contains(property))
m_MovedProperties.Add(property);
internal static void GenerateApplicationVertexInputs(ShaderGraphRequirements graphRequiements, ShaderGenerator vertexInputs, int vertexInputStartIndex, int maxVertexInputs)
public int GetShaderPropertyIndex(IShaderProperty property)
int vertexInputIndex = vertexInputStartIndex;
vertexInputs.AddShaderChunk("struct GraphVertexInput", false);
vertexInputs.AddShaderChunk("{", false);
vertexInputs.Indent();
vertexInputs.AddShaderChunk("float4 vertex : POSITION;", false);
vertexInputs.AddShaderChunk("float3 normal : NORMAL;", false);
vertexInputs.AddShaderChunk("float4 tangent : TANGENT;", false);
return m_Properties.IndexOf(property);
}
if (graphRequiements.requiresVertexColor)
void RemoveShaderPropertyNoValidate(Guid guid)
{
if (m_Properties.RemoveAll(x => x.guid == guid) > 0)
vertexInputs.AddShaderChunk("float4 color : COLOR;", false);
m_RemovedProperties.Add(guid);
m_AddedProperties.RemoveAll(x => x.guid == guid);
m_MovedProperties.RemoveAll(x => x.guid == guid);
foreach (var channel in graphRequiements.requiresMeshUVs.Distinct())
{
vertexInputs.AddShaderChunk(string.Format("float4 texcoord{0} : TEXCOORD{1};", ((int)channel).ToString(), vertexInputIndex.ToString()), false);
vertexInputIndex++;
}
}
static List<IEdge> s_TempEdges = new List<IEdge>();
vertexInputs.AddShaderChunk("UNITY_VERTEX_INPUT_INSTANCE_ID", false);
vertexInputs.Deindent();
vertexInputs.AddShaderChunk("};", false);
public void ReplacePropertyNodeWithConcreteNode(PropertyNode propertyNode)
{
ReplacePropertyNodeWithConcreteNodeNoValidate(propertyNode);
ValidateGraph();
internal static void GenerateSurfaceDescription(
List<INode> activeNodeList,
AbstractMaterialNode masterNode,
AbstractMaterialGraph graph,
ShaderGenerator surfaceDescriptionFunction,
ShaderGenerator shaderFunctionVisitor,
PropertyCollector shaderProperties,
ShaderGraphRequirements requirements,
GenerationMode mode,
string functionName = "PopulateSurfaceData",
string surfaceDescriptionName = "SurfaceDescription",
FloatShaderProperty outputIdProperty = null,
Dictionary<Guid, int> ids = null,
IEnumerable<MaterialSlot> slots = null)
void ReplacePropertyNodeWithConcreteNodeNoValidate(PropertyNode propertyNode)
if (graph == null)
var property = properties.FirstOrDefault(x => x.guid == propertyNode.propertyGuid);
if (property == null)
surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} {1}(SurfaceInputs IN) {{", surfaceDescriptionName, functionName), false);
surfaceDescriptionFunction.Indent();
surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} surface = ({0})0;", surfaceDescriptionName), false);
var node = property.ToConcreteNode();
if (!(node is AbstractMaterialNode))
return;
foreach (CoordinateSpace space in Enum.GetValues(typeof(CoordinateSpace)))
{
var neededCoordinateSpace = space.ToNeededCoordinateSpace();
if ((requirements.requiresNormal & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Normal)), false);
if ((requirements.requiresTangent & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Tangent)), false);
if ((requirements.requiresBitangent & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.BiTangent)), false);
if ((requirements.requiresViewDir & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.ViewDirection)), false);
if ((requirements.requiresPosition & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Position)), false);
}
var slot = propertyNode.FindOutputSlot<MaterialSlot>(PropertyNode.OutputSlotId);
var newSlot = node.GetOutputSlots<MaterialSlot>().FirstOrDefault(s => s.valueType == slot.valueType);
if (newSlot == null)
return;
node.drawState = propertyNode.drawState;
AddNodeNoValidate(node);
if (requirements.requiresScreenPosition)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
if (requirements.requiresVertexColor)
surfaceDescriptionFunction.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
foreach (var edge in this.GetEdges(slot.slotReference))
ConnectNoValidate(newSlot.slotReference, edge.inputSlot);
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceDescriptionFunction.AddShaderChunk(string.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
RemoveNodeNoValidate(propertyNode);
}
graph.CollectShaderProperties(shaderProperties, mode);
public void ValidateGraph()
{
var propertyNodes = GetNodes<PropertyNode>().Where(n => !m_Properties.Any(p => p.guid == n.propertyGuid)).ToArray();
foreach (var pNode in propertyNodes)
ReplacePropertyNodeWithConcreteNodeNoValidate(pNode);
var currentId = -1;
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
//First validate edges, remove any
//orphans. This can happen if a user
//manually modifies serialized data
//of if they delete a node in the inspector
//debug view.
foreach (var edge in edges.ToArray())
if (activeNode is IGeneratesFunction)
(activeNode as IGeneratesFunction).GenerateNodeFunction(shaderFunctionVisitor, mode);
if (activeNode is IGeneratesBodyCode)
(activeNode as IGeneratesBodyCode).GenerateNodeCode(surfaceDescriptionFunction, mode);
if (masterNode == null && activeNode.hasPreview)
{
var outputSlot = activeNode.GetOutputSlots<MaterialSlot>().FirstOrDefault();
if (outputSlot != null)
{
currentId++;
ids[activeNode.guid] = currentId;
surfaceDescriptionFunction.AddShaderChunk(string.Format("if ({0} == {1}) {{ surface.PreviewOutput = {2}; return surface; }}", outputIdProperty.referenceName, currentId, ShaderGenerator.AdaptNodeOutputForPreview(activeNode, outputSlot.id, activeNode.GetVariableNameForSlot(outputSlot.id))), false);
}
}
activeNode.CollectShaderProperties(shaderProperties, mode);
}
var outputNode = GetNodeFromGuid(edge.outputSlot.nodeGuid);
var inputNode = GetNodeFromGuid(edge.inputSlot.nodeGuid);
if (masterNode != null)
{
if (masterNode is IMasterNode)
MaterialSlot outputSlot = null;
MaterialSlot inputSlot = null;
if (outputNode != null && inputNode != null)
var usedSlots = slots ?? masterNode.GetInputSlots<MaterialSlot>();
foreach (var input in usedSlots)
{
var foundEdges = graph.GetEdges(input.slotReference).ToArray();
if (foundEdges.Any())
{
var outputRef = foundEdges[0].outputSlot;
var fromNode = graph.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(input.shaderOutputName), fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
}
else
{
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode)), true);
}
}
outputSlot = outputNode.FindOutputSlot<MaterialSlot>(edge.outputSlot.slotId);
inputSlot = inputNode.FindInputSlot<MaterialSlot>(edge.inputSlot.slotId);
else if (masterNode.hasPreview)
if (outputNode == null
|| inputNode == null
|| outputSlot == null
|| inputSlot == null
|| !outputSlot.IsCompatibleWith(inputSlot))
foreach (var slot in masterNode.GetOutputSlots<MaterialSlot>())
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(slot.shaderOutputName), masterNode.GetVariableNameForSlot(slot.id)), true);
//orphaned edge
RemoveEdgeNoValidate(edge);
surfaceDescriptionFunction.AddShaderChunk("return surface;", false);
surfaceDescriptionFunction.Deindent();
surfaceDescriptionFunction.AddShaderChunk("}", false);
}
foreach (var node in GetNodes<INode>())
node.ValidateNode();
static void Visit(List<INode> outputList, Dictionary<Guid, INode> unmarkedNodes, INode node)
{
if (!unmarkedNodes.ContainsKey(node.guid))
return;
foreach (var slot in node.GetInputSlots<ISlot>())
foreach (var edge in m_AddedEdges.ToList())
foreach (var edge in node.owner.GetEdges(slot.slotReference))
if (!ContainsNodeGuid(edge.outputSlot.nodeGuid) || !ContainsNodeGuid(edge.inputSlot.nodeGuid))
var inputNode = node.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid);
Visit(outputList, unmarkedNodes, inputNode);
Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}\n{2}", edge.outputSlot.nodeGuid, edge.inputSlot.nodeGuid, Environment.StackTrace);
m_AddedEdges.Remove(edge);
unmarkedNodes.Remove(node.guid);
outputList.Add(node);
public string GetShader(AbstractMaterialNode node, GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures, out PreviewMode previewMode, out FloatShaderProperty outputIdProperty, Dictionary<Guid, int> ids = null)
public void ReplaceWith(IGraph other)
bool isUber = node == null;
var vertexInputs = new ShaderGenerator();
var vertexShader = new ShaderGenerator();
var surfaceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();
var otherMg = other as AbstractMaterialGraph;
if (otherMg == null)
throw new ArgumentException("Can only replace with another AbstractMaterialGraph", "other");
var activeNodeList = ListPool<INode>.Get();
if (isUber)
using (var removedPropertiesPooledObject = ListPool<Guid>.GetDisposable())
var unmarkedNodes = GetNodes<INode>().Where(x => !(x is IMasterNode)).ToDictionary(x => x.guid);
while (unmarkedNodes.Any())
{
var unmarkedNode = unmarkedNodes.FirstOrDefault();
Visit(activeNodeList, unmarkedNodes, unmarkedNode.Value);
}
var removedPropertyGuids = removedPropertiesPooledObject.value;
foreach (var property in m_Properties)
removedPropertyGuids.Add(property.guid);
foreach (var propertyGuid in removedPropertyGuids)
RemoveShaderPropertyNoValidate(propertyGuid);
else
foreach (var otherProperty in otherMg.properties)
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
if (!properties.Any(p => p.guid == otherProperty.guid))
AddShaderProperty(otherProperty);
var requirements = GetRequirements(activeNodeList);
GenerateApplicationVertexInputs(requirements, vertexInputs, 0, 8);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, InterpolatorType.Normal, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, InterpolatorType.Tangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, InterpolatorType.BiTangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresViewDir, InterpolatorType.ViewDirection, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, InterpolatorType.Position, surfaceInputs);
other.ValidateGraph();
ValidateGraph();
if (requirements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.VertexColor), false);
if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);
previewMode = PreviewMode.Preview3D;
if (!isUber)
// Current tactic is to remove all nodes and edges and then re-add them, such that depending systems
// will re-initialize with new references.
using (var pooledList = ListPool<IEdge>.GetDisposable())
foreach (var pNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (pNode.previewMode == PreviewMode.Preview3D)
{
previewMode = PreviewMode.Preview3D;
break;
}
}
var removedNodeEdges = pooledList.value;
removedNodeEdges.AddRange(m_Edges);
foreach (var edge in removedNodeEdges)
RemoveEdgeNoValidate(edge);
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("half4 {0};", channel.GetUVName()), false);
surfaceInputs.Deindent();
surfaceInputs.AddShaderChunk("};", false);
vertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false);
vertexShader.Indent();
vertexShader.AddShaderChunk("return v;", false);
vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
var slots = new List<MaterialSlot>();
foreach (var activeNode in isUber ? activeNodeList.Where(n => ((AbstractMaterialNode)n).hasPreview) : ((INode)node).ToEnumerable())
using (var removedNodesPooledObject = ListPool<Guid>.GetDisposable())
if (activeNode is IMasterNode)
slots.AddRange(activeNode.GetInputSlots<MaterialSlot>());
else
slots.AddRange(activeNode.GetOutputSlots<MaterialSlot>());
var removedNodeGuids = removedNodesPooledObject.value;
removedNodeGuids.AddRange(m_Nodes.Where(n => n != null).Select(n => n.guid));
foreach (var nodeGuid in removedNodeGuids)
RemoveNodeNoValidate(m_NodeDictionary[nodeGuid]);
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, !isUber);
var shaderProperties = new PropertyCollector();
outputIdProperty = new FloatShaderProperty
{
displayName = "OutputId",
generatePropertyBlock = false,
value = -1
};
if (isUber)
shaderProperties.AddShaderProperty(outputIdProperty);
ValidateGraph();
foreach (var node in other.GetNodes<INode>())
AddNodeNoValidate(node);
GenerateSurfaceDescription(
activeNodeList,
node,
this,
surfaceDescriptionFunction,
shaderFunctionVisitor,
shaderProperties,
requirements,
mode,
outputIdProperty: outputIdProperty,
ids: ids);
foreach (var edge in other.edges)
ConnectNoValidate(edge.outputSlot, edge.inputSlot);
var finalShader = new ShaderGenerator();
finalShader.AddShaderChunk(string.Format(@"Shader ""{0}""", name), false);
finalShader.AddShaderChunk("{", false);
finalShader.Indent();
ValidateGraph();
}
finalShader.AddShaderChunk("Properties", false);
finalShader.AddShaderChunk("{", false);
finalShader.Indent();
finalShader.AddShaderChunk(shaderProperties.GetPropertiesBlock(2), false);
finalShader.Deindent();
finalShader.AddShaderChunk("}", false);
public void OnBeforeSerialize()
{
m_SerializableNodes = SerializationHelper.Serialize(GetNodes<INode>());
m_SerializableEdges = SerializationHelper.Serialize<IEdge>(m_Edges);
m_SerializedProperties = SerializationHelper.Serialize<IShaderProperty>(m_Properties);
}
finalShader.AddShaderChunk("CGINCLUDE", false);
finalShader.AddShaderChunk("#include \"UnityCG.cginc\"", false);
finalShader.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
finalShader.AddShaderChunk(vertexInputs.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false);
finalShader.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
finalShader.AddShaderChunk(vertexShader.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);
finalShader.AddShaderChunk("ENDCG", false);
public virtual void OnAfterDeserialize()
{
// have to deserialize 'globals' before nodes
m_Properties = SerializationHelper.Deserialize<IShaderProperty>(m_SerializedProperties, GraphUtil.GetLegacyTypeRemapping());
var nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes, GraphUtil.GetLegacyTypeRemapping());
m_Nodes = new List<AbstractMaterialNode>(nodes.Count);
m_NodeDictionary = new Dictionary<Guid, INode>(nodes.Count);
foreach (var node in nodes.OfType<AbstractMaterialNode>())
{
node.owner = this;
node.UpdateNodeAfterDeserialization();
node.tempId = new Identifier(m_Nodes.Count);
m_Nodes.Add(node);
m_NodeDictionary.Add(node.guid, node);
}
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(node, requirements), false);
m_SerializableNodes = null;
ListPool<INode>.Release(activeNodeList);
m_Edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges, GraphUtil.GetLegacyTypeRemapping());
m_SerializableEdges = null;
foreach (var edge in m_Edges)
AddEdgeToNodeEdges(edge);
}
finalShader.Deindent();
finalShader.AddShaderChunk("}", false);
configuredTextures = shaderProperties.GetConfiguredTexutres();
return finalShader.GetShaderString(0);
public void OnEnable()
{
foreach (var node in GetNodes<INode>().OfType<IOnAssetEnabled>())
{
node.OnEnable();
}
[Serializable]
public Mesh mesh;
public SerializableMesh serializedMesh = new SerializableMesh();
[NonSerialized]
public float scale = 1f;
}
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractShaderProperty.cs


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

public abstract Vector4 defaultValue { get; }
public abstract string GetPropertyBlockString();
public abstract string GetPropertyDeclarationString();
public abstract string GetPropertyDeclarationString(string delimiter = ";");
public virtual string GetInlinePropertyDeclarationString()
public virtual string GetPropertyAsArgumentString()
return GetPropertyDeclarationString();
return GetPropertyDeclarationString(string.Empty);
public abstract INode ToConcreteNode();
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/BitangentMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.BiTangent);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.BiTangent));
}
public NeededCoordinateSpace RequiresBitangent()

39
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorMaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine;

public override VisualElement InstantiateControl()
{
return new ColorRGBASlotControlView(this);
}
protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
return string.Format("IsGammaSpace() ? {0}4({1}, {2}, {3}, {4}) : {0}4 (SRGBToLinear({0}3({1}, {2}, {3})), {4})"
, precision
, value.x
, value.y
, value.z
, value.w);
}
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
{
if (!generationMode.IsPreview())
return;
var matOwner = owner as AbstractMaterialNode;
if (matOwner == null)
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
var property = new ColorShaderProperty()
{
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
generatePropertyBlock = false,
value = value
};
properties.AddShaderProperty(property);
}
public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty(PropertyType.Color)
{
name = name,
colorValue = new Color(value.x, value.x, value.z, value.w),
};
return pp;
}
}
}

42
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorRGBMaterialSlot.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Slots;
using UnityEngine;

string displayName,
string shaderOutputName,
SlotType slotType,
Vector4 value,
Color value,
: base(slotId, displayName, shaderOutputName, slotType, value, shaderStage, hidden)
: base(slotId, displayName, shaderOutputName, slotType, (Vector4)value, shaderStage, hidden)
{
}

}
protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
return string.Format("IsGammaSpace() ? {0}3({1}, {2}, {3}) : SRGBToLinear({0}3({1}, {2}, {3}))"
, precision
, value.x
, value.y
, value.z);
}
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
{
if (!generationMode.IsPreview())
return;
var matOwner = owner as AbstractMaterialNode;
if (matOwner == null)
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
var property = new ColorShaderProperty()
{
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
generatePropertyBlock = false,
value = new Color(value.x, value.y, value.z)
};
properties.AddShaderProperty(property);
}
public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty(PropertyType.Color)
{
name = name,
colorValue = new Color(value.x, value.y, value.z, 1),
};
return pp;
}
}
}

25
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorShaderProperty.cs


using System;
using System.Text;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

{
[SerializeField]
private bool m_HDR;
private ColorMode m_ColorMode;
public bool HDR
public ColorMode colorMode
get { return m_HDR; }
get { return m_ColorMode; }
if (m_HDR == value)
if (m_ColorMode == value)
m_HDR = value;
m_ColorMode = value;
}
}

return string.Empty;
var result = new StringBuilder();
if (HDR)
if (colorMode == ColorMode.HDR)
result.Append("[HDR]");
result.Append(referenceName);
result.Append("(\"");

return result.ToString();
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return "float4 " + referenceName + ";";
return string.Format("float4 {0}{1}", referenceName, delimiter);
return new PreviewProperty
return new PreviewProperty(PropertyType.Color)
propType = PropertyType.Color,
}
public override INode ToConcreteNode()
{
return new ColorNode { color = new ColorNode.Color(value, colorMode) };
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapInputMaterialSlot.cs


public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Cubemap)
propType = PropertyType.Cubemap,
cubemapValue = cubemap
};
return pp;

18
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapShaderProperty.cs


using System;
using System.Text;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

result.Append("\", CUBE) = \"\" {}");
return result.ToString();
}
public override string GetPropertyDeclarationString(string delimiter = ";")
{
return string.Format("TEXTURECUBE({0}){1} SAMPLER(sampler{0}){1}", referenceName, delimiter);
}
public override string GetPropertyDeclarationString()
public override string GetPropertyAsArgumentString()
return "samplerCUBE " + referenceName + ";";
return string.Format("TEXTURECUBE_ARGS({0}, sampler{0})", referenceName);
return new PreviewProperty()
return new PreviewProperty(PropertyType.Cubemap)
propType = PropertyType.Cubemap,
}
public override INode ToConcreteNode()
{
return new CubemapAssetNode { cubemap = value.cubemap };
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/DynamicMatrixMaterialSlot.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class DynamicMatrixMaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Matrix4x4>
public class DynamicMatrixMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Matrix4x4>
{
[SerializeField]
private Matrix4x4 m_Value;

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


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class DynamicVectorMaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Vector4>
public class DynamicVectorMaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4>
{
[SerializeField]
private Vector4 m_Value;

public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
{
name = name,
propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType),
vector4Value = new Vector4(value.x, value.y, value.z, value.w),
floatValue = value.x,
colorValue = new Vector4(value.x, value.x, value.z, value.w),
};
var propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType);
var pp = new PreviewProperty(propType) { name = name };
if (propType == PropertyType.Vector1)
pp.floatValue = value.x;
else
pp.vector4Value = new Vector4(value.x, value.y, value.z, value.w);
var channelCount = (int)SlotValueHelper.GetChannelCount(concreteValueType);
var values = value.x.ToString();
var channelCount = SlotValueHelper.GetChannelCount(concreteValueType);
string values = NodeUtils.FloatToShaderValue(value.x);
if (channelCount == 1)
return values;
for (var i = 1; i < channelCount; i++)

property = new Vector2ShaderProperty();
break;
case ConcreteSlotValueType.Vector1:
property = new FloatShaderProperty();
property = new Vector1ShaderProperty();
break;
default:
throw new ArgumentOutOfRangeException();

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IShaderProperty.cs


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

string overrideReferenceName { get; set; }
string GetPropertyBlockString();
string GetPropertyDeclarationString();
string GetInlinePropertyDeclarationString();
string GetPropertyDeclarationString(string delimiter = ";");
string GetPropertyAsArgumentString();
INode ToConcreteNode();
}
}

53
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialGraphAsset.cs


using System;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEditor.Graphing;
public class MaterialGraphAsset
static class MaterialGraphAsset
var hasErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic);
var result = hasErrorsCall.Invoke(null, new object[] { shader });
return (int)result != 0;
var errors = GetShaderErrors(shader);
return errors.Any(x => x.warning == 0);
}
public struct ShaderError
{
public string message;
public string messageDetails;
public string platform;
public string file;
public int line;
public int warning;
}
static MethodInfo s_GetErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrors", BindingFlags.Static | BindingFlags.NonPublic);
static Type s_ShaderErrorType = typeof(ShaderUtil).Assembly.GetType("UnityEditor.ShaderError");
static FieldInfo s_ShaderErrorMessageField = s_ShaderErrorType.GetField("message", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorMessageDetailsField = s_ShaderErrorType.GetField("messageDetails", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorPlatformField = s_ShaderErrorType.GetField("platform", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorFileField = s_ShaderErrorType.GetField("file", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorLineField = s_ShaderErrorType.GetField("line", BindingFlags.Instance | BindingFlags.Public);
static FieldInfo s_ShaderErrorWarningField = s_ShaderErrorType.GetField("warning", BindingFlags.Instance | BindingFlags.Public);
public static ShaderError[] GetShaderErrors(Shader shader)
{
var invoke = s_GetErrorsCall.Invoke(null, new object[] { shader });
var objects = (Array)invoke;
var errors = new ShaderError[objects.Length];
for (var i = 0; i < objects.Length; i++)
{
var obj = objects.GetValue(i);
errors[i] = new ShaderError
{
message = (string)s_ShaderErrorMessageField.GetValue(obj),
messageDetails = (string)s_ShaderErrorMessageDetailsField.GetValue(obj),
platform = (string)s_ShaderErrorPlatformField.GetValue(obj),
file = (string)s_ShaderErrorFileField.GetValue(obj),
line = (int)s_ShaderErrorLineField.GetValue(obj),
warning = (int)s_ShaderErrorWarningField.GetValue(obj),
};
}
return errors;
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialGraphAsset.cs.meta


fileFormatVersion: 2
guid: 562bd27a5e73fc64d80a1d9d936ffbd5
timeCreated: 1464601236
licenseType: Pro
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0

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


using System;
using System.Linq;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("com.unity.shadergraph.EditorTests")]
public abstract class MaterialSlot : SerializableSlot
public abstract class MaterialSlot : ISlot
const string k_NotInit = "Not Initilaized";
[SerializeField]
int m_Id;
[SerializeField]
string m_DisplayName = k_NotInit;
[SerializeField]
SlotType m_SlotType = SlotType.Input;
[SerializeField]
int m_Priority = int.MaxValue;
[SerializeField]
bool m_Hidden;
[SerializeField]
string m_ShaderOutputName;

private bool m_HasError;
bool m_HasError;
: base(slotId, displayName, slotType, hidden)
m_Id = slotId;
m_DisplayName = displayName;
m_SlotType = slotType;
m_Hidden = hidden;
m_ShaderOutputName = shaderOutputName;
this.shaderStage = shaderStage;
}
protected MaterialSlot(int slotId, string displayName, string shaderOutputName, SlotType slotType, int priority, ShaderStage shaderStage = ShaderStage.Dynamic, bool hidden = false)
{
m_Id = slotId;
m_DisplayName = displayName;
m_SlotType = slotType;
m_Priority = priority;
m_Hidden = hidden;
m_ShaderOutputName = shaderOutputName;
this.shaderStage = shaderStage;
}

return "(3)";
case ConcreteSlotValueType.Vector4:
return "(4)";
case ConcreteSlotValueType.Boolean:
return "(B)";
case ConcreteSlotValueType.Matrix2:
return "(2x2)";
case ConcreteSlotValueType.Matrix3:

}
}
public override string displayName
public virtual string displayName
get { return base.displayName + ConcreteSlotValueTypeAsString(concreteValueType); }
set { base.displayName = value; }
get { return m_DisplayName + ConcreteSlotValueTypeAsString(concreteValueType); }
set { m_DisplayName = value; }
return base.displayName;
return m_DisplayName;
}
public static MaterialSlot CreateMaterialSlot(SlotValueType type, int slotId, string displayName, string shaderOutputName, SlotType slotType, Vector4 defaultValue, ShaderStage shaderStage = ShaderStage.Dynamic, bool hidden = false)

return new Vector2MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue, shaderStage, hidden);
case SlotValueType.Vector1:
return new Vector1MaterialSlot(slotId, displayName, shaderOutputName, slotType, defaultValue.x, shaderStage, hidden);
case SlotValueType.Boolean:
return new BooleanMaterialSlot(slotId, displayName, shaderOutputName, slotType, false, shaderStage, hidden);
public SlotReference slotReference
{
get { return new SlotReference(owner.guid, m_Id); }
}
public INode owner { get; set; }
public bool hidden
{
get { return m_Hidden; }
set { m_Hidden = value; }
}
public int id
{
get { return m_Id; }
}
public int priority
{
get { return m_Priority; }
set { m_Priority = value; }
}
public bool isInputSlot
{
get { return m_SlotType == SlotType.Input; }
}
public bool isOutputSlot
{
get { return m_SlotType == SlotType.Output; }
}
public SlotType slotType
{
get { return m_SlotType; }
}
public bool isConnected
{
get
{
// node and graph respectivly
if (owner == null || owner.owner == null)
return false;
var graph = owner.owner;
var edges = graph.GetEdges(slotReference);
return edges.Any();
}
}
public abstract SlotValueType valueType { get; }
public abstract ConcreteSlotValueType concreteValueType { get; }

return inputType == SlotValueType.Cubemap;
case SlotValueType.Dynamic:
case SlotValueType.Vector4:
return inputType == SlotValueType.Vector4
|| inputType == SlotValueType.Vector3
|| inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
return inputType == SlotValueType.Vector3
|| inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
return inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
case SlotValueType.Vector1:
return inputType == SlotValueType.Vector4
|| inputType == SlotValueType.Vector3

case SlotValueType.Boolean:
return inputType == SlotValueType.Boolean;
}
return false;
}

return PropertyType.Texture;
case ConcreteSlotValueType.Cubemap:
return PropertyType.Cubemap;
case ConcreteSlotValueType.Boolean:
return PropertyType.Boolean;
return PropertyType.Float;
return PropertyType.Vector1;
case ConcreteSlotValueType.Vector2:
return PropertyType.Vector2;
case ConcreteSlotValueType.Vector3:

}
public abstract void CopyValuesFrom(MaterialSlot foundSlot);
bool Equals(MaterialSlot other)
{
return m_Id == other.m_Id && owner.guid.Equals(other.owner.guid);
}
public bool Equals(ISlot other)
{
return Equals(other as object);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((MaterialSlot)obj);
}
public override int GetHashCode()
{
unchecked
{
return (m_Id * 397) ^ (owner != null ? owner.GetHashCode() : 0);
}
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix2MaterialSlot.cs


public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Matrix2)
propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType),
vector4Value = new Vector4(value.GetRow(0).x, value.GetRow(0).y, 0, 0),
floatValue = value.GetRow(0).x,
colorValue = new Vector4(value.GetRow(0).x, value.GetRow(0).x, 0, 0)

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix2ShaderProperty.cs


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

public override PreviewProperty GetPreviewMaterialProperty()
{
return default(PreviewProperty);
}
public override INode ToConcreteNode()
{
return new Matrix2Node
{
row0 = new Vector2(value.m00, value.m01),
row1 = new Vector2(value.m10, value.m11)
};
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix3MaterialSlot.cs


public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Matrix3)
propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType),
vector4Value = new Vector4(value.GetRow(0).x, value.GetRow(0).y, value.GetRow(0).z, 0),
floatValue = value.GetRow(0).x,
colorValue = new Vector4(value.GetRow(0).x, value.GetRow(0).x, value.GetRow(0).z, 0)

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix3ShaderProperty.cs


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

public override PreviewProperty GetPreviewMaterialProperty()
{
return default(PreviewProperty);
}
public override INode ToConcreteNode()
{
return new Matrix3Node
{
row0 = new Vector3(value.m00, value.m01, value.m02),
row1 = new Vector3(value.m10, value.m11, value.m12),
row2 = new Vector3(value.m20, value.m21, value.m22)
};
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Matrix4MaterialSlot.cs


public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Matrix4)
propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType),
vector4Value = new Vector4(value.GetRow(0).x, value.GetRow(0).y, value.GetRow(0).z, value.GetRow(0).w),
floatValue = value.GetRow(0).x,
colorValue = new Vector4(value.GetRow(0).x, value.GetRow(0).x, value.GetRow(0).z, value.GetRow(0).w)

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


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

public override PreviewProperty GetPreviewMaterialProperty()
{
return default(PreviewProperty);
}
public override INode ToConcreteNode()
{
return new Matrix4Node
{
row0 = new Vector4(value.m00, value.m01, value.m02, value.m03),
row1 = new Vector4(value.m10, value.m11, value.m12, value.m13),
row2 = new Vector4(value.m20, value.m21, value.m22, value.m23),
row3 = new Vector4(value.m30, value.m31, value.m32, value.m33)
};
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MatrixShaderProperty.cs


return string.Empty;
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
{
return "float4x4 " + referenceName + ";";
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/NormalMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.Normal);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Normal));
}
public NeededCoordinateSpace RequiresNormal()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/PositionMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.Position);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Position));
}
public NeededCoordinateSpace RequiresPosition()

157
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/PreviewProperty.cs


using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace UnityEditor.ShaderGraph

public string name;
public PropertyType propType;
public string name { get; set; }
public PropertyType propType { get; private set; }
public PreviewProperty(PropertyType type) : this()
{
propType = type;
}
[StructLayout(LayoutKind.Explicit)]
struct Data
{
[FieldOffset(0)]
public Color colorValue;
[FieldOffset(0)]
public Texture textureValue;
[FieldOffset(0)]
public Cubemap cubemapValue;
[FieldOffset(0)]
public Vector4 vector4Value;
[FieldOffset(0)]
public float floatValue;
[FieldOffset(0)]
public bool booleanValue;
}
Data m_Data;
public Color colorValue
{
get
{
if (propType != PropertyType.Color)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Color, propType));
return m_Data.colorValue;
}
set
{
if (propType != PropertyType.Color)
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Color, propType));
m_Data.colorValue = value;
}
}
public Texture textureValue
{
get
{
if (propType != PropertyType.Texture)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Texture, propType));
return m_Data.textureValue;
}
set
{
if (propType != PropertyType.Texture)
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Texture, propType));
m_Data.textureValue = value;
}
}
public Cubemap cubemapValue
{
get
{
if (propType != PropertyType.Cubemap)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Cubemap, propType));
return m_Data.cubemapValue;
}
set
{
if (propType != PropertyType.Cubemap)
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Cubemap, propType));
m_Data.cubemapValue = value;
}
}
public Vector4 vector4Value
{
get
{
if (propType != PropertyType.Vector2 && propType != PropertyType.Vector3 && propType != PropertyType.Vector4)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Vector4, propType));
return m_Data.vector4Value;
}
set
{
if (propType != PropertyType.Vector2 && propType != PropertyType.Vector3 && propType != PropertyType.Vector4)
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Vector4, propType));
m_Data.vector4Value = value;
}
}
public float floatValue
{
get
{
if (propType != PropertyType.Vector1)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Vector1, propType));
return m_Data.floatValue;
}
set
{
if (propType != PropertyType.Vector1)
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Vector1, propType));
m_Data.floatValue = value;
}
}
public Color colorValue;
public Texture textureValue;
public Cubemap cubemapValue;
public Vector4 vector4Value;
public float floatValue;
public bool booleanValue
{
get
{
if (propType != PropertyType.Boolean)
throw new ArgumentException(string.Format(k_GetErrorMessage, PropertyType.Boolean, propType));
return m_Data.booleanValue;
}
set
{
if (propType != PropertyType.Boolean)
throw new ArgumentException(string.Format(k_SetErrorMessage, PropertyType.Boolean, propType));
m_Data.booleanValue = value;
}
}
const string k_SetErrorMessage = "Cannot set a {0} property on a PreviewProperty with type {1}.";
const string k_GetErrorMessage = "Cannot get a {0} property on a PreviewProperty with type {1}.";
public void SetMaterialPropertyBlockValue(MaterialPropertyBlock block)
{
if (propType == PropertyType.Texture && textureValue != null)
block.SetTexture(name, m_Data.textureValue);
else if (propType == PropertyType.Cubemap && cubemapValue != null)
block.SetTexture(name, m_Data.cubemapValue);
else if (propType == PropertyType.Color)
block.SetColor(name, m_Data.colorValue);
else if (propType == PropertyType.Vector2 || propType == PropertyType.Vector3 || propType == PropertyType.Vector4)
block.SetVector(name, m_Data.vector4Value);
else if (propType == PropertyType.Vector1)
block.SetFloat(name, m_Data.floatValue);
else if (propType == PropertyType.Boolean)
block.SetFloat(name, m_Data.booleanValue ? 1 : 0);
}
}
public static class PreviewPropertyExtensions
{
public static void SetPreviewProperty(this MaterialPropertyBlock block, PreviewProperty previewProperty)
{
previewProperty.SetMaterialPropertyBlockValue(block);
}
}
}

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


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

return string.Empty;
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return string.Format(@"
#ifdef UNITY_COMPILER_HLSL
SamplerState {0};
#endif", referenceName);
return string.Format(@"SAMPLER({0}){1}", referenceName, delimiter);
}
public override INode ToConcreteNode()
{
return new SamplerStateNode();
}
}
}

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ScreenPositionMaterialSlot.cs


[Serializable]
public class ScreenPositionMaterialSlot : Vector4MaterialSlot, IMayRequireScreenPosition
{
public ScreenPositionMaterialSlot()
{}
public ScreenPositionMaterialSlot(int slotId, string displayName, string shaderOutputName,
ShaderStage shaderStage = ShaderStage.Dynamic, bool hidden = false)
: base(slotId, displayName, shaderOutputName, SlotType.Input, Vector3.zero, shaderStage, hidden)

{
return ShaderGeneratorNames.ScreenPosition;
return string.Format("IN.{0}", ShaderGeneratorNames.ScreenPosition);
}
public bool RequiresScreenPosition()

36
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SerializableCubemap.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class SerializableCubemap : ISerializationCallbackReceiver
public class SerializableCubemap
{
[SerializeField]
private string m_SerializedCubemap;

public Cubemap cubemap;
}
Cubemap m_Cubemap;
if (m_Cubemap == null && !string.IsNullOrEmpty(m_SerializedCubemap))
{
var cube = new CubemapHelper();
EditorJsonUtility.FromJsonOverwrite(m_SerializedCubemap, cube);
m_Cubemap = cube.cubemap;
m_SerializedCubemap = null;
}
return m_Cubemap;
}
set { m_Cubemap = value; }
}
if (string.IsNullOrEmpty(m_SerializedCubemap))
return null;
public void OnBeforeSerialize()
{
var cube = new CubemapHelper { cubemap = cubemap };
m_SerializedCubemap = EditorJsonUtility.ToJson(cube, true);
}
var cube = new CubemapHelper();
EditorJsonUtility.FromJsonOverwrite(m_SerializedCubemap, cube);
return cube.cubemap;
}
set
{
if(cubemap == value)
return;
public void OnAfterDeserialize()
{
var cubemapHelper = new CubemapHelper();
cubemapHelper.cubemap = value;
m_SerializedCubemap = EditorJsonUtility.ToJson(cubemapHelper, true);
}
}
}
}

35
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SerializableTexture.cs


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class SerializableTexture : ISerializationCallbackReceiver
public class SerializableTexture
{
[SerializeField]
private string m_SerializedTexture;

public Texture texture;
}
Texture m_Texture;
if (m_Texture == null && !string.IsNullOrEmpty(m_SerializedTexture))
{
var tex = new TextureHelper();
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, tex);
m_Texture = tex.texture;
m_SerializedTexture = null;
}
return m_Texture;
if (string.IsNullOrEmpty(m_SerializedTexture))
return null;
var tex = new TextureHelper();
EditorJsonUtility.FromJsonOverwrite(m_SerializedTexture, tex);
return tex.texture;
set { m_Texture = value; }
}
set
{
if (texture == value)
return;
public void OnBeforeSerialize()
{
var tex = new TextureHelper { texture = texture };
m_SerializedTexture = EditorJsonUtility.ToJson(tex, true);
}
public void OnAfterDeserialize()
{
var textureHelper = new TextureHelper();
textureHelper.texture = value;
m_SerializedTexture = EditorJsonUtility.ToJson(textureHelper, true);
}
}
}
}

49
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ShaderGraphRequirements.cs


using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{

if (other.requiresMeshUVs != null)
newReqs.requiresMeshUVs.AddRange(other.requiresMeshUVs);
return newReqs;
}
public static ShaderGraphRequirements FromNodes(List<INode> nodes)
{
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal());
NeededCoordinateSpace requiresBitangent = nodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresBitangent());
NeededCoordinateSpace requiresTangent = nodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent());
NeededCoordinateSpace requiresViewDir = nodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresViewDirection());
NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition());
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
var meshUV = new List<UVChannel>();
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
{
var channel = (UVChannel)uvIndex;
if (nodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
meshUV.Add(channel);
}
// if anything needs tangentspace we have make
// sure to have our othonormal basis!
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition
| requiresTangent | requiresViewDir | requiresPosition
| requiresNormal;
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
if (needsTangentSpace)
{
requiresBitangent |= NeededCoordinateSpace.Object;
requiresNormal |= NeededCoordinateSpace.Object;
requiresTangent |= NeededCoordinateSpace.Object;
}
var reqs = new ShaderGraphRequirements()
{
requiresNormal = requiresNormal,
requiresBitangent = requiresBitangent,
requiresTangent = requiresTangent,
requiresViewDir = requiresViewDir,
requiresPosition = requiresPosition,
requiresScreenPosition = requiresScreenPosition,
requiresVertexColor = requiresVertexColor,
requiresMeshUVs = meshUV
};
return reqs;
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TangentMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.Tangent);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Tangent));
}
public NeededCoordinateSpace RequiresTangent()

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


public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Texture)
propType = PropertyType.Texture,
textureValue = texture
};
return pp;

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


public enum FilterMode
{
Linear,
Point
Point,
Trilinear
Clamp
Clamp,
Mirror,
MirrorOnce
}
[SerializeField] private FilterMode m_filter = FilterMode.Linear;

17
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureShaderProperty.cs


using System;
using System.Text;
using UnityEditor.Graphing;
using UnityEngine;
namespace UnityEditor.ShaderGraph

return result.ToString();
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return "UNITY_DECLARE_TEX2D(" + referenceName + ");";
return string.Format("TEXTURE2D({0}){1} SAMPLER(sampler{0}){1}", referenceName, delimiter);
public override string GetInlinePropertyDeclarationString()
public override string GetPropertyAsArgumentString()
return "UNITY_DECLARE_TEX2D_NOSAMPLER(" + referenceName + ");";
return string.Format("TEXTURE2D_ARGS({0}, sampler{0})", referenceName);
return new PreviewProperty()
return new PreviewProperty(PropertyType.Texture)
propType = PropertyType.Texture,
}
public override INode ToConcreteNode()
{
return new Texture2DAssetNode { texture = value.texture };
}
}
}

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


[Serializable]
public class UVMaterialSlot : Vector2MaterialSlot, IMayRequireMeshUV
{
private UVChannel m_Channel = UVChannel.uv0;
[SerializeField]
UVChannel m_Channel = UVChannel.UV0;
public UVChannel channel
{

public override string GetDefaultValue(GenerationMode generationMode)
{
return string.Format("{0}.xy", channel.GetUVName());
return string.Format("IN.{0}.xy", channel.GetUVName());
}
public bool RequiresMeshUV(UVChannel channel)

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


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Vector1MaterialSlot : MaterialSlot, IMaterialSlotHasVaule<float>
public class Vector1MaterialSlot : MaterialSlot, IMaterialSlotHasValue<float>
{
[SerializeField]
private float m_Value;

protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
return value.ToString();
return NodeUtils.FloatToShaderValue(value);
}
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)

if (matOwner == null)
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
var property = new FloatShaderProperty()
var property = new Vector1ShaderProperty()
{
overrideReferenceName = matOwner.GetVariableNameForSlot(id),
generatePropertyBlock = false,

public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Vector1)
propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType),
vector4Value = new Vector4(value, value, value, value),
floatValue = value,
colorValue = new Vector4(value, value, value, value),
floatValue = value
};
return pp;
}

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


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Vector2MaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Vector2>
public class Vector2MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector2>
{
[SerializeField]
private Vector2 m_Value;

protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
return precision + "2 (" + value.x + "," + value.y + ")";
return precision + "2 (" + NodeUtils.FloatToShaderValue(value.x) + "," + NodeUtils.FloatToShaderValue(value.y) + ")";
}
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)

public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Vector2)
propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType),
vector4Value = new Vector4(value.x, value.y, 0, 0),
floatValue = value.x,
colorValue = new Vector4(value.x, value.x, 0, 0),
vector4Value = new Vector4(value.x, value.y, 0, 0)
};
return pp;
}

public override void CopyValuesFrom(MaterialSlot foundSlot)
{

15
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2ShaderProperty.cs


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

{
get { return new Vector4(value.x, value.y, 0, 0); }
}
public override string GetInlinePropertyDeclarationString()
{
return "float2 " + referenceName + ";";
}
return new PreviewProperty()
return new PreviewProperty(PropertyType.Vector2)
propType = PropertyType.Vector2,
}
public override INode ToConcreteNode()
{
return new Vector2Node { value = value };
}
}
}

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


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Vector3MaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Vector3>
public class Vector3MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector3>
{
[SerializeField]
private Vector3 m_Value;

protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
return precision + "3 (" + value.x + "," + value.y + "," + value.z + ")";
return precision + "3 (" + NodeUtils.FloatToShaderValue(value.x) + "," + NodeUtils.FloatToShaderValue(value.y) + "," + NodeUtils.FloatToShaderValue(value.z) + ")";
}
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)

public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Vector3)
propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType),
vector4Value = new Vector4(value.x, value.y, value.z, 0),
floatValue = value.x,
colorValue = new Vector4(value.x, value.x, value.z, 0),
vector4Value = new Vector4(value.x, value.y, value.z, 0)
};
return pp;
}

16
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3ShaderProperty.cs


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

{
get { return new Vector4(value.x, value.y, value.z, 0); }
}
public override string GetInlinePropertyDeclarationString()
{
return "float3 " + referenceName + ";";
}
return new PreviewProperty()
return new PreviewProperty(PropertyType.Vector3)
propType = PropertyType.Vector3,
}
public override INode ToConcreteNode()
{
return new Vector3Node { value = value };
}
}
}

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


namespace UnityEditor.ShaderGraph
{
[Serializable]
public class Vector4MaterialSlot : MaterialSlot, IMaterialSlotHasVaule<Vector4>
public class Vector4MaterialSlot : MaterialSlot, IMaterialSlotHasValue<Vector4>
{
[SerializeField]
private Vector4 m_Value;

protected override string ConcreteSlotValueAsVariable(AbstractMaterialNode.OutputPrecision precision)
{
return precision + "4 (" + value.x + "," + value.y + "," + value.z + "," + value.w + ")";
return precision + "4 (" + NodeUtils.FloatToShaderValue(value.x) + "," + NodeUtils.FloatToShaderValue(value.y) + "," + NodeUtils.FloatToShaderValue(value.z) + "," + NodeUtils.FloatToShaderValue(value.w) + ")";
}
public override void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)

public override PreviewProperty GetPreviewProperty(string name)
{
var pp = new PreviewProperty
var pp = new PreviewProperty(PropertyType.Vector4)
propType = ConvertConcreteSlotValueTypeToPropertyType(concreteValueType),
floatValue = value.x,
colorValue = new Vector4(value.x, value.x, value.z, value.w),
};
return pp;
}

public override void CopyValuesFrom(MaterialSlot foundSlot)
{

9
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4ShaderProperty.cs


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

public override PreviewProperty GetPreviewMaterialProperty()
{
return new PreviewProperty()
return new PreviewProperty(PropertyType.Vector4)
propType = PropertyType.Vector4,
}
public override INode ToConcreteNode()
{
return new Vector4Node { value = value };
}
}
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/VectorShaderProperty.cs


return result.ToString();
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return "float4 " + referenceName + ";";
return string.Format("float4 {0}{1}", referenceName, delimiter);
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/VertexColorMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return ShaderGeneratorNames.VertexColor;
return string.Format("IN.{0}", ShaderGeneratorNames.VertexColor);
}
public bool RequiresScreenPosition()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ViewDirectionMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.ViewDirection);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.ViewDirection));
}
public NeededCoordinateSpace RequiresViewDirection()

94
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector1ShaderProperty.cs


using System;
using System.Text;
using UnityEditor.Graphing;
public enum FloatType
{
Default,
Slider,
Integer
}
public class FloatShaderProperty : AbstractShaderProperty<float>
[FormerName("UnityEditor.ShaderGraph.FloatShaderProperty")]
public class Vector1ShaderProperty : AbstractShaderProperty<float>
public FloatShaderProperty()
public Vector1ShaderProperty()
displayName = "Float";
displayName = "Vector1";
get { return PropertyType.Float; }
get { return PropertyType.Vector1; }
}
public override Vector4 defaultValue

[SerializeField]
private FloatType m_FloatType = FloatType.Default;
public FloatType floatType
{
get { return m_FloatType; }
set
{
if (m_FloatType == value)
return;
m_FloatType = value;
}
}
[SerializeField]
private Vector2 m_RangeValues = new Vector2(0, 1);
public Vector2 rangeValues
{
get { return m_RangeValues; }
set
{
if (m_RangeValues == value)
return;
m_RangeValues = value;
}
}
// if (m_FloatType == FloatPropertyChunk.FloatType.Toggle)
// result.Append("[Toggle]");
// else if (m_FloatType == FloatPropertyChunk.FloatType.PowerSlider)
// result.Append("[PowerSlider(" + m_rangeValues.z + ")]");
//if (m_FloatType == FloatPropertyChunk.FloatType.Float || m_FloatType == FloatPropertyChunk.FloatType.Toggle)
//{
result.Append("\", Float) = ");
/* }
else if (m_FloatType == FloatPropertyChunk.FloatType.Range || m_FloatType == FloatPropertyChunk.FloatType.PowerSlider)
{
result.Append("\", Range(");
result.Append(m_rangeValues.x + ", " + m_rangeValues.y);
result.Append(")) = ");
}*/
switch(floatType)
{
case FloatType.Slider:
result.Append("\", Range(");
result.Append(m_RangeValues.x + ", " + m_RangeValues.y);
result.Append(")) = ");
break;
case FloatType.Integer:
result.Append("\", Int) = ");
break;
default:
result.Append("\", Float) = ");
break;
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return "float " + referenceName + ";";
return string.Format("float {0}{1}", referenceName, delimiter);
return new PreviewProperty()
return new PreviewProperty(PropertyType.Vector1)
propType = PropertyType.Float,
}
public override INode ToConcreteNode()
{
switch(m_FloatType)
{
case FloatType.Slider:
return new SliderNode { value = new Vector3(value, m_RangeValues.x, m_RangeValues.y) };
case FloatType.Integer:
return new IntegerNode { value = (int)value };
default:
return new Vector1Node { value = value };
}
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IMaterialSlotHasValue.cs.meta


fileFormatVersion: 2
guid: 722107fbcd3d86249ac260090e5cc77e
guid: 94492244ef44a2e48b3e7790d7ac681d
MonoImporter:
externalObjects: {}
serializedVersion: 2

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/IGeneratesFunction.cs


{
public interface IGeneratesFunction
{
void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode);
void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode);
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/NeededCoordinateSpace.cs


Tangent = 1 << 3
}
public enum CoordinateSpace : int
public enum CoordinateSpace
{
Object,
View,

127
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightPBRSubShader.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

PBRMasterNode.MetallicSlotId,
PBRMasterNode.SmoothnessSlotId,
PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
}
};

PBRMasterNode.SpecularSlotId,
PBRMasterNode.SmoothnessSlotId,
PBRMasterNode.OcclusionSlotId,
PBRMasterNode.AlphaSlotId
PBRMasterNode.AlphaSlotId,
PBRMasterNode.AlphaThresholdSlotId
private static void GenerateApplicationVertexInputs(ShaderGraphRequirements graphRequiements, ShaderGenerator vertexInputs, int vertexInputStartIndex, int maxVertexInputs)
{
int vertexInputIndex = vertexInputStartIndex;
vertexInputs.AddShaderChunk("struct GraphVertexInput", false);
vertexInputs.AddShaderChunk("{", false);
vertexInputs.Indent();
vertexInputs.AddShaderChunk("float4 vertex : POSITION;", false);
vertexInputs.AddShaderChunk("float3 normal : NORMAL;", false);
vertexInputs.AddShaderChunk("float4 tangent : TANGENT;", false);
vertexInputs.AddShaderChunk("float4 lightmapUV : TEXCOORD0;", false);
if (graphRequiements.requiresVertexColor)
{
vertexInputs.AddShaderChunk("float4 color : COLOR;", false);
}
foreach (var channel in graphRequiements.requiresMeshUVs.Distinct())
{
vertexInputs.AddShaderChunk(string.Format("float4 texcoord{0} : TEXCOORD{1};", ((int)channel).ToString(), vertexInputIndex.ToString()), false);
vertexInputIndex++;
}
vertexInputs.AddShaderChunk("UNITY_VERTEX_INPUT_INSTANCE_ID", false);
vertexInputs.Deindent();
vertexInputs.AddShaderChunk("};", false);
}
var builder = new ShaderStringBuilder();
builder.IncreaseIndent();
builder.IncreaseIndent();
var shaderFunctionVisitor = new ShaderGenerator();
var functionRegistry = new FunctionRegistry(builder);
var surfaceInputs = new ShaderGenerator();
var shaderProperties = new PropertyCollector();

var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
var requirements = AbstractMaterialGraph.GetRequirements(activeNodeList);
GenerateApplicationVertexInputs(requirements, vertexInputs, 1, 8);
var requirements = ShaderGraphRequirements.FromNodes(activeNodeList);
var modelRequiements = ShaderGraphRequirements.none;
modelRequiements.requiresNormal |= NeededCoordinateSpace.World;
modelRequiements.requiresTangent |= NeededCoordinateSpace.World;
modelRequiements.requiresBitangent |= NeededCoordinateSpace.World;
modelRequiements.requiresPosition |= NeededCoordinateSpace.World;
modelRequiements.requiresViewDir |= NeededCoordinateSpace.World;
modelRequiements.requiresMeshUVs.Add(UVChannel.UV1);
GraphUtil.GenerateApplicationVertexInputs(requirements.Union(modelRequiements), vertexInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, InterpolatorType.Normal, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, InterpolatorType.Tangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, InterpolatorType.BiTangent, surfaceInputs);

var slots = new List<MaterialSlot>();
foreach (var id in pass.PixelShaderSlots)
slots.Add(masterNode.FindSlot<MaterialSlot>(id));
AbstractMaterialGraph.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
AbstractMaterialGraph.GenerateSurfaceDescription(
GraphUtil.GenerateSurfaceDescription(
shaderFunctionVisitor,
functionRegistry,
null,
graph.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(builder.ToString(), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceVertexShader.GetShaderString(2), false);
graph.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);

var zWriteVisitor = new ShaderGenerator();
materialOptions.GetBlend(blendingVisitor);
materialOptions.GetCull(cullingVisitor);

var localSurfaceInputs = new ShaderGenerator();
var surfaceOutputRemap = new ShaderGenerator();
var reqs = ShaderGraphRequirements.none;
reqs.requiresNormal |= NeededCoordinateSpace.World;
reqs.requiresTangent |= NeededCoordinateSpace.World;
reqs.requiresBitangent |= NeededCoordinateSpace.World;
reqs.requiresPosition |= NeededCoordinateSpace.World;
reqs.requiresViewDir |= NeededCoordinateSpace.World;
ShaderGenerator.GenerateStandardTransforms(
3,
10,

localSurfaceInputs,
requirements,
reqs,
modelRequiements,
CoordinateSpace.World);
ShaderGenerator defines = new ShaderGenerator();

if (masterNode.model == PBRMasterNode.Model.Specular)
defines.AddShaderChunk("#define _SPECULAR_SETUP 1", true);
switch (masterNode.alphaMode)
{
case PBRMasterNode.AlphaMode.AlphaBlend:
case PBRMasterNode.AlphaMode.AdditiveBlend:
defines.AddShaderChunk("#define _AlphaOut 1", true);
break;
case PBRMasterNode.AlphaMode.Clip:
defines.AddShaderChunk("#define _AlphaClip 1", true);
break;
}
if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId))
defines.AddShaderChunk("#define _AlphaClip 1", true);
surfaceOutputRemap.AddShaderChunk(slot.shaderOutputName
+ " = surf."
+ slot.shaderOutputName + ";", true);
surfaceOutputRemap.AddShaderChunk(string.Format("{0} = surf.{0};", slot.shaderOutputName), true);
}
if (!File.Exists(templateLocation))

resultPass = resultPass.Replace("${SurfaceInputs}", localSurfaceInputs.GetShaderString(3));
resultPass = resultPass.Replace("${SurfaceOutputRemap}", surfaceOutputRemap.GetShaderString(3));
resultPass = resultPass.Replace("${Tags}", string.Empty);
resultPass = resultPass.Replace("${Blending}", blendingVisitor.GetShaderString(2));
resultPass = resultPass.Replace("${Culling}", cullingVisitor.GetShaderString(2));

subShader.Indent();
subShader.AddShaderChunk("Tags{ \"RenderPipeline\" = \"LightweightPipeline\"}", true);
var materialOptions = new SurfaceMaterialOptions();
switch (masterNode.alphaMode)
{
case PBRMasterNode.AlphaMode.Overwrite:
case PBRMasterNode.AlphaMode.Clip:
materialOptions.srcBlend = SurfaceMaterialOptions.BlendMode.One;
materialOptions.dstBlend = SurfaceMaterialOptions.BlendMode.Zero;
materialOptions.cullMode = SurfaceMaterialOptions.CullMode.Back;
materialOptions.zTest = SurfaceMaterialOptions.ZTest.LEqual;
materialOptions.zWrite = SurfaceMaterialOptions.ZWrite.On;
materialOptions.renderQueue = SurfaceMaterialOptions.RenderQueue.Geometry;
materialOptions.renderType = SurfaceMaterialOptions.RenderType.Opaque;
break;
case PBRMasterNode.AlphaMode.AlphaBlend:
materialOptions.srcBlend = SurfaceMaterialOptions.BlendMode.SrcAlpha;
materialOptions.dstBlend = SurfaceMaterialOptions.BlendMode.OneMinusSrcAlpha;
materialOptions.cullMode = SurfaceMaterialOptions.CullMode.Back;
materialOptions.zTest = SurfaceMaterialOptions.ZTest.LEqual;
materialOptions.zWrite = SurfaceMaterialOptions.ZWrite.Off;
materialOptions.renderQueue = SurfaceMaterialOptions.RenderQueue.Transparent;
materialOptions.renderType = SurfaceMaterialOptions.RenderType.Transparent;
break;
case PBRMasterNode.AlphaMode.AdditiveBlend:
materialOptions.srcBlend = SurfaceMaterialOptions.BlendMode.One;
materialOptions.dstBlend = SurfaceMaterialOptions.BlendMode.One;
materialOptions.cullMode = SurfaceMaterialOptions.CullMode.Back;
materialOptions.zTest = SurfaceMaterialOptions.ZTest.LEqual;
materialOptions.zWrite = SurfaceMaterialOptions.ZWrite.Off;
materialOptions.renderQueue = SurfaceMaterialOptions.RenderQueue.Transparent;
materialOptions.renderType = SurfaceMaterialOptions.RenderType.Transparent;
break;
}
var materialOptions = MasterNode.GetMaterialOptionsFromAlphaMode(masterNode.alphaMode);
var tagsVisitor = new ShaderGenerator();
materialOptions.GetTags(tagsVisitor);
subShader.AddShaderChunk(tagsVisitor.GetShaderString(0), true);

65
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightUnlitSubShader.cs


namespace UnityEditor.ShaderGraph
{
public class LightWeightUnlitSubShader
public class LightWeightUnlitSubShader : IUnlitSubShader
{
Pass m_UnlitPass = new Pass()
{

UnlitMasterNode.ColorSlotId,
UnlitMasterNode.AlphaSlotId
UnlitMasterNode.AlphaSlotId,
UnlitMasterNode.AlphaThresholdSlotId
}
};

public List<int> PixelShaderSlots;
}
private static string GetShaderPassFromTemplate(string template, UnlitMasterNode masterNode, Pass pass, GenerationMode mode)
private static string GetShaderPassFromTemplate(
string template,
UnlitMasterNode masterNode,
Pass pass,
GenerationMode mode,
SurfaceMaterialOptions materialOptions)
var builder = new ShaderStringBuilder();
builder.IncreaseIndent();
builder.IncreaseIndent();
var shaderFunctionVisitor = new ShaderGenerator();
var functionRegistry = new FunctionRegistry(builder);
var surfaceInputs = new ShaderGenerator();
var shaderProperties = new PropertyCollector();

var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);
var requirements = AbstractMaterialGraph.GetRequirements(activeNodeList);
AbstractMaterialGraph.GenerateApplicationVertexInputs(requirements, vertexInputs, 0, 8);
var requirements = ShaderGraphRequirements.FromNodes(activeNodeList);
GraphUtil.GenerateApplicationVertexInputs(requirements, vertexInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, InterpolatorType.Normal, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, InterpolatorType.Tangent, surfaceInputs);
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, InterpolatorType.BiTangent, surfaceInputs);

if (slot != null)
slots.Add(slot);
}
AbstractMaterialGraph.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true);
AbstractMaterialGraph.GenerateSurfaceDescription(
GraphUtil.GenerateSurfaceDescription(
shaderFunctionVisitor,
functionRegistry,
shaderProperties,
requirements,
mode,

null,
graph.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(builder.ToString(), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
var tagsVisitor = new ShaderGenerator();
var materialOptions = new SurfaceMaterialOptions();
materialOptions.GetTags(tagsVisitor);
materialOptions.GetBlend(blendingVisitor);
materialOptions.GetCull(cullingVisitor);
materialOptions.GetDepthTest(zTestVisitor);

var surfaceOutputRemap = new ShaderGenerator();
var reqs = ShaderGraphRequirements.none;
reqs.requiresNormal |= NeededCoordinateSpace.World;
reqs.requiresTangent |= NeededCoordinateSpace.World;
reqs.requiresBitangent |= NeededCoordinateSpace.World;
reqs.requiresPosition |= NeededCoordinateSpace.World;
reqs.requiresViewDir |= NeededCoordinateSpace.World;
ShaderGenerator.GenerateStandardTransforms(
3,

CoordinateSpace.World);
ShaderGenerator defines = new ShaderGenerator();
if (masterNode.IsSlotConnected(UnlitMasterNode.AlphaThresholdSlotId))
defines.AddShaderChunk("#define _AlphaClip 1", true);
var templateLocation = ShaderGenerator.GetTemplatePath(template);
foreach (var slot in usedSlots)

resultPass = resultPass.Replace("${SurfaceInputs}", localSurfaceInputs.GetShaderString(3));
resultPass = resultPass.Replace("${SurfaceOutputRemap}", surfaceOutputRemap.GetShaderString(3));
resultPass = resultPass.Replace("${Tags}", tagsVisitor.GetShaderString(2));
resultPass = resultPass.Replace("${Tags}", string.Empty);
resultPass = resultPass.Replace("${LOD}", "" + materialOptions.lod);
public IEnumerable<string> GetSubshader(UnlitMasterNode masterNode, GenerationMode mode)
public string GetSubshader(UnlitMasterNode masterNode, GenerationMode mode)
{
var subShader = new ShaderGenerator();
subShader.AddShaderChunk("SubShader", true);

var materialOptions = MasterNode.GetMaterialOptionsFromAlphaMode(masterNode.alphaMode);
var tagsVisitor = new ShaderGenerator();
materialOptions.GetTags(tagsVisitor);
subShader.AddShaderChunk(tagsVisitor.GetShaderString(0), true);
mode),
mode,
materialOptions),
return new[] { subShader.GetShaderString(0) };
return subShader.GetShaderString(0);
}
}
}

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


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

}
[Serializable]
public abstract class AbstractMaterialNode : SerializableNode, IGenerateProperties
public abstract class AbstractMaterialNode : INode, ISerializationCallbackReceiver, IGenerateProperties
{
protected static List<MaterialSlot> s_TempSlots = new List<MaterialSlot>();
protected static List<IEdge> s_TempEdges = new List<IEdge>();

}
[NonSerialized]
private Guid m_Guid;
[SerializeField]
private string m_GuidSerialized;
[SerializeField]
private string m_Name;
[SerializeField]
private DrawState m_DrawState;
[NonSerialized]
private List<ISlot> m_Slots = new List<ISlot>();
[SerializeField]
List<SerializationHelper.JSONSerializedElement> m_SerializableSlots = new List<SerializationHelper.JSONSerializedElement>();
[NonSerialized]
public Identifier tempId { get; set; }
public IGraph owner { get; set; }
public OnNodeModified onModified { get; set; }
public void Dirty(ModificationScope scope)
{
if (onModified != null)
onModified(this, scope);
}
public Guid guid
{
get { return m_Guid; }
}
public string name
{
get { return m_Name; }
set { m_Name = value; }
}
public virtual bool canDeleteNode
{
get { return true; }
}
public DrawState drawState
{
get { return m_DrawState; }
set
{
m_DrawState = value;
Dirty(ModificationScope.Node);
}
}
private OutputPrecision m_OutputPrecision = OutputPrecision.@float;
public OutputPrecision precision
{
get { return m_OutputPrecision; }

//[SerializeField]
private OutputPrecision m_OutputPrecision = OutputPrecision.@float;
[SerializeField]
bool m_PreviewExpanded = true;

if (previewExpanded == value)
return;
m_PreviewExpanded = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
}
}

{
get { return true; }
}
public virtual bool allowedInRemapGraph
{
get { return true; }
}
public virtual bool allowedInMainGraph
{
get { return true; }

get { return true; }
}
public override bool hasError
public virtual bool hasError
{
get { return m_HasError; }
protected set { m_HasError = value; }

{
if (m_NameForDefaultVariableName != name || m_GuidForDefaultVariableName != guid)
{
m_DefaultVariableName = string.Format("{0}_{1}", GetHLSLSafeName(name), GuidEncoder.Encode(guid));
m_DefaultVariableName = string.Format("{0}_{1}", NodeUtils.GetHLSLSafeName(name), GuidEncoder.Encode(guid));
m_NameForDefaultVariableName = name;
m_GuidForDefaultVariableName = guid;
}

protected AbstractMaterialNode()
{
m_DrawState.expanded = true;
m_Guid = Guid.NewGuid();
public Guid RewriteGuid()
{
m_Guid = Guid.NewGuid();
return m_Guid;
}
public void GetInputSlots<T>(List<T> foundSlots) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.isInputSlot && slot is T)
foundSlots.Add((T)slot);
}
}
public void GetOutputSlots<T>(List<T> foundSlots) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.isOutputSlot && slot is T)
foundSlots.Add((T)slot);
}
}
public void GetSlots<T>(List<T> foundSlots) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot is T)
foundSlots.Add((T)slot);
}
}
public virtual void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
foreach (var inputSlot in this.GetInputSlots<MaterialSlot>())

return ConcreteSlotValueType.Matrix2;
}
public override void ValidateNode()
public virtual void ValidateNode()
{
var isInError = false;

return false;
}
public static string GetSlotDimension(ConcreteSlotValueType slotValue)
{
switch (slotValue)
{
case ConcreteSlotValueType.Vector1:
return string.Empty;
case ConcreteSlotValueType.Vector2:
return "2";
case ConcreteSlotValueType.Vector3:
return "3";
case ConcreteSlotValueType.Vector4:
return "4";
case ConcreteSlotValueType.Matrix2:
return "2x2";
case ConcreteSlotValueType.Matrix3:
return "3x3";
case ConcreteSlotValueType.Matrix4:
return "4x4";
default:
return "Error";
}
}
public static string ConvertConcreteSlotValueTypeToString(OutputPrecision p, ConcreteSlotValueType slotValue)
{
switch (slotValue)
{
case ConcreteSlotValueType.Vector1:
return p.ToString();
case ConcreteSlotValueType.Vector2:
return p + "2";
case ConcreteSlotValueType.Vector3:
return p + "3";
case ConcreteSlotValueType.Vector4:
return p + "4";
case ConcreteSlotValueType.Texture2D:
return "Texture2D";
case ConcreteSlotValueType.Cubemap:
return "Cubemap";
case ConcreteSlotValueType.Matrix2:
return p + "2x2";
case ConcreteSlotValueType.Matrix3:
return p + "3x3";
case ConcreteSlotValueType.Matrix4:
return p + "4x4";
case ConcreteSlotValueType.SamplerState:
return "SamplerState";
default:
return "Error";
}
}
public virtual void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
s_TempSlots.Clear();

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 string.Format("_{0}_{1}", GetVariableNameForNode(), GetHLSLSafeName(slot.shaderOutputName));
return string.Format("_{0}_{1}", GetVariableNameForNode(), NodeUtils.GetHLSLSafeName(slot.shaderOutputName));
}
public virtual string GetVariableNameForNode()

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)
public void AddSlot(ISlot slot)
{
if (!(slot is MaterialSlot))
throw new ArgumentException(string.Format("Trying to add slot {0} to Material node {1}, but it is not a {2}", slot, this, typeof(MaterialSlot)));

// this will remove the old slot and add a new one
// if an old one was found. This allows updating values
base.AddSlot(slot);
m_Slots.RemoveAll(x => x.id == slot.id);
m_Slots.Add(slot);
slot.owner = this;
Dirty(ModificationScope.Topological);
}
public void RemoveSlot(int slotId)
{
// Remove edges that use this slot
// no owner can happen after creation
// but before added to graph
if (owner != null)
{
var edges = owner.GetEdges(GetSlotReference(slotId));
foreach (var edge in edges.ToArray())
owner.RemoveEdge(edge);
}
//remove slots
m_Slots.RemoveAll(x => x.id == slotId);
Dirty(ModificationScope.Topological);
}
public void RemoveSlotsNameNotMatching(IEnumerable<int> slotIds, bool supressWarnings = false)
{
var invalidSlots = m_Slots.Select(x => x.id).Except(slotIds);
foreach (var invalidSlot in invalidSlots.ToArray())
{
if (!supressWarnings)
Debug.LogWarningFormat("Removing Invalid MaterialSlot: {0}", invalidSlot);
RemoveSlot(invalidSlot);
}
}
public SlotReference GetSlotReference(int slotId)
{
var slot = FindSlot<ISlot>(slotId);
if (slot == null)
throw new ArgumentException("Slot could not be found", "slotId");
return new SlotReference(guid, slotId);
}
public T FindSlot<T>(int slotId) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.id == slotId && slot is T)
return (T)slot;
}
return default(T);
}
public T FindInputSlot<T>(int slotId) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.isInputSlot && slot.id == slotId && slot is T)
return (T)slot;
}
return default(T);
}
public T FindOutputSlot<T>(int slotId) where T : ISlot
{
foreach (var slot in m_Slots)
{
if (slot.isOutputSlot && slot.id == slotId && slot is T)
return (T)slot;
}
return default(T);
}
public virtual IEnumerable<ISlot> GetInputsWithNoConnection()
{
return this.GetInputSlots<ISlot>().Where(x => !owner.GetEdges(GetSlotReference(x.id)).Any());
}
public virtual void OnBeforeSerialize()
{
m_GuidSerialized = m_Guid.ToString();
m_SerializableSlots = SerializationHelper.Serialize<ISlot>(m_Slots);
}
public virtual void OnAfterDeserialize()
{
if (!string.IsNullOrEmpty(m_GuidSerialized))
m_Guid = new Guid(m_GuidSerialized);
else
m_Guid = Guid.NewGuid();
m_Slots = SerializationHelper.Deserialize<ISlot>(m_SerializableSlots, GraphUtil.GetLegacyTypeRemapping());
m_SerializableSlots = null;
foreach (var s in m_Slots)
s.owner = this;
UpdateNodeAfterDeserialization();
}
public virtual void UpdateNodeAfterDeserialization()
{}
public bool IsSlotConnected(int slotId)
{
var slot = FindSlot<MaterialSlot>(slotId);
return slot != null && owner.GetEdges(slot.slotReference).Any();
}
}
}

68
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs


if ((value.outRed == m_ChannelMixer.outRed) && (value.outGreen == m_ChannelMixer.outGreen) && (value.outBlue == m_ChannelMixer.outBlue))
return;
m_ChannelMixer = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
string GetFunctionPrototype(string argIn, string argRed, string argGreen, string argBlue, string argOut)
{
return string.Format("void {0} ({1} {2}, {3} {4}, {3} {5}, {3} {6}, out {7} {8})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), argIn,
precision + "3", argRed, argGreen, argBlue,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), argOut);
}
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
var sb = new ShaderStringBuilder();
var inputValue = GetSlotValue(InputSlotId, generationMode);
var outputValue = GetSlotValue(OutputSlotId, generationMode);
sb.AppendLine("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId));
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Red = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outRed[0], channelMixer.outRed[1], channelMixer.outRed[2]), true);
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Green = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outGreen[0], channelMixer.outGreen[1], channelMixer.outGreen[2]), true);
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Blue = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outBlue[0], channelMixer.outBlue[1], channelMixer.outBlue[2]), true);
sb.AppendLine("{0}3 _{1}_Red = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outRed[0], channelMixer.outRed[1], channelMixer.outRed[2]);
sb.AppendLine("{0}3 _{1}_Green = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outGreen[0], channelMixer.outGreen[1], channelMixer.outGreen[2]);
sb.AppendLine("{0}3 _{1}_Blue = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outBlue[0], channelMixer.outBlue[1], channelMixer.outBlue[2]);
sb.AppendLine("{0}({1}, _{2}_Red, _{2}_Green, _{2}_Blue, {3});", GetFunctionName(), inputValue, GetVariableNameForNode(), outputValue);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, string.Format("_{0}_Red", GetVariableNameForNode()), string.Format("_{0}_Green", GetVariableNameForNode()), string.Format("_{0}_Blue", GetVariableNameForNode()), outputValue), true);
}
string GetFunctionCallBody(string inputValue, string red, string green, string blue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + red + ", " + green + ", " + blue + ", " + outputValue + ");";
visitor.AddShaderChunk(sb.ToString(), false);
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)

properties.Add(new PreviewProperty()
properties.Add(new PreviewProperty(PropertyType.Vector3)
propType = PropertyType.Vector3,
properties.Add(new PreviewProperty()
properties.Add(new PreviewProperty(PropertyType.Vector3)
propType = PropertyType.Vector3,
properties.Add(new PreviewProperty()
properties.Add(new PreviewProperty(PropertyType.Vector3)
propType = PropertyType.Vector3,
vector4Value = channelMixer.outBlue
});
}

});
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
var sg = new ShaderGenerator();
sg.AddShaderChunk(GetFunctionPrototype("In", "Red", "Green", "Blue", "Out"), false);
sg.AddShaderChunk("{", false);
sg.Indent();
sg.AddShaderChunk(string.Format("Out = {0} (dot(In, Red), dot(In, Green), dot(In, Blue));",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType)), true);
sg.Deindent();
sg.AddShaderChunk("}", false);
visitor.AddShaderChunk(sg.GetShaderString(0), true);
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0} ({1} In, {2}3 Red, {2}3 Green, {2}3 Blue, out {3} Out)",
GetFunctionName(),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
precision,
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Out = {0}(dot(In, Red), dot(In, Green), dot(In, Blue));",
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
}
});
}
}
}

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


return;
m_HueMode = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Blend/BlendMode.cs


Lighten,
LinearBurn,
LinearDodge,
LinearLight,
LinearLightAddSub,
Multiply,
Negation,

159
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Blend/BlendNode.cs


[SerializeField]
BlendMode m_BlendMode = BlendMode.Overlay;
[EnumControl("")]
[EnumControl("Mode")]
public BlendMode blendMode
{
get { return m_BlendMode; }

return;
m_BlendMode = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

}
static string Unity_Blend_Burn(
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = 1.0 - (1.0 - B)/A;
Out = 1.0 - (1.0 - Blend)/Base;
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = min(B, A);
Out = min(Blend, Base);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = abs(B - A);
Out = abs(Blend - Base);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = B / (1.0 - A);
Out = Base / (1.0 - Blend);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = A / (B + 0.000000000001);
Out = Base / (Blend + 0.000000000001);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = B + A - (2.0 * B * A);
Out = Blend + Base - (2.0 * Blend * Base);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
{precision}{slot2dimension} result1 = 1.0 - 2.0 * (1.0 - A) * (1.0 - B);
{precision}{slot2dimension} result2 = 2.0 * A * B;
{precision}{slot2dimension} zeroOrOne = step(A, 0.5);
{precision}{slot2dimension} result1 = 1.0 - 2.0 * (1.0 - Base) * (1.0 - Blend);
{precision}{slot2dimension} result2 = 2.0 * Base * Blend;
{precision}{slot2dimension} zeroOrOne = step(Blend, 0.5);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = step(1 - A, B);
Out = step(1 - Base, Blend);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = max(B, A);
Out = max(Blend, Base);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = A + B - 1.0;
Out = Base + Blend - 1.0;
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
[Slot(2, Binding.None)] out DynamicDimensionVector Out)
{
return
@"
{
Out = Base + Blend;
}";
}
static string Unity_Blend_LinearLight(
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = A + B;
Out = Blend < 0.5 ? max(Base + (2 * Blend) - 1, 0) : min(Base + 2 * (Blend - 0.5), 1);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = B + 2.0 * A - 1.0;
Out = Blend + 2.0 * Base - 1.0;
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = A * B;
Out = Base * Blend;
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = 1.0 - abs(1.0 - B - A);
Out = 1.0 - abs(1.0 - Blend - Base);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = 1.0 - (1.0 - B) * (1.0 - A);
Out = 1.0 - (1.0 - Blend) * (1.0 - Base);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
{precision}{slot2dimension} result1 = 1.0 - 2.0 * (1.0 - A) * (1.0 - B);
{precision}{slot2dimension} result2 = 2.0 * A * B;
{precision}{slot2dimension} zeroOrOne = step(B, 0.5);
{precision}{slot2dimension} result1 = 1.0 - 2.0 * (1.0 - Base) * (1.0 - Blend);
{precision}{slot2dimension} result2 = 2.0 * Base * Blend;
{precision}{slot2dimension} zeroOrOne = step(Base, 0.5);
Out = result2 * zeroOrOne + (1 - zeroOrOne) * result1;
}
";

[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
{precision}{slot2dimension} check = step (0.5, A);
{precision}{slot2dimension} result1 = check * max(2.0 * (A - 0.5), B);
Out = result1 + (1.0 - check) * min(2.0 * A, B);
{precision}{slot2dimension} check = step (0.5, Blend);
{precision}{slot2dimension} result1 = check * max(2.0 * (Base - 0.5), Blend);
Out = result1 + (1.0 - check) * min(2.0 * Base, Blend);
[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
{precision}{slot2dimension} result1 = 2.0 * B * A + B * A - 2.0 * B * B * A;
{precision}{slot2dimension} result2 = 2.0 * sqrt(B) * A - sqrt(B) + 2.0 * B - 2.0 * B * A;
{precision}{slot2dimension} zeroOrOne = step(0.5, A);
{precision}{slot2dimension} result1 = 2.0 * Base * Blend + Base * Base * (1.0 - 2.0 * Blend);
{precision}{slot2dimension} result2 = sqrt(Base) * (2.0 * Blend - 1.0) + 2.0 * Base * (1.0 - Blend);
{precision}{slot2dimension} zeroOrOne = step(0.5, Blend);
Out = result2 * zeroOrOne + (1 - zeroOrOne) * result1;
}
";

[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
{precision}{slot2dimension} result1 = 1.0 - (1.0 - B) / (2.0 * A);
{precision}{slot2dimension} result2 = B / (2.0 * (1.0 - A));
{precision}{slot2dimension} zeroOrOne = step(0.5, A);
{precision}{slot2dimension} result1 = 1.0 - (1.0 - Blend) / (2.0 * Base);
{precision}{slot2dimension} result2 = Blend / (2.0 * (1.0 - Base));
{precision}{slot2dimension} zeroOrOne = step(0.5, Base);
Out = result2 * zeroOrOne + (1 - zeroOrOne) * result1;
}
";

[Slot(0, Binding.None)] DynamicDimensionVector A,
[Slot(1, Binding.None)] DynamicDimensionVector B,
[Slot(0, Binding.None)] DynamicDimensionVector Base,
[Slot(1, Binding.None)] DynamicDimensionVector Blend,
Out = A - B;
Out = Base - Blend;
}
";
}

106
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Mask/ChannelMaskNode.cs


using System.Reflection;
using System;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;

string GetFunctionName()
{
return string.Format("Unity_ChannelMask_{0}_{1}", channel, precision);
string channelSum = "None";
if (channelMask != 0)
{
bool red = (channelMask & 1) != 0;
bool green = (channelMask & 2) != 0;
bool blue = (channelMask & 4) != 0;
bool alpha = (channelMask & 8) != 0;
channelSum = string.Format("{0}{1}{2}{3}", red ? "Red" : "", green ? "Green" : "", blue ? "Blue" : "", alpha ? "Alpha" : "");
}
return string.Format("Unity_ChannelMask_{0}_{1}", channelSum, precision);
}
public sealed override void UpdateNodeAfterDeserialization()

RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
}
public TextureChannel channel;
private TextureChannel m_Channel = TextureChannel.Red;
private int m_ChannelMask = -1;
[ChannelEnumControl("Channel")]
public TextureChannel channel
[ChannelEnumMaskControl("Channels")]
public int channelMask
get { return m_Channel; }
get { return m_ChannelMask; }
if (m_Channel == value)
if (m_ChannelMask == value)
m_Channel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
m_ChannelMask = value;
Dirty(ModificationScope.Graph);
int channelCount = (int)SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType);
if ((int)channel >= channelCount)
channel = TextureChannel.Red;
int channelCount = SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType);
if (channelMask >= 1 << channelCount)
channelMask = -1;
return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<DynamicVectorMaterialSlot>(InputSlotId).concreteValueType), argIn,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<DynamicVectorMaterialSlot>(OutputSlotId).concreteValueType), argOut);
return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(), NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<DynamicVectorMaterialSlot>(InputSlotId).concreteValueType), argIn, NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<DynamicVectorMaterialSlot>(OutputSlotId).concreteValueType), argOut);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)

string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(string.Format("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, outputValue), true);
}

}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Out"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
switch (channel)
registry.ProvideFunction(GetFunctionName(), s =>
case TextureChannel.Green:
outputString.AddShaderChunk("Out = In.yyyy;", false);
break;
case TextureChannel.Blue:
outputString.AddShaderChunk("Out = In.zzzz;", false);
break;
case TextureChannel.Alpha:
outputString.AddShaderChunk("Out = In.wwww;", false);
break;
default:
outputString.AddShaderChunk("Out = In.xxxx;", false);
break;
}
int channelCount = SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType);
s.AppendLine(GetFunctionPrototype("In", "Out"));
using (s.BlockScope())
{
if(channelMask == 0)
s.AppendLine("Out = 0;");
else if(channelMask == -1)
s.AppendLine("Out = In;");
else
{
bool red = (channelMask & 1) != 0;
bool green = (channelMask & 2) != 0;
bool blue = (channelMask & 4) != 0;
bool alpha = (channelMask & 8) != 0;
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
switch (channelCount)
{
case 1:
s.AppendLine("Out = In.r;");
break;
case 2:
s.AppendLine(string.Format("Out = {0}2({1}, {2});", precision,
red ? "In.r": "0", green ? "In.g" : "0"));
break;
case 3:
s.AppendLine(string.Format("Out = {0}3({1}, {2}, {3});", precision,
red ? "In.r" : "0", green ? "In.g" : "0", blue ? "In.b" : "0"));
break;
case 4:
s.AppendLine(string.Format("Out = {0}4({1}, {2}, {3}, {4});", precision,
red ? "In.r" : "0", green ? "In.g" : "0", blue ? "In.b" : "0", alpha ? "In.a" : "0"));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
});
}
}
}

118
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalCreateNode.cs


public const int StrengthInputId = 4;
public const int OutputSlotId = 5;
const string kTextureInputName = "Texture";
const string kUVInputName = "UV";
const string kSamplerInputName = "Sampler";
const string kOffsetInputName = "Offset";
const string kStrengthInputName = "Strength";
const string kOutputSlotName = "Out";
const string k_TextureInputName = "Texture";
const string k_UVInputName = "UV";
const string k_SamplerInputName = "Sampler";
const string k_OffsetInputName = "Offset";
const string k_StrengthInputName = "Strength";
const string k_OutputSlotName = "Out";
public NormalCreateNode()
{

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, kTextureInputName, kTextureInputName));
AddSlot(new UVMaterialSlot(UVInputId, kUVInputName, kUVInputName, UVChannel.uv0));
AddSlot(new SamplerStateMaterialSlot(SamplerInputId, kSamplerInputName, kSamplerInputName, SlotType.Input));
AddSlot(new Vector1MaterialSlot(OffsetInputId, kOffsetInputName, kOffsetInputName, SlotType.Input, 0.5f));
AddSlot(new Vector1MaterialSlot(StrengthInputId, kStrengthInputName, kStrengthInputName, SlotType.Input, 8f));
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
AddSlot(new Texture2DInputMaterialSlot(TextureInputId, k_TextureInputName, k_TextureInputName));
AddSlot(new UVMaterialSlot(UVInputId, k_UVInputName, k_UVInputName, UVChannel.UV0));
AddSlot(new SamplerStateMaterialSlot(SamplerInputId, k_SamplerInputName, k_SamplerInputName, SlotType.Input));
AddSlot(new Vector1MaterialSlot(OffsetInputId, k_OffsetInputName, k_OffsetInputName, SlotType.Input, 0.5f));
AddSlot(new Vector1MaterialSlot(StrengthInputId, k_StrengthInputName, k_StrengthInputName, SlotType.Input, 8f));
AddSlot(new Vector3MaterialSlot(OutputSlotId, k_OutputSlotName, k_OutputSlotName, SlotType.Output, Vector3.zero));
string GetFunctionPrototype(string textureIn, string samplerIn, string uvIn, string offsetIn, string strengthIn, string argOut)
{
return string.Format("void {0} ({1} {2}, {3} {4}, {5} {6}, {7} {8}, {9} {10}, out {11} {12})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(TextureInputId).concreteValueType), textureIn,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(SamplerInputId).concreteValueType), samplerIn,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(UVInputId).concreteValueType), uvIn,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(OffsetInputId).concreteValueType), offsetIn,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(StrengthInputId).concreteValueType), strengthIn,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), argOut);
}
string textureValue = GetSlotValue(TextureInputId, generationMode);
string uvValue = GetSlotValue(UVInputId, generationMode);
string offsetValue = GetSlotValue(OffsetInputId, generationMode);
string strengthValue = GetSlotValue(StrengthInputId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
var textureValue = GetSlotValue(TextureInputId, generationMode);
var uvValue = GetSlotValue(UVInputId, generationMode);
var offsetValue = GetSlotValue(OffsetInputId, generationMode);
var strengthValue = GetSlotValue(StrengthInputId, generationMode);
var outputValue = GetSlotValue(OutputSlotId, generationMode);
var samplerSlot = FindInputSlot<MaterialSlot>(SamplerInputId);
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);

else
samplerValue = string.Format("sampler{0}", GetSlotValue(TextureInputId, generationMode));
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody(textureValue, samplerValue, uvValue, offsetValue, strengthValue, outputValue), true);
}
var sb = new ShaderStringBuilder();
sb.AppendLine("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId));
sb.AppendLine("{0}({1}, {2}, {3}, {4}, {5}, {6});", GetFunctionName(), textureValue, samplerValue, uvValue, offsetValue, strengthValue, outputValue);
string GetFunctionCallBody(string textureValue, string samplerValue, string uvValue, string offsetValue, string strengthValue, string outputValue)
{
return GetFunctionName() + " (" + textureValue + ", " + samplerValue + ", " + uvValue + ", " + offsetValue + ", " + strengthValue + ", " + outputValue + ");";
visitor.AddShaderChunk(sb.ToString(), false);
var sg = new ShaderGenerator();
sg.AddShaderChunk(GetFunctionPrototype("Texture", "Sampler", "UV", "Offset", "Strength", "Out"), false);
sg.AddShaderChunk("{", false);
sg.Indent();
var sb = new ShaderStringBuilder();
sb.AppendLine("void {0}({1} Texture, {2} Sampler, {3} UV, {4} Offset, {5} Strength, out {6} Out)", GetFunctionName(),
FindInputSlot<MaterialSlot>(TextureInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(SamplerInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(UVInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(OffsetInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(StrengthInputId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (sb.BlockScope())
{
sb.AppendLine("Offset = pow(Offset, 3) * 0.1;");
sb.AppendLine("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision);
sb.AppendLine("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision);
sg.AddShaderChunk("Offset = pow(Offset, 3) * 0.1;", false);
sg.AddShaderChunk(string.Format("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision), false);
sg.AddShaderChunk(string.Format("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision), false);
sb.AppendLine("{0} normalSample = Texture.Sample(Sampler, UV);", precision);
sb.AppendLine("{0} uSample = Texture.Sample(Sampler, offsetU);", precision);
sb.AppendLine("{0} vSample = Texture.Sample(Sampler, offsetV);", precision);
sb.AppendLine("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision);
sb.AppendLine("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision);
sb.AppendLine("Out = normalize(cross(va, vb));");
}
sg.AddShaderChunk(string.Format("{0} normalSample = Texture.Sample(Sampler, UV);", precision), false);
sg.AddShaderChunk(string.Format("{0} uSample = Texture.Sample(Sampler, offsetU);", precision), false);
sg.AddShaderChunk(string.Format("{0} vSample = Texture.Sample(Sampler, offsetV);", precision), false);
visitor.AddShaderChunk(sb.ToString(), true);
}
sg.AddShaderChunk(string.Format("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision), false);
sg.AddShaderChunk(string.Format("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision), false);
sg.AddShaderChunk("Out = normalize(cross(va, vb));", false);
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0}({1} Texture, {2} Sampler, {3} UV, {4} Offset, {5} Strength, out {6} Out)", GetFunctionName(),
FindInputSlot<MaterialSlot>(TextureInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(SamplerInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(UVInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(OffsetInputId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(StrengthInputId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Offset = pow(Offset, 3) * 0.1;");
s.AppendLine("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision);
s.AppendLine("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision);
sg.Deindent();
sg.AddShaderChunk("}", false);
s.AppendLine("{0} normalSample = Texture.Sample(Sampler, UV);", precision);
s.AppendLine("{0} uSample = Texture.Sample(Sampler, offsetU);", precision);
s.AppendLine("{0} vSample = Texture.Sample(Sampler, offsetV);", precision);
visitor.AddShaderChunk(sg.GetShaderString(0), true);
s.AppendLine("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision);
s.AppendLine("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision);
s.AppendLine("Out = normalize(cross(va, vb));");
}
});
}
public bool RequiresMeshUV(UVChannel channel)

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalStrengthNode.cs


return
@"
{
Out = {precision}3(In.rg * Strength, 1);
Out = {precision}3(In.rg * Strength, In.b);
}
";
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalUnpackNode.cs


using System.Reflection;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{

return
@"
{
Out = UnpackNormal(In);
Out = UnpackNormalmapRGorAG(In);
}
";
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Utility/ColorspaceConversion.cs


if (m_Conversion.Equals(value))
return;
m_Conversion = value;
if (onModified != null)
onModified(this, ModificationScope.Graph);
Dirty(ModificationScope.Graph);
}
}

103
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs


string GetFunctionName()
{
return "Unity_Flip_" + ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType);
return "Unity_Flip_" + NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType);
}
public sealed override void UpdateNodeAfterDeserialization()

RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
}
int channelCount { get { return (int)SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType); } }
int channelCount { get { return SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType); } }
[SerializeField]
private bool m_RedChannel;

if (m_RedChannel == value.isOn)
return;
m_RedChannel = value.isOn;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
Dirty(ModificationScope.Node);
}
}

if (m_GreenChannel == value.isOn)
return;
m_GreenChannel = value.isOn;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
Dirty(ModificationScope.Node);
}
}

if (m_BlueChannel == value.isOn)
return;
m_BlueChannel = value.isOn;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
Dirty(ModificationScope.Node);
}
}

if (m_AlphaChannel == value.isOn)
return;
m_AlphaChannel = value.isOn;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
Dirty(ModificationScope.Node);
string GetFunctionPrototype(string inArg, string flipArg, string outArg)
{
return string.Format("void {0} ({1} {2}, {3} {4}, out {5} {6})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), inArg,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), flipArg,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), outArg);
}
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
var sb = new ShaderStringBuilder();
var inputValue = GetSlotValue(InputSlotId, generationMode);
var outputValue = GetSlotValue(OutputSlotId, generationMode);
sb.AppendLine("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId));
visitor.AddShaderChunk(string.Format("{0} _{1}_Flip = {0} ({2}{3}{4}{5});",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
GetVariableNameForNode(),
Convert.ToInt32(m_RedChannel).ToString(),
channelCount > 1 ? string.Format(", {0}", (Convert.ToInt32(m_GreenChannel)).ToString()) : "",
channelCount > 2 ? string.Format(", {0}", (Convert.ToInt32(m_BlueChannel)).ToString()) : "",
channelCount > 3 ? string.Format(", {0}", (Convert.ToInt32(m_AlphaChannel)).ToString()) : ""), true);
sb.AppendLine("{0} _{1}_Flip = {0} ({2}",
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision),
GetVariableNameForNode(),
Convert.ToInt32(m_RedChannel));
if (channelCount > 1)
sb.Append(", {0}", Convert.ToInt32(m_GreenChannel));
if (channelCount > 2)
sb.Append(", {0}", Convert.ToInt32(m_BlueChannel));
if (channelCount > 3)
sb.Append(", {0}", Convert.ToInt32(m_AlphaChannel));
sb.Append(");");
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, string.Format("_{0}_Flip", GetVariableNameForNode()), outputValue), true);
}
sb.AppendLine("{0}({1}, _{2}_Flip, {3});", GetFunctionName(), inputValue, GetVariableNameForNode(), outputValue);
string GetFunctionCallBody(string inputValue, string flipValue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + flipValue + ", " + outputValue + ");";
visitor.AddShaderChunk(sb.ToString(), false);
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)

properties.Add(new PreviewProperty()
properties.Add(new PreviewProperty(PropertyType.Vector4)
propType = PropertyType.Vector4,
vector4Value = new Vector4(Convert.ToInt32(m_RedChannel), Convert.ToInt32(m_GreenChannel), Convert.ToInt32(m_BlueChannel), Convert.ToInt32(m_AlphaChannel)),
});
}

public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Flip", "Out"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk("Out = abs(Flip - In);", false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
var sb = new ShaderStringBuilder();
sb.AppendLine("void {0}({1} In, {2} Flip, out {3} Out)",
GetFunctionName(),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (sb.BlockScope())
{
sb.AppendLine("Out = (Flip * -2 + 1) * In;");
}
visitor.AddShaderChunk(sb.ToString(), true);
}
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0}({1} In, {2} Flip, out {3} Out)",
GetFunctionName(),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Out = (Flip * -2 + 1) * In;");
}
});
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SplitNode.cs


var numInputChannels = 0;
if (inputSlot != null)
{
numInputChannels = (int)SlotValueHelper.GetChannelCount(inputSlot.concreteValueType);
numInputChannels = SlotValueHelper.GetChannelCount(inputSlot.concreteValueType);
if (numInputChannels > 4)
numInputChannels = 0;

111
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SwizzleNode.cs


using System;
using System.Collections.Generic;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;

{
[Title("Channel", "Swizzle")]
public class SwizzleNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
public class SwizzleNode : AbstractMaterialNode, IGeneratesBodyCode
{
public SwizzleNode()
{

get { return true; }
}
string GetFunctionName()
{
return "Unity_Swizzle_" + precision + "_" + GuidEncoder.Encode(guid);
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero));

static Dictionary<TextureChannel, string> m_ComponentList = new Dictionary<TextureChannel, string>
static Dictionary<TextureChannel, string> s_ComponentList = new Dictionary<TextureChannel, string>
{TextureChannel.Red, ".r" },
{TextureChannel.Green, ".g" },
{TextureChannel.Blue, ".b" },
{TextureChannel.Alpha, ".a" },
{TextureChannel.Red, "r" },
{TextureChannel.Green, "g" },
{TextureChannel.Blue, "b" },
{TextureChannel.Alpha, "a" },
private TextureChannel m_RedChannel;
TextureChannel m_RedChannel;
[ChannelEnumControl("Red Out")]
public TextureChannel redChannel

return;
m_RedChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Node);
private TextureChannel m_GreenChannel;
TextureChannel m_GreenChannel;
[ChannelEnumControl("Green Out")]
public TextureChannel greenChannel

return;
m_GreenChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Node);
private TextureChannel m_BlueChannel;
TextureChannel m_BlueChannel;
[ChannelEnumControl("Blue Out")]
public TextureChannel blueChannel

return;
m_BlueChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Node);
private TextureChannel m_AlphaChannel;
TextureChannel m_AlphaChannel;
[ChannelEnumControl("Alpha Out")]
public TextureChannel alphaChannel

return;
m_AlphaChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Node);
int channelCount = (int)SlotValueHelper.GetChannelCount(FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType);
var channelCount = SlotValueHelper.GetChannelCount(FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType);
if ((int)redChannel >= channelCount)
redChannel = TextureChannel.Red;
if ((int)greenChannel >= channelCount)

alphaChannel = TextureChannel.Red;
}
string GetFunctionPrototype(string inArg, string outArg)
{
return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), inArg,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), outArg);
}
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, outputValue), true);
var outputSlotType = FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision);
var outputName = GetVariableNameForSlot(OutputSlotId);
var inputValue = GetSlotValue(InputSlotId, generationMode);
var inputValueType = FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType;
if (inputValueType == ConcreteSlotValueType.Vector1)
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", outputSlotType, outputName, inputValue), false);
else if (generationMode == GenerationMode.ForReals)
visitor.AddShaderChunk(string.Format("{0} {1} = {2}.{3}{4}{5}{6};", outputSlotType, outputName, inputValue, s_ComponentList[m_RedChannel], s_ComponentList[m_GreenChannel], s_ComponentList[m_BlueChannel], s_ComponentList[m_AlphaChannel]), false);
else
visitor.AddShaderChunk(string.Format("{0} {1} = {0}({3}[((int){2} >> 0) & 3], {3}[((int){2} >> 2) & 3], {3}[((int){2} >> 4) & 3], {3}[((int){2} >> 6) & 3]);",
outputSlotType,
outputName,
GetVariableNameForNode(), // Name of the uniform we encode swizzle values into
inputValue), false);
string GetFunctionCallBody(string inputValue, string outputValue)
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
return GetFunctionName() + " (" + inputValue + ", " + outputValue + ");";
base.CollectShaderProperties(properties, generationMode);
if (generationMode != GenerationMode.Preview)
return;
properties.AddShaderProperty(new Vector1ShaderProperty
{
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false
});
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
ValidateChannelCount();
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Out"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(string.Format("Out = {0} ({1}, {2}, {3}, {4});",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
kInputSlotName + m_ComponentList[m_RedChannel],
kInputSlotName + m_ComponentList[m_GreenChannel],
kInputSlotName + m_ComponentList[m_BlueChannel],
kInputSlotName + m_ComponentList[m_AlphaChannel]), false);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
base.CollectPreviewMaterialProperties(properties);
// Encode swizzle values into an integer
var value = ((int)redChannel) | ((int)greenChannel << 2) | ((int)blueChannel << 4) | ((int)alphaChannel << 6);
properties.Add(new PreviewProperty(PropertyType.Vector1)
{
name = GetVariableNameForNode(),
floatValue = value
});
}
}
}

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


UpdateNodeAfterDeserialization();
}
protected struct Boolean
{}
protected struct Vector1
{}

if (p.ParameterType.IsByRef)
t = p.ParameterType.GetElementType();
if (t == typeof(Boolean))
{
return SlotValueType.Boolean;
}
if (t == typeof(Vector1))
{
return SlotValueType.Vector1;

foreach (var par in method.GetParameters())
{
var attribute = GetSlotAttribute(par);
var name = GraphUtil.ConvertCamelCase(par.Name, true);
s = new ColorRGBAMaterialSlot(attribute.slotId, par.Name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, hidden: attribute.hidden);
s = new ColorRGBAMaterialSlot(attribute.slotId, name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, hidden: attribute.hidden);
s = new ColorRGBAMaterialSlot(attribute.slotId, par.Name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, hidden: attribute.hidden);
s = new ColorRGBAMaterialSlot(attribute.slotId, name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, hidden: attribute.hidden);
s = new ColorRGBMaterialSlot(attribute.slotId, par.Name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, hidden: attribute.hidden);
s = new ColorRGBMaterialSlot(attribute.slotId, name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, hidden: attribute.hidden);
par.Name,
name,
s = CreateBoundSlot(attribute.binding, attribute.slotId, par.Name, par.Name, attribute.hidden);
s = CreateBoundSlot(attribute.binding, attribute.slotId, name, par.Name, attribute.hidden);
slots.Add(s);
m_Slots.Add(attribute);

case Binding.TangentSpacePosition:
return new PositionMaterialSlot(slotId, displayName, shaderOutputName, CoordinateSpace.Tangent);
case Binding.MeshUV0:
return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.uv0);
return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.UV0);
return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.uv1);
return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.UV1);
return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.uv2);
return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.UV2);
return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.uv3);
return new UVMaterialSlot(slotId, displayName, shaderOutputName, UVChannel.UV3);
case Binding.ScreenPosition:
return new ScreenPositionMaterialSlot(slotId, displayName, shaderOutputName);
case Binding.ObjectSpaceViewDirection:

private string GetParamTypeName(MaterialSlot slot)
{
return ConvertConcreteSlotValueTypeToString(precision, slot.concreteValueType);
return NodeUtils.ConvertConcreteSlotValueTypeToString(precision, slot.concreteValueType);
return function.Name + "_" + (function.IsStatic ? string.Empty : GuidEncoder.Encode(guid) + "_") + precision;
return function.Name + "_" + (function.IsStatic ? string.Empty : GuidEncoder.Encode(guid) + "_") + precision + (this.GetSlots<DynamicVectorMaterialSlot>().Select(s => NodeUtils.GetSlotDimension(s.concreteValueType)).FirstOrDefault() ?? "");
}
private string GetFunctionHeader()

foreach (var slot in s_TempSlots)
{
var toReplace = string.Format("{{slot{0}dimension}}", slot.id);
var replacement = GetSlotDimension(slot.concreteValueType);
var replacement = NodeUtils.GetSlotDimension(slot.concreteValueType);
public virtual void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public virtual void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
string function = GetFunctionHeader() + GetFunctionBody(GetFunctionToConvert());
visitor.AddShaderChunk(function, true);
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine(GetFunctionHeader());
var functionBody = GetFunctionBody(GetFunctionToConvert());
var lines = functionBody.Trim('\r', '\n', '\t', ' ');
s.AppendLines(lines);
});
}
private static SlotAttribute GetSlotAttribute([NotNull] ParameterInfo info)

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/GeometryNode.cs


return;
m_Space = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

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


using System;
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;

{
public enum ColorMode
{
Default,
HDR
}
[SerializeField]
private Color m_Color;
public const int OutputSlotId = 0;
private const string kOutputSlotName = "Out";

UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
[SerializeField]
Color m_Color = new Color(UnityEngine.Color.clear, ColorMode.Default);
[Serializable]
public struct Color
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
public UnityEngine.Color color;
public ColorMode mode;
public Color(UnityEngine.Color color, ColorMode mode)
{
this.color = color;
this.mode = mode;
}
}
[ColorControl("")]

set
{
if (m_Color == value)
if ((value.color == m_Color.color) && (value.mode == m_Color.mode))
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
Dirty(ModificationScope.Node);
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{

{
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,
value = color,
HDR = false
value = color.color,
colorMode = color.mode
});
}

return;
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForNode() + " = " + precision + "4 (" + color.r + ", " + color.g + ", " + color.b + ", " + color.a + ");", true);
visitor.AddShaderChunk(string.Format(
@"{0}4 {1} = IsGammaSpace() ? {0}4({2}, {3}, {4}, {5}) : {0}4(SRGBToLinear({0}3({2}, {3}, {4})), {5});"
, precision
, GetVariableNameForNode()
, color.color.r
, color.color.g
, color.color.b
, color.color.a), true);
}
public override string GetVariableNameForSlot(int slotId)

public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty
properties.Add(new PreviewProperty(PropertyType.Color)
propType = PropertyType.Color,
colorValue = color
colorValue = color.color
var prop = new ColorShaderProperty();
prop.value = color;
return prop;
return new ColorShaderProperty { value = color.color, colorMode = color.mode };
}
public int outputSlotId { get { return OutputSlotId; } }

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


return;
m_constant = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Basic/TimeNode.cs


public class TimeNode : AbstractMaterialNode, IMayRequireTime
{
private const string kOutputSlotName = "Time";
private const string kOutputSlot1Name = "SinTime";
private const string kOutputSlot2Name = "CosTime";
private const string kOutputSlot3Name = "DeltaTime";
private const string kOutputSlot4Name = "SmoothDelta";
private const string kOutputSlot1Name = "Sine Time";
private const string kOutputSlot2Name = "Cosine Time";
private const string kOutputSlot3Name = "Delta Time";
private const string kOutputSlot4Name = "Smooth Delta";
public const int OutputSlotId = 0;
public const int OutputSlot1Id = 1;

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


public const int OutputSlotId = 0;
private const string kOutputSlotName = "Out";
/*[SerializeField]
private FloatPropertyChunk.FloatType m_floatType;*/
// [SerializeField]
//private Vector3 m_rangeValues = new Vector3(0f, 1f, 2f);
public Vector1Node()
{
name = "Vector 1";

m_Value = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
/* public FloatPropertyChunk.FloatType floatType
{
get { return m_floatType; }
set
{
if (m_floatType == value)
return;
m_floatType = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
}
}*/
/* public Vector3 rangeValues
{
get { return m_rangeValues; }
set
{
if (m_rangeValues == value)
return;
m_rangeValues = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
}
}
*/
properties.AddShaderProperty(new FloatShaderProperty()
properties.AddShaderProperty(new Vector1ShaderProperty()
{
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,

if (generationMode.IsPreview())
return;
visitor.AddShaderChunk(precision + " " + GetVariableNameForNode() + " = " + m_Value + ";", true);
visitor.AddShaderChunk(precision + " " + GetVariableNameForNode() + " = " + NodeUtils.FloatToShaderValue(m_Value) + ";", true);
}
public override string GetVariableNameForSlot(int slotId)

public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty()
properties.Add(new PreviewProperty(PropertyType.Vector1)
propType = PropertyType.Float,
floatValue = m_Value
});
}

var prop = new FloatShaderProperty();
prop.value = value;
return prop;
return new Vector1ShaderProperty { value = value };
}
public int outputSlotId { get { return OutputSlotId; } }

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


m_Value = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
}
}

if (generationMode.IsPreview())
return;
visitor.AddShaderChunk(precision + "2 " + GetVariableNameForNode() + " = " + precision + "2" + m_Value + ";", true);
visitor.AddShaderChunk(string.Format("{0}2 {1} = {0}2({2},{3});", precision, GetVariableNameForNode(), NodeUtils.FloatToShaderValue(m_Value.x), NodeUtils.FloatToShaderValue(m_Value.y)), true);
}
public override string GetVariableNameForSlot(int slotId)

public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty()
properties.Add(new PreviewProperty(PropertyType.Vector2)
propType = PropertyType.Vector2,
vector4Value = m_Value
});
}

var prop = new Vector2ShaderProperty();
prop.value = value;
return prop;
return new Vector2ShaderProperty { value = value };
}
public int outputSlotId { get { return OutputSlotId; } }

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


m_Value = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
}
}

if (generationMode.IsPreview())
return;
visitor.AddShaderChunk(precision + "3 " + GetVariableNameForNode() + " = " + precision + "3" + m_Value + ";", true);
var s = string.Format("{0}3 {1} = {0}3({2},{3},{4});",
precision,
GetVariableNameForNode(),
NodeUtils.FloatToShaderValue(m_Value.x),
NodeUtils.FloatToShaderValue(m_Value.y),
NodeUtils.FloatToShaderValue(m_Value.z));
visitor.AddShaderChunk(s, true);
}
public override string GetVariableNameForSlot(int slotId)

public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty()
properties.Add(new PreviewProperty(PropertyType.Vector3)
propType = PropertyType.Vector3,
vector4Value = m_Value
});
}

var prop = new Vector3ShaderProperty();
prop.value = value;
return prop;
return new Vector3ShaderProperty { value = value };
}
public int outputSlotId { get { return OutputSlotId; } }

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


m_Value = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
Dirty(ModificationScope.Node);
}
}

if (generationMode.IsPreview())
return;
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForNode() + " = " + precision + "4" + m_Value + ";", true);
var s = string.Format("{0}4 {1} = {0}4({2},{3},{4},{5});",
precision,
GetVariableNameForNode(),
NodeUtils.FloatToShaderValue(m_Value.x),
NodeUtils.FloatToShaderValue(m_Value.y),
NodeUtils.FloatToShaderValue(m_Value.z),
NodeUtils.FloatToShaderValue(m_Value.w));
visitor.AddShaderChunk(s, true);
}
public override string GetVariableNameForSlot(int slotId)

public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty()
properties.Add(new PreviewProperty(PropertyType.Vector4)
propType = PropertyType.Vector4,
vector4Value = m_Value
});
}

var prop = new Vector4ShaderProperty();
prop.value = value;
return prop;
return new Vector4ShaderProperty { value = value };
}
public int outputSlotId { get { return OutputSlotId; } }

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


public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.BiTangent);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.BiTangent));
}
public NeededCoordinateSpace RequiresBitangent()

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/NormalVectorNode.cs


namespace UnityEditor.ShaderGraph
{
[FormerName("UnityEngine.MaterialGraph.NormalNode")]
[Title("Input", "Geometry", "Normal Vector")]
public class NormalVectorNode : GeometryNode, IMayRequireNormal
{

public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.Normal);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Normal));
}
public NeededCoordinateSpace RequiresNormal()

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


namespace UnityEditor.ShaderGraph
{
[FormerName("UnityEngine.MaterialGraph.WorldPosNode")]
[Title("Input", "Geometry", "Position")]
public class PositionNode : GeometryNode, IMayRequirePosition
{

public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.Position);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Position));
}
public NeededCoordinateSpace RequiresPosition()

17
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ScreenPositionNode.cs


[SerializeField]
private ScreenSpaceType m_ScreenSpaceType = ScreenSpaceType.Default;
[EnumControl("")]
[EnumControl("Mode")]
public ScreenSpaceType screenSpaceType
{
get { return m_ScreenSpaceType; }

return;
m_ScreenSpaceType = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

switch (m_ScreenSpaceType)
{
case ScreenSpaceType.Raw:
visitor.AddShaderChunk(string.Format("{0}4 {1} = {2};", precision, GetVariableNameForSlot(kOutputSlotId),
visitor.AddShaderChunk(string.Format("{0}4 {1} = IN.{2};", precision, GetVariableNameForSlot(kOutputSlotId),
"float4((" + ShaderGeneratorNames.ScreenPosition + ".xy / " + ShaderGeneratorNames.ScreenPosition + ".w) * 2 - 1, 0, 0)"), true);
string.Format("float4((IN.{0}.xy / IN.{0}.w) * 2 - 1, 0, 0)", ShaderGeneratorNames.ScreenPosition)), true);
"float4((" + ShaderGeneratorNames.ScreenPosition + ".xy / " + ShaderGeneratorNames.ScreenPosition + ".w) * 2 - 1, 0, 0)"), true);
string.Format("float4((IN.{0}.xy / IN.{0}.w) * 2 - 1, 0, 0)", ShaderGeneratorNames.ScreenPosition)), true);
"float4(" + ShaderGeneratorNames.ScreenPosition + ".x * _ScreenParams.x / _ScreenParams.y, " + ShaderGeneratorNames.ScreenPosition + ".y, 0, 0)"), true);
string.Format("frac(float4({0}.x * _ScreenParams.x / _ScreenParams.y, {0}.y, 0, 0))", GetVariableNameForSlot(kOutputSlotId))), true);
"float4(" + ShaderGeneratorNames.ScreenPosition + ".xy / " + ShaderGeneratorNames.ScreenPosition + ".w, 0, 0)"), true);
string.Format("float4(IN.{0}.xy / IN.{0}.w, 0, 0)", ShaderGeneratorNames.ScreenPosition)), true);
break;
}
}

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


public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.Tangent);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Tangent));
}
public NeededCoordinateSpace RequiresTangent()

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


[SerializeField]
private UVChannel m_OutputChannel;
[EnumControl("")]
[EnumControl("Channel")]
public UVChannel uvChannel
{
get { return m_OutputChannel; }

return;
m_OutputChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(OutputSlotId) + " = " + m_OutputChannel.GetUVName() + ";", true);
visitor.AddShaderChunk(string.Format("{0}4 {1} = IN.{2};", precision, GetVariableNameForSlot(OutputSlotId), m_OutputChannel.GetUVName()), true);
}
public bool RequiresMeshUV(UVChannel channel)

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


public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.VertexColor;
return string.Format("IN.{0}", ShaderGeneratorNames.VertexColor);
}
public bool RequiresVertexColor()

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


namespace UnityEditor.ShaderGraph
{
[FormerName("UnityEngine.MaterialGraph.ViewDirectionNode")]
[Title("Input", "Geometry", "View Direction")]
public class ViewDirectionNode : GeometryNode, IMayRequireViewDirection
{

public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.ViewDirection);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.ViewDirection));
}
public NeededCoordinateSpace RequiresViewDirection()

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


if (value == row)
return;
row = value;
if (onModified != null)
onModified(this, ModificationScope.Graph);
Dirty(ModificationScope.Graph);
}
public Matrix2Node()

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


if (value == row)
return;
row = value;
if (onModified != null)
onModified(this, ModificationScope.Graph);
Dirty(ModificationScope.Graph);
}
public Matrix3Node()

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


if (value == row)
return;
row = value;
if (onModified != null)
onModified(this, ModificationScope.Graph);
Dirty(ModificationScope.Graph);
}
public Matrix4Node()

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Matrix/TransformationMatrixNode.cs


using System.ComponentModel;
using UnityEditor.Graphing;
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Drawing.Controls;

{TransformationMatrixType.ViewProjection, "UNITY_MATRIX_VP"},
{TransformationMatrixType.TransposeModelView, "UNITY_MATRIX_T_MV"},
{TransformationMatrixType.InverseTransposeModelView, "UNITY_MATRIX_IT_MV"},
{TransformationMatrixType.ObjectToWorld, "unity_ObjectToWorld"},
{TransformationMatrixType.WorldToObject, "unity_WorldToObject"},
{TransformationMatrixType.ObjectToWorld, "UNITY_MATRIX_M"},
{TransformationMatrixType.WorldToObject, "UNITY_MATRIX_I_M"},
};
[SerializeField]

return;
m_matrix = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
Dirty(ModificationScope.Graph);
}
}

37
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/PropertyNode.cs


if (property == null)
return;
if (property is FloatShaderProperty)
if (property is Vector1ShaderProperty)
AddSlot(new Vector1MaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(OutputSlotId, property.displayName, "Out", SlotType.Output, 0));
AddSlot(new Vector2MaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero));
AddSlot(new Vector2MaterialSlot(OutputSlotId, property.displayName, "Out", SlotType.Output, Vector4.zero));
AddSlot(new Vector3MaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero));
AddSlot(new Vector3MaterialSlot(OutputSlotId, property.displayName, "Out", SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlotId, property.displayName, "Out", SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlotId, property.displayName, "Out", SlotType.Output, Vector4.zero));
AddSlot(new Texture2DMaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output));
AddSlot(new Texture2DMaterialSlot(OutputSlotId, property.displayName, "Out", SlotType.Output));
AddSlot(new CubemapMaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output));
AddSlot(new CubemapMaterialSlot(OutputSlotId, property.displayName, "Out", SlotType.Output));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
else if (property is BooleanShaderProperty)
{
AddSlot(new BooleanMaterialSlot(OutputSlotId, property.displayName, "Out", SlotType.Output, false));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
}

if (property == null)
return;
if (property is FloatShaderProperty)
if (property is Vector1ShaderProperty)
{
var result = string.Format("{0} {1} = {2};"
, precision

, property.referenceName);
visitor.AddShaderChunk(result, true);
}
else if (property is BooleanShaderProperty)
{
var result = string.Format("{0} {1} = {2};"
, precision
, GetVariableNameForSlot(OutputSlotId)
, property.referenceName);
visitor.AddShaderChunk(result, true);
}
[PropertyControl]
public Guid propertyGuid
{
get { return m_PropertyGuid; }

UpdateNode();
if (onModified != null)
{
onModified(this, ModificationScope.Topological);
}
Dirty(ModificationScope.Topological);
}
}

23
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/AmbientNode.cs


[Title("Input", "Scene", "Ambient")]
public class AmbientNode : AbstractMaterialNode
{
const string kOutputSlotName = "Color";
const string kOutputSlot1Name = "Sky";
const string kOutputSlot2Name = "Equator";
const string kOutputSlot3Name = "Ground";
const string kOutputSlotName = "Color/Sky";
const string kOutputSlot1Name = "Equator";
const string kOutputSlot2Name = "Ground";
public const int OutputSlot3Id = 3;
public AmbientNode()
{

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlot1Id, kOutputSlot1Name, kOutputSlot1Name, SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlot2Id, kOutputSlot2Name, kOutputSlot2Name, SlotType.Output, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlot3Id, kOutputSlot3Name, kOutputSlot3Name, SlotType.Output, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, OutputSlot1Id, OutputSlot2Id, OutputSlot3Id });
AddSlot(new ColorRGBMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
AddSlot(new ColorRGBMaterialSlot(OutputSlot1Id, kOutputSlot1Name, kOutputSlot1Name, SlotType.Output, Vector4.zero));
AddSlot(new ColorRGBMaterialSlot(OutputSlot2Id, kOutputSlot2Name, kOutputSlot2Name, SlotType.Output, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { OutputSlotId, OutputSlot1Id, OutputSlot2Id });
}
public override string GetVariableNameForSlot(int slotId)

case OutputSlot1Id:
return "unity_AmbientSky";
return "unity_AmbientEquator";
return "unity_AmbientEquator";
case OutputSlot3Id:
return "UNITY_LIGHTMODEL_AMBIENT";
return "unity_AmbientSky";
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/CameraNode.cs


const string kOutputSlot2Name = "Orthographic";
const string kOutputSlot3Name = "Near Plane";
const string kOutputSlot4Name = "Far Plane";
const string kOutputSlot5Name = "Sign";
const string kOutputSlot5Name = "Z Buffer Sign";
const string kOutputSlot6Name = "Width";
const string kOutputSlot7Name = "Height";

102
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/FogNode.cs


const int OutputSlotId = 0;
const int OutputSlot1Id = 1;
const string kOutputSlotName = "Color";
const string kOutputSlot1Name = "Density";
const string k_OutputSlotName = "Color";
const string k_OutputSlot1Name = "Density";
public override bool hasPreview
{

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
AddSlot(new Vector1MaterialSlot(OutputSlot1Id, kOutputSlot1Name, kOutputSlot1Name, SlotType.Output, 0));
AddSlot(new Vector4MaterialSlot(OutputSlotId, k_OutputSlotName, k_OutputSlotName, SlotType.Output, Vector4.zero));
AddSlot(new Vector1MaterialSlot(OutputSlot1Id, k_OutputSlot1Name, k_OutputSlot1Name, SlotType.Output, 0));
string GetFunctionPrototype(string argIn, string argOut, string argOut2)
{
return string.Format("void {0} ({1}3 {2}, out {3} {4}, out {5} {6})", GetFunctionName(), precision, argIn,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), argOut,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlot1Id).concreteValueType), argOut2);
}
string colorValue = GetSlotValue(OutputSlotId, generationMode);
string densityValue = GetSlotValue(OutputSlot1Id, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlot1Id).concreteValueType), GetVariableNameForSlot(OutputSlot1Id)), true);
string objectSpacePosition = string.Format("IN.{0}", CoordinateSpace.Object.ToVariableName(InterpolatorType.Position));
visitor.AddShaderChunk(GetFunctionCallBody(objectSpacePosition, colorValue, densityValue), true);
visitor.AddShaderChunk(string.Format("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId)), false);
visitor.AddShaderChunk(string.Format("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlot1Id).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlot1Id)), false);
visitor.AddShaderChunk(string.Format("{0}(IN.{1}, {2}, {3});", GetFunctionName(),
CoordinateSpace.Object.ToVariableName(InterpolatorType.Position),
GetVariableNameForSlot(OutputSlotId), GetVariableNameForSlot(OutputSlot1Id)), false);
string GetFunctionCallBody(string objectSpaceValue, string outputValue, string output1Value)
{
return GetFunctionName() + " (" + objectSpaceValue + ", " + outputValue + ", " + output1Value + ");";
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
var sg = new ShaderGenerator();
sg.AddShaderChunk(GetFunctionPrototype("ObjectSpacePosition", "Color", "Density"), false);
sg.AddShaderChunk("{", false);
sg.Indent();
sg.AddShaderChunk("Color = unity_FogColor;", false);
sg.AddShaderChunk(string.Format("{0} clipZ_01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(UnityObjectToClipPos(ObjectSpacePosition).z);", precision), false);
sg.AddShaderChunk("#if defined(FOG_LINEAR)", false);
sg.Indent();
sg.AddShaderChunk(string.Format("{0} fogFactor = saturate(clipZ_01 * unity_FogParams.z + unity_FogParams.w);", precision), false);
sg.AddShaderChunk("Density = fogFactor;", false);
sg.Deindent();
sg.AddShaderChunk("#elif defined(FOG_EXP)", false);
sg.Indent();
sg.AddShaderChunk(string.Format("{0} fogFactor = unity_FogParams.y * clipZ_01;", precision), false);
sg.AddShaderChunk("Density = {2}(saturate(exp2(-fogFactor)));", false);
sg.Deindent();
sg.AddShaderChunk("#elif defined(FOG_EXP2)", false);
sg.Indent();
sg.AddShaderChunk(string.Format("{0} fogFactor = unity_FogParams.x * clipZ_01;", precision), false);
sg.AddShaderChunk("Density = {2}(saturate(exp2(-fogFactor*fogFactor)));", false);
sg.Deindent();
sg.AddShaderChunk("#else", false);
sg.Indent();
sg.AddShaderChunk("Density = 0.0h;", false);
sg.Deindent();
sg.AddShaderChunk("#endif", false);
registry.ProvideFunction(GetFunctionName(), s =>
{
s.AppendLine("void {0}({1}3 ObjectSpacePosition, out {2} Color, out {3} Density)",
GetFunctionName(),
precision,
FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision),
FindOutputSlot<MaterialSlot>(OutputSlot1Id).concreteValueType.ToString(precision));
using (s.BlockScope())
{
s.AppendLine("Color = unity_FogColor;");
sg.Deindent();
sg.AddShaderChunk("}", false);
visitor.AddShaderChunk(sg.GetShaderString(0), true);
s.AppendLine("{0} clipZ_01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(mul(GetWorldToHClipMatrix(), mul(GetObjectToWorldMatrix(), ObjectSpacePosition)).z);", precision);
s.AppendLine("#if defined(FOG_LINEAR)");
using (s.IndentScope())
{
s.AppendLine("{0} fogFactor = saturate(clipZ_01 * unity_FogParams.z + unity_FogParams.w);", precision);
s.AppendLine("Density = fogFactor;");
}
s.AppendLine("#elif defined(FOG_EXP)");
using (s.IndentScope())
{
s.AppendLine("{0} fogFactor = unity_FogParams.y * clipZ_01;", precision);
s.AppendLine("Density = saturate(exp2(-fogFactor));");
}
s.AppendLine("#elif defined(FOG_EXP2)");
using (s.IndentScope())
{
s.AppendLine("{0} fogFactor = unity_FogParams.x * clipZ_01;", precision);
s.AppendLine("Density = saturate(exp2(-fogFactor*fogFactor));");
}
s.AppendLine("#else");
using (s.IndentScope())
{
s.AppendLine("Density = 0.0h;");
}
s.AppendLine("#endif");
}
});
}
public NeededCoordinateSpace RequiresPosition()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Scene/ReflectionProbeNode.cs


@"
{
{precision}3 reflectVec = reflect(-ViewDir, Normal);
Out = DecodeHDR(UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflectVec, LOD), unity_SpecCube0_HDR);
Out = DecodeHDREnvironment(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVec, LOD), unity_SpecCube0_HDR);
}
";
}

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


if (m_Cubemap.cubemap == value)
return;
m_Cubemap.cubemap = value;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
Dirty(ModificationScope.Node);
}
}

public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
properties.Add(new PreviewProperty
properties.Add(new PreviewProperty(PropertyType.Cubemap)
propType = PropertyType.Cubemap,
cubemapValue = cubemap
});
}

var prop = new CubemapShaderProperty();
prop.value = m_Cubemap;
var prop = new CubemapShaderProperty { value = m_Cubemap };
if (cubemap != null)
prop.displayName = cubemap.name;
return prop;

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

正在加载...
取消
保存