浏览代码

Merge branch 'exposed-prop-subgraph'

# Conflicts:
#	MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs
/main
Tim Cooper 7 年前
当前提交
f2cae710
共有 74 个文件被更改,包括 1241 次插入1572 次删除
  1. 7
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/NodeUtils.cs
  2. 1
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableGraph.cs
  3. 2
      MaterialGraphProject/Assets/NewNodes/Keep/SamplerStateNode.cs
  4. 2
      MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPBR.shader
  5. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateRemapGraph.cs
  6. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateShaderSubGraph.cs
  7. 105
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/AbstractMaterialGraphEditWindow.cs
  8. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs
  9. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs
  10. 61
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/Nodes/RemapMasterNodePresenter.cs
  11. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/PropertyNodePresenter.cs
  12. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewSystem.cs
  13. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/ShaderGraphImporter.cs
  14. 19
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightSubshaderPBR.template
  15. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightSubshaderUnlit.template
  16. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/Graphs/Add-Sub-Graph.ShaderSubGraph.meta
  17. 139
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs
  18. 18
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractShaderProperty.cs
  19. 13
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/ColorShaderProperty.cs
  20. 13
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/FloatShaderProperty.cs
  21. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/IShaderProperty.cs
  22. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraph.cs
  23. 26
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialSlot.cs
  24. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/SamplerStateShaderProperty.cs
  25. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/TextureShaderProperty.cs
  26. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/Vector2ShaderProperty.cs
  27. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/Vector3ShaderProperty.cs
  28. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/Vector4ShaderProperty.cs
  29. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/VectorShaderProperty.cs
  30. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/IGenerateProperties.cs
  31. 166
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/AbstractLightweightMasterNode.cs
  32. 39
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/AbstractLightweightPBRMasterNode.cs
  33. 20
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/LightweightMetallicMasterNode.cs
  34. 33
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/LightweightSpecularMasterNode.cs
  35. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/LightweightUnlitMasterNode.cs
  36. 15
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs
  37. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/ColorNode.cs
  38. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/ViewDirectionNode.cs
  39. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Vector/Vector1Node.cs
  40. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Vector/Vector2Node.cs
  41. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Vector/Vector3Node.cs
  42. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Vector/Vector4Node.cs
  43. 189
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MasterNode.cs
  44. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PropertyNode.cs
  45. 124
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapGraph.cs
  46. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MaterialSubGraphAsset.cs
  47. 106
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraph.cs
  48. 302
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs
  49. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphOutputNode.cs
  50. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/PropertyCollector.cs
  51. 263
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs
  52. 23
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporter.cs
  53. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporter.cs.meta
  54. 41
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporterEditor.cs
  55. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporterEditor.cs.meta
  56. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/IMasterNode.cs
  57. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/IMasterNode.cs.meta
  58. 15
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapGraphAsset.cs
  59. 65
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraph.cs
  60. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraph.cs.meta
  61. 229
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphNode.cs
  62. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphNode.cs.meta
  63. 98
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MasterRemapNode.cs
  64. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MasterRemapNode.cs.meta
  65. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeInspectors/SubgraphInputNodeInspector.cs.meta
  66. 85
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeInspectors/SubgraphInputNodeInspector.cs
  67. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapInputNode.cs.meta
  68. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/RemapMasterNode.cs.meta
  69. 93
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapInputNode.cs
  70. 22
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MaterialRemapAsset.cs
  71. 140
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/RemapMasterNode.cs
  72. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs.meta
  73. 80
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs
  74. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapGraphAsset.cs.meta

7
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/NodeUtils.cs


if (nodeList.Contains(fromNode))
continue;
var remapper = fromNode as INodeGroupRemapper;
if (remapper != null)
{
remapper.DepthFirstCollectNodesFromNodeSlotList(nodeList, includeSelf);
continue;
}
foreach (var slot in fromNode.GetInputSlots<ISlot>())
{
if (slotIds != null && !slotIds.Contains(slot.id))

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


foreach (var edge in m_Edges)
AddEdgeToNodeEdges(edge);
OnEnable();
ValidateGraph();
}

2
MaterialGraphProject/Assets/NewNodes/Keep/SamplerStateNode.cs


{
properties.AddShaderProperty(new SamplerStateShaderProperty()
{
name = GetVariableNameForNode(),
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,
value = new TextureSamplerState()
{

2
MaterialGraphProject/Assets/SRP/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPBR.shader


#ifndef _EMISSION
s.Emission = 0;
#else
s.Emission = LIGHTWEIGHT_GAMMA_TO_LINEAR(tex2D(_EmissionMap, i.uv01.xy).rgb) * _EmissionColor.rgb;
s.Emission = LIGHTWEIGHT_GAMMA_TO_LINEAR(tex2D(_EmissionMap, i.meshUV0.xy).rgb) * _EmissionColor.rgb;
#endif
// Alpha
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateRemapGraph.cs


{
public class CreateRemapGraph : EndNameEditAction
{
[MenuItem("Assets/Create/Remap Graph", false, 209)]
[MenuItem("Assets/Create/Shader Remap Graph", false, 209)]
"New Remap-Graph.remapGraph", null, null);
"New Remap-Graph.ShaderRemapGraph", null, null);
/* var graph = CreateInstance<MaterialRemapAsset>();
graph.name = Path.GetFileName(pathName);
AssetDatabase.CreateAsset(graph, pathName);*/
var graph = new MasterRemapGraph();
File.WriteAllText(pathName, EditorJsonUtility.ToJson(graph));
AssetDatabase.Refresh();
}
}
}

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateShaderSubGraph.cs


public override void Action(int instanceId, string pathName, string resourceFile)
{
var graph = new SubGraph();
graph.AddNode(new SubGraphInputNode());
graph.AddNode(new SubGraphOutputNode());
File.WriteAllText(pathName, EditorJsonUtility.ToJson(graph));
AssetDatabase.Refresh();

105
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/AbstractMaterialGraphEditWindow.cs


}
}
public class MasterReampGraphEditWindow : AbstractMaterialGraphEditWindow<MasterRemapGraph>
{
public override AbstractMaterialGraph GetMaterialGraph()
{
return inMemoryAsset;
}
}
public abstract class AbstractMaterialGraphEditWindow<TGraphType> : HelperMaterialGraphEditWindow where TGraphType : AbstractMaterialGraph
{
public static bool allowAlwaysRepaint = true;

UpdateShaderGraphOnDisk(path);
if (typeof(TGraphType) == typeof(SubGraph))
UpdateShaderSubGraphOnDisk(path);
UpdateAbstractSubgraphOnDisk<SubGraph>(path);
if (typeof(TGraphType) == typeof(MasterRemapGraph))
UpdateAbstractSubgraphOnDisk<MasterRemapGraph>(path);
}
}

return;
var graphPresenter = graphEditorView.presenter.graphPresenter;
var selected = graphPresenter.elements.Where(e => e.selected).ToArray();
var deserialized = MaterialGraphPresenter.DeserializeCopyBuffer(JsonUtility.ToJson(MaterialGraphPresenter.CreateCopyPasteGraph(selected)));
var selected = graphPresenter.elements.Where(e => e.selected);
var filtered = new List<GraphElementPresenter>();
foreach (var presenter in selected)
{
var nodePresenter = presenter as MaterialNodePresenter;
if (nodePresenter != null)
{
if (!(nodePresenter.node is PropertyNode))
filtered.Add(nodePresenter);
}
else
{
filtered.Add(presenter);
}
}
var deserialized = MaterialGraphPresenter.DeserializeCopyBuffer(JsonUtility.ToJson(MaterialGraphPresenter.CreateCopyPasteGraph(filtered)));
graph.AddNode(new SubGraphInputNode());
graph.AddNode(new SubGraphOutputNode());
var nodeGuidMap = new Dictionary<Guid, Guid>();

}
// remap outputs to the subgraph
var inputEdgeNeedsRemap = new List<IEdge>();
var outputEdgeNeedsRemap = new List<IEdge>();
var onlyInputInternallyConnected = new List<IEdge>();
var onlyOutputInternallyConnected = new List<IEdge>();
foreach (var edge in deserialized.edges)
{
var outputSlot = edge.outputSlot;

// one edge needs to go to outside world
else if (outputRemapExists)
{
inputEdgeNeedsRemap.Add(edge);
onlyOutputInternallyConnected.Add(edge);
outputEdgeNeedsRemap.Add(edge);
onlyInputInternallyConnected.Add(edge);
// we do a grouping here as the same output can
// point to multiple inputs
var uniqueOutputs = outputEdgeNeedsRemap.GroupBy(edge => edge.outputSlot);
var uniqueInputEdges = onlyOutputInternallyConnected.GroupBy(
edge => edge.outputSlot,
edge => edge,
(key, edges) => new {slotRef = key, edges = edges.ToList()});
foreach (var group in uniqueOutputs)
foreach (var group in uniqueInputEdges)
var inputNode = graph.inputNode;
var slotId = inputNode.AddSlot();
var inputNode = new PropertyNode();
var outputSlotRef = new SlotReference(inputNode.guid, slotId);
var sr = group.slotRef;
var fromNode = graphPresenter.graph.GetNodeFromGuid(sr.nodeGuid);
var fromSlot = fromNode.FindOutputSlot<MaterialSlot>(sr.slotId);
foreach (var edge in group)
switch (fromSlot.concreteValueType)
var newEdge = graph.Connect(outputSlotRef, new SlotReference(nodeGuidMap[edge.inputSlot.nodeGuid], edge.inputSlot.slotId));
inputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));
case ConcreteSlotValueType.SamplerState:
break;
case ConcreteSlotValueType.Matrix4:
break;
case ConcreteSlotValueType.Matrix3:
break;
case ConcreteSlotValueType.Matrix2:
break;
case ConcreteSlotValueType.Texture2D:
break;
case ConcreteSlotValueType.Vector4:
break;
case ConcreteSlotValueType.Vector3:
break;
case ConcreteSlotValueType.Vector2:
break;
case ConcreteSlotValueType.Vector1:
break;
case ConcreteSlotValueType.Error:
break;
default:
throw new ArgumentOutOfRangeException();
var uniqueInputs = inputEdgeNeedsRemap.GroupBy(edge => edge.inputSlot);
var uniqueOutputEdges = onlyInputInternallyConnected.GroupBy(
edge => edge.inputSlot,
edge => edge,
(key, edges) => new {slot = key, edges = edges.ToList()});
foreach (var group in uniqueInputs)
foreach (var group in uniqueOutputEdges)
{
var outputNode = graph.outputNode;
var slotId = outputNode.AddSlot();

foreach (var edge in group)
foreach (var edge in group.edges)
{
var newEdge = graph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef);
outputsNeedingConnection.Add(new KeyValuePair<IEdge, IEdge>(edge, newEdge));

graphPresenter.AddNode(subGraphNode);
subGraphNode.subGraphAsset = subGraph;
foreach (var edgeMap in inputsNeedingConnection)
/* foreach (var edgeMap in inputsNeedingConnection)
}
}*/
foreach (var edgeMap in outputsNeedingConnection)
{

graphPresenter.RemoveElements(toDelete, new List<GraphEdgePresenter>());
}
private void UpdateShaderSubGraphOnDisk(string path)
private void UpdateAbstractSubgraphOnDisk<T>(string path) where T : AbstractSubGraph
var graph = inMemoryAsset as SubGraph;
var graph = inMemoryAsset as T;
if (graph == null)
return;

return;
List<PropertyCollector.TextureInfo> configuredTextures;
graph.GetShader(Path.GetFileNameWithoutExtension(path), out configuredTextures);
graph.GetShader(Path.GetFileNameWithoutExtension(path), GenerationMode.ForReals, out configuredTextures);
var shaderImporter = AssetImporter.GetAtPath(path) as ShaderImporter;
if (shaderImporter == null)

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


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

using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph.Drawing.Inspector
{

gm.AddItem(new GUIContent("Vector4"), false, () => m_Presenter.graph.AddShaderProperty(new Vector4ShaderProperty()));
gm.AddItem(new GUIContent("Color"), false, () => m_Presenter.graph.AddShaderProperty(new ColorShaderProperty()));
gm.AddItem(new GUIContent("Texture"), false, () => m_Presenter.graph.AddShaderProperty(new TextureShaderProperty()));
gm.ShowAsContext();
}
gm.ShowAsContext();
}
public void OnChange(GraphInspectorPresenter.ChangeType changeType)
{

m_PropertyItems.Add(new ShaderPropertyView(m_Graph, property));
m_Graph.onChange += OnGraphChange;
}
}
}
}
void OnGraphChange(GraphChange change)

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/MaterialGraphPresenter.cs


typeMapper[typeof(AACheckerboardNode)] = typeof(AnyNodePresenter); // anything derived from AnyNode should use the AnyNodePresenter
typeMapper[typeof(AACheckerboard3dNode)] = typeof(AnyNodePresenter); // anything derived from AnyNode should use the AnyNodePresenter*/
typeMapper[typeof(SubGraphNode)] = typeof(SubgraphNodePresenter);
typeMapper[typeof(MasterRemapNode)] = typeof(MasterRemapNodePresenter);
// typeMapper[typeof(RemapMasterNode)] = typeof(RemapMasterNodePresenter);
// typeMapper[typeof(MasterRemapInputNode)] = typeof(RemapInputNodePresenter);
typeMapper[typeof(AbstractSubGraphIONode)] = typeof(SubgraphIONodePresenter);
// typeMapper[typeof(AbstractSurfaceMasterNode)] = typeof(SurfaceMasterNodePresenter);

61
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/Nodes/RemapMasterNodePresenter.cs


using System;
using System.Collections.Generic;
using UnityEditor.Experimental.UIElements.GraphView;
/* [Serializable]
class RemapMasterControlPresenter : GraphControlPresenter
{
public override void OnGUIHandler()
{
base.OnGUIHandler();
[Serializable]
class RemapContolPresenter : GraphControlPresenter
{
public override void OnGUIHandler()
{
base.OnGUIHandler();
var remapNode = node as RemapMasterNode;
if (remapNode == null)
return;
var remapNode = node as MasterRemapNode;
if (remapNode == null)
return;
remapNode.remapAsset = (MaterialRemapAsset)EditorGUILayout.MiniThumbnailObjectField(
new GUIContent("Remap Asset"),
remapNode.remapAsset,
typeof(MaterialRemapAsset), null);
}
remapNode.remapGraphAsset = (MasterRemapGraphAsset)EditorGUILayout.MiniThumbnailObjectField(
new GUIContent("Remap"),
remapNode.remapGraphAsset,
typeof(MasterRemapGraphAsset), null);
}
public override float GetHeight()
{
return EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing;
}
}
public override float GetHeight()
{
return EditorGUIUtility.singleLineHeight + 2 * EditorGUIUtility.standardVerticalSpacing;
}
}
[Serializable]
public class RemapMasterNodePresenter : MasterNodePresenter
{
protected override IEnumerable<GraphControlPresenter> GetControlData()
{
var instance = CreateInstance<RemapMasterControlPresenter>();
instance.Initialize(node);
var controls = new List<GraphControlPresenter>(base.GetControlData());
controls.Add(instance);
return controls;
}
}*/
[Serializable]
public class MasterRemapNodePresenter : MaterialNodePresenter
{
protected override IEnumerable<GraphControlPresenter> GetControlData()
{
var instance = CreateInstance<RemapContolPresenter>();
instance.Initialize(node);
return new List<GraphControlPresenter> { instance };
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Presenters/PropertyNodePresenter.cs


var propertiesGUID = properties.Select(x => x.guid).ToList();
var currentSelectedIndex = propertiesGUID.IndexOf(currentGUID);
var newIndex = EditorGUILayout.Popup("Property", currentSelectedIndex, properties.Select(x => x.name).ToArray());
var newIndex = EditorGUILayout.Popup("Property", currentSelectedIndex, properties.Select(x => x.displayName).ToArray());
if (newIndex != currentSelectedIndex)
tNode.propertyGuid = propertiesGUID[newIndex];

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewSystem.cs


}
var node = m_Graph.GetNodeFromGuid(nodeGuid);
m_PreviewMaterial.shader = previewData.shader;
m_PreviewGenerator.DoRenderPreview(previewData.renderTexture, m_PreviewMaterial, previewData.previewMode, node is MasterNode, time, m_PreviewPropertyBlock);
m_PreviewGenerator.DoRenderPreview(previewData.renderTexture, m_PreviewMaterial, previewData.previewMode, node is IMasterNode, time, m_PreviewPropertyBlock);
previewData.texture = previewData.renderTexture;
}

if (!m_Previews.TryGetValue(nodeGuid, out previewData))
return;
if (node is MasterNode && node.owner is UnityEngine.MaterialGraph.MaterialGraph)
if (node is IMasterNode)
var masterNode = (MasterNode)node;
var materialGraph = (UnityEngine.MaterialGraph.MaterialGraph) node.owner;
var materialGraph = (AbstractMaterialGraph) node.owner;
previewData.shaderString = materialGraph.GetShader(node.guid + "_preview", out defaultTextures);
previewData.previewMode = masterNode.has3DPreview() ? PreviewMode.Preview3D : PreviewMode.Preview2D;
PreviewMode pmode;
previewData.shaderString = materialGraph.GetShader(node, GenerationMode.Preview, node.guid + "_preview", out defaultTextures, out pmode);
previewData.previewMode = node.previewMode;
}
else if (!node.hasPreview || NodeUtils.FindEffectiveShaderStage(node, true) == ShaderStage.Vertex)
{

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


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

19
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightSubshaderPBR.template


fixed4 frag (GraphVertexOutput IN) : SV_Target
{
${LocalPixelShader}
SurfaceInputs surfaceInput = (SurfaceInputs)0;
${SurfaceInputs}

float3 Specular = float3(0, 0, 0);
float Metallic = 0;
float3 Normal = float3(.5, .5, 1);
float3 Normal = float3(0, 0, 1);
float3 Emission = 0;
float Smoothness = 0;
float Occlusion = 1;

#if defined(UNITY_COLORSPACE_GAMMA)
Albedo = Albedo * Albedo;
Emission = Emission * Emission;
#endif
surfaceInput.worldSpacePosition,
surfaceInput.worldSpaceNormal,
surfaceInput.worldSpaceTangent,
surfaceInput.worldSpaceBiTangent,
surfaceInput.worldSpaceViewDirection,
worldSpacePosition,
worldSpaceNormal,
worldSpaceTangent,
worldSpaceBiTangent,
worldSpaceViewDirection,
IN.fogCoord,
Albedo,

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Templates/lightweightSubshaderUnlit.template


fixed4 frag (GraphVertexOutput IN) : SV_Target
{
${LocalPixelShader}
float3 Alpha = 0;
${SurfaceOutputRemap}
#ifdef _ALPHABLEND_ON

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/Graphs/Add-Sub-Graph.ShaderSubGraph.meta


fileFormatVersion: 2
guid: e8dfdb83d3043c7499b6cd1edd7b8f8d
timeCreated: 1503169600
licenseType: Pro
ScriptedImporter:
userData:
assetBundleName:

139
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs


}
}
public void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
public virtual void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
public void AddShaderProperty(IShaderProperty property)
public virtual void AddShaderProperty(IShaderProperty property)
{
if (property == null)
return;

requiresMeshUVs = meshUV
};
reqs = reqs.Union(nodeForRequirements.GetNodeSpecificRequirements());
ListPool<INode>.Release(activeNodeList);
return reqs;
}

return GetShader(node, GenerationMode.Preview, string.Format("hidden/preview/{0}", node.GetVariableNameForNode()), out configuredTextures, out previewMode);
}
protected string GetShader(AbstractMaterialNode node, GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures, out PreviewMode previewMode)
public string GetShader(AbstractMaterialNode node, GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures, out PreviewMode previewMode)
if (node == null)
throw new ArgumentNullException(nameof(node));
var pixelShader = new ShaderGenerator();
var surfaceDescription = new ShaderGenerator();
var surfaceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();

vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
surfaceDescription.AddShaderChunk("struct SurfaceDescription{", false);
surfaceDescription.Indent();
if (mode == GenerationMode.Preview)
surfaceDescriptionStruct.AddShaderChunk("struct SurfaceDescription{", false);
surfaceDescriptionStruct.Indent();
if (node is IMasterNode)
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
surfaceDescription.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + node.GetVariableNameForSlot(slot.id) + ";", false);
foreach (var slot in node.GetInputSlots<MaterialSlot>())
surfaceDescriptionStruct.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + slot.shaderOutputName + ";", false);
foreach (var slot in node.GetInputSlots<MaterialSlot>())
surfaceDescription.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + slot.shaderOutputName + ";", false);
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
surfaceDescriptionStruct.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + node.GetVariableNameForSlot(slot.id) + ";", false);
surfaceDescription.Deindent();
surfaceDescription.AddShaderChunk("};", false);
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
pixelShader.AddShaderChunk("SurfaceDescription PopulateSurfaceData(SurfaceInputs IN) {", false);
pixelShader.Indent();
surfaceDescriptionFunction.AddShaderChunk("SurfaceDescription PopulateSurfaceData(SurfaceInputs IN) {", false);
surfaceDescriptionFunction.Indent();
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceNormal), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceNormal), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceNormal), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceNormal), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceTangent), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceTangent), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceTangent), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceTangent), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceBiTangent), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceBiTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceBiTangent), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceBiTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceBiTangent), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceBiTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceBiTangent), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceBiTangent), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceViewDirection), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceViewDirection), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceViewDirection), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpacePosition), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpacePosition), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.ViewSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpacePosition), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.WorldSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpacePosition), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float3 {0} = IN.{0};", ShaderGeneratorNames.TangentSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
surfaceDescriptionFunction.AddShaderChunk(string.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
var shaderProperties = new PropertyCollector();
CollectShaderProperties(shaderProperties, mode);

if (activeNode is IGeneratesFunction)
(activeNode as IGeneratesFunction).GenerateNodeFunction(shaderFunctionVisitor, mode);
if (activeNode is IGeneratesBodyCode)
(activeNode as IGeneratesBodyCode).GenerateNodeCode(pixelShader, mode);
(activeNode as IGeneratesBodyCode).GenerateNodeCode(surfaceDescriptionFunction, mode);
pixelShader.AddShaderChunk("SurfaceDescription surface = (SurfaceDescription)0;", false);
if (mode == GenerationMode.Preview)
{
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
pixelShader.AddShaderChunk(string.Format("surface.{0} = {0};", node.GetVariableNameForSlot(slot.id)), true);
}
else
surfaceDescriptionFunction.AddShaderChunk("SurfaceDescription surface = (SurfaceDescription)0;", false);
if (node is IMasterNode)
foreach (var edge in GetEdges(input.slotReference))
var foundEdges = GetEdges(input.slotReference).ToArray();
if (foundEdges.Any())
{
var outputRef = foundEdges[0].outputSlot;
var fromNode = GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", input.shaderOutputName, fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
}
else
var outputRef = edge.outputSlot;
var fromNode = GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
if (fromNode == null)
continue;
pixelShader.AddShaderChunk(string.Format("surface.{0} = {1};", input.shaderOutputName, fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", input.shaderOutputName, input.GetDefaultValue(mode)), true);
pixelShader.AddShaderChunk("return surface;", false);
pixelShader.Deindent();
pixelShader.AddShaderChunk("}", false);
else
{
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {0};", node.GetVariableNameForSlot(slot.id)), true);
}
surfaceDescriptionFunction.AddShaderChunk("return surface;", false);
surfaceDescriptionFunction.Deindent();
surfaceDescriptionFunction.AddShaderChunk("}", false);
ListPool<INode>.Release(activeNodeList);
var finalShader = new ShaderGenerator();

finalShader.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
finalShader.AddShaderChunk(graphVertexInput, false);
finalShader.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescription.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false);
finalShader.AddShaderChunk(pixelShader.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);
if (mode == GenerationMode.Preview)
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(node, requirements), false);
var masterNode = node as IMasterNode;
if (masterNode != null)
{
var subShaders = masterNode.GetSubshader(requirements, null);
foreach (var ss in subShaders)
finalShader.AddShaderChunk(ss, false);
}
var master = (MasterNode) node;
finalShader.AddShaderChunk(master.GetSubShader(requirements), false);
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(node, requirements), false);
}
finalShader.Deindent();

18
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractShaderProperty.cs


set { m_Value = value; }
}
public string name
public string displayName
{
get
{

set { m_Name = value; }
}
public string description
public string referenceName
return string.IsNullOrEmpty(m_Description) ? name : m_Description;
return string.IsNullOrEmpty(overrideReferenceName)
? string.Format("{0}_{1}", propertyType, GuidEncoder.Encode(guid))
: overrideReferenceName;
set { m_Description = value; }
public string overrideReferenceName { get; set; } = string.Empty;
public abstract PropertyType propertyType { get; }
public Guid guid

set { m_GeneratePropertyBlock = value; }
}
public abstract Vector4 defaultValue { get; }
public virtual string GetInlinePropertyDeclarationString()
{
return GetPropertyDeclarationString();
}
public abstract PreviewProperty GetPreviewMaterialProperty();
public virtual void OnBeforeSerialize()

13
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/ColorShaderProperty.cs


get { return PropertyType.Color; }
}
public override Vector4 defaultValue
{
get { return new Vector4(value.r, value.g, value.b, value.a); }
}
public override string GetPropertyBlockString()
{
if (!generatePropertyBlock)

if (HDR)
result.Append("[HDR]");
result.Append(name);
result.Append(referenceName);
result.Append(description);
result.Append(displayName);
result.Append("\", Color) = (");
result.Append(value.r);
result.Append(",");

public override string GetPropertyDeclarationString()
{
return "float4 " + name + ";";
return "float4 " + referenceName + ";";
}
public override PreviewProperty GetPreviewMaterialProperty()

m_Name = name,
m_Name = referenceName,
m_PropType = PropertyType.Color,
m_Color = value
};

13
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/FloatShaderProperty.cs


get { return PropertyType.Float; }
}
public override Vector4 defaultValue
{
get { return new Vector4(value, value, value, value);}
}
public override string GetPropertyBlockString()
{
var result = new StringBuilder();

// result.Append("[PowerSlider(" + m_rangeValues.z + ")]");
result.Append(name);
result.Append(referenceName);
result.Append(description);
result.Append(displayName);
//if (m_FloatType == FloatPropertyChunk.FloatType.Float || m_FloatType == FloatPropertyChunk.FloatType.Toggle)
//{

public override string GetPropertyDeclarationString()
{
return "float " + name + ";";
return "float " + referenceName + ";";
}
public override PreviewProperty GetPreviewMaterialProperty()

m_Name = name,
m_Name = referenceName,
m_PropType = PropertyType.Float,
m_Float = value
};

9
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/IShaderProperty.cs


{
public interface IShaderProperty
{
string name { get; set; }
string description { get; set; }
string displayName { get; set; }
string referenceName { get; }
Vector4 defaultValue { get; }
string overrideReferenceName { get; set; }
string GetInlinePropertyDeclarationString();
PreviewProperty GetPreviewMaterialProperty();
}
}

10
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraph.cs


[Serializable]
public class MaterialGraph : AbstractMaterialGraph
{
public MasterNode masterNode
public IMasterNode masterNode
get { return GetNodes<MasterNode>().FirstOrDefault(); }
get { return GetNodes<INode>().OfType<IMasterNode>().FirstOrDefault(); }
public string GetShader(string name, out List<PropertyCollector.TextureInfo> configuredTextures)
public string GetShader(string name, GenerationMode mode, out List<PropertyCollector.TextureInfo> configuredTextures)
PreviewMode mode;
return GetShader(masterNode, GenerationMode.ForReals, name, out configuredTextures, out mode);
PreviewMode pmode;
return GetShader(masterNode as AbstractMaterialNode, mode, name, out configuredTextures, out pmode);
}
}

26
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialSlot.cs


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

[SerializeField]
ShaderStage m_ShaderStage;
public static readonly string DefaultTextureName = "ShaderGraph_DefaultTexture";
public MaterialSlot() { }

if (matOwner == null)
throw new Exception(string.Format("Slot {0} either has no owner, or the owner is not a {1}", this, typeof(AbstractMaterialNode)));
if (concreteValueType == ConcreteSlotValueType.Texture2D)
return DefaultTextureName;
if (generationMode.IsPreview())
return matOwner.GetVariableNameForSlot(id);

}
}
public void AddProperty(PropertyCollector properties, GenerationMode generationMode)
public void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode)
if (!generationMode.IsPreview())
// share tex2d for all non connected slots :)
if (concreteValueType == ConcreteSlotValueType.Texture2D)
{
var prop = new TextureShaderProperty();
prop.overrideReferenceName = DefaultTextureName;
prop.modifiable = false;
prop.generatePropertyBlock = true;
properties.AddShaderProperty(prop);
return;
}
if (concreteValueType == ConcreteSlotValueType.SamplerState)
if (concreteValueType == ConcreteSlotValueType.SamplerState ||
concreteValueType == ConcreteSlotValueType.Texture2D)
if (!generationMode.IsPreview())
return;
var matOwner = owner as AbstractMaterialNode;

throw new ArgumentOutOfRangeException();
}
property.name = matOwner.GetVariableNameForSlot(id);
property.overrideReferenceName = matOwner.GetVariableNameForSlot(id);
property.generatePropertyBlock = false;
properties.AddShaderProperty(property);

7
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/SamplerStateShaderProperty.cs


get { return PropertyType.SamplerState; }
}
public override Vector4 defaultValue
{
get { return new Vector4(); }
}
public override string GetPropertyBlockString()
{
return string.Empty;

{
string ss = name + "_"
string ss = referenceName + "_"
+ Enum.GetName(typeof(TextureSamplerState.FilterMode), value.filter) + "_"
+ Enum.GetName(typeof(TextureSamplerState.WrapMode), value.wrap) + "_sampler;";

17
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/TextureShaderProperty.cs


set { m_Modifiable = value; }
}
public override Vector4 defaultValue
{
get { return new Vector4(); }
}
public override string GetPropertyBlockString()
{
var result = new StringBuilder();

}
result.Append("[NoScaleOffset] ");
result.Append(name);
result.Append(referenceName);
result.Append(description);
result.Append(displayName);
result.Append("\", 2D) = \"white\" {}");
return result.ToString();
}

return "UNITY_DECLARE_TEX2D(" + name + ");";
return "UNITY_DECLARE_TEX2D(" + referenceName + ");";
public override string GetInlinePropertyDeclarationString()
{
return "UNITY_DECLARE_TEX2D_NOSAMPLER(" + referenceName + ");";
}
m_Name = name,
m_Name = referenceName,
m_PropType = PropertyType.Texture,
m_Texture = value.texture
};

12
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/Vector2ShaderProperty.cs


get { return PropertyType.Vector2; }
}
public override Vector4 defaultValue
{
get { return new Vector4(value.x, value.y, 0, 0); }
}
public override string GetInlinePropertyDeclarationString()
{
return "float2 " + referenceName + ";";
}
m_Name = name,
m_Name = referenceName,
m_PropType = PropertyType.Vector2,
m_Vector4 = value
};

12
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/Vector3ShaderProperty.cs


get { return PropertyType.Vector3; }
}
public override Vector4 defaultValue
{
get { return new Vector4(value.x, value.y, value.z, 0); }
}
public override string GetInlinePropertyDeclarationString()
{
return "float3 " + referenceName + ";";
}
m_Name = name,
m_Name = referenceName,
m_PropType = PropertyType.Vector3,
m_Vector4 = value
};

7
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/Vector4ShaderProperty.cs


get { return PropertyType.Vector4; }
}
public override Vector4 defaultValue
{
get { return value; }
}
m_Name = name,
m_Name = referenceName,
m_PropType = PropertyType.Vector4,
m_Vector4 = value
};

6
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/VectorShaderProperty.cs


public override string GetPropertyBlockString()
{
var result = new StringBuilder();
result.Append(name);
result.Append(referenceName);
result.Append(description);
result.Append(displayName);
result.Append("\", Vector) = (");
result.Append(value.x);
result.Append(",");

public override string GetPropertyDeclarationString()
{
return "float4 " + name + ";";
return "float4 " + referenceName + ";";
}
}
}

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


using System.Collections.Generic;
namespace UnityEngine.MaterialGraph
{
public interface IGenerateProperties

166
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/AbstractLightweightMasterNode.cs


protected abstract IEnumerable<int> masterVertexInputs { get; }
protected abstract string GetTemplateName();
protected virtual void GetLightweightDefinesAndRemap(ShaderGenerator defines, ShaderGenerator surfaceOutputRemap)
protected virtual void GetLightweightDefinesAndRemap(ShaderGenerator defines, ShaderGenerator surfaceOutputRemap, MasterRemapGraph remapper)
foreach (var slot in GetInputSlots<MaterialSlot>())
// Step 1: no remapper, working with raw master node..
if (remapper == null)
{
foreach (var slot in GetInputSlots<MaterialSlot>())
{
surfaceOutputRemap.AddShaderChunk(slot.shaderOutputName
+ " = surf."
+ slot.shaderOutputName + ";", true);
}
}
// Step 2: remapper present... complex workflow time
else
var edge = owner.GetEdges(slot.slotReference).FirstOrDefault();
if (edge == null)
continue;
surfaceOutputRemap.AddShaderChunk("{", false);
surfaceOutputRemap.Indent();
foreach (var prop in remapper.properties)
{
surfaceOutputRemap.AddShaderChunk(prop.GetInlinePropertyDeclarationString(), true);
surfaceOutputRemap.AddShaderChunk(string.Format("{0} = surf.{0};", prop.referenceName), true);
}
List<INode> nodes = new List<INode>();
NodeUtils.DepthFirstCollectNodesFromNode(nodes, this, NodeUtils.IncludeSelf.Exclude);
foreach (var activeNode in nodes.OfType<AbstractMaterialNode>())
{
if (activeNode is IGeneratesBodyCode)
(activeNode as IGeneratesBodyCode).GenerateNodeCode(surfaceOutputRemap,
GenerationMode.ForReals);
}
foreach (var input in GetInputSlots<MaterialSlot>())
{
foreach (var edge in owner.GetEdges(input.slotReference))
{
var outputRef = edge.outputSlot;
var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
if (fromNode == null)
continue;
surfaceOutputRemap.AddShaderChunk(slot.shaderOutputName
+ " = surf."
+ slot.shaderOutputName + ";", true);
surfaceOutputRemap.AddShaderChunk(
string.Format("{0} = {1};", input.shaderOutputName,
fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
}
}
surfaceOutputRemap.Deindent();
surfaceOutputRemap.AddShaderChunk("}", false);
public override string GetSubShader(ShaderGraphRequirements shaderGraphRequirements)
public override IEnumerable<string> GetSubshader(ShaderGraphRequirements graphRequirements, MasterRemapGraph remapper)
{
var tagsVisitor = new ShaderGenerator();
var blendingVisitor = new ShaderGenerator();

m_MaterialOptions.GetDepthTest(zTestVisitor);
m_MaterialOptions.GetDepthWrite(zWriteVisitor);
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this);
var surfaceInput = new ShaderGenerator();
// bitangent needs normal for x product
if (shaderGraphRequirements.requiresNormal > 0 || shaderGraphRequirements.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : NORMAL;", ShaderGeneratorNames.ObjectSpaceNormal), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.normal;", ShaderGeneratorNames.ObjectSpaceNormal), false);
surfaceInput.AddShaderChunk(string.Format("float3 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceNormal), false);
}
if (shaderGraphRequirements.requiresTangent > 0 || shaderGraphRequirements.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TANGENT;", ShaderGeneratorNames.ObjectSpaceTangent), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.tangent;", ShaderGeneratorNames.ObjectSpaceTangent), false);
surfaceInput.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceTangent), false);
surfaceInput.AddShaderChunk(string.Format("float3 {0} = normalize(cross(normalize(IN.{1}), normalize(IN.{2}.xyz)) * IN.{2}.w);",
ShaderGeneratorNames.ObjectSpaceBiTangent,
ShaderGeneratorNames.ObjectSpaceNormal,
ShaderGeneratorNames.ObjectSpaceTangent), false);
}
int interpolatorIndex = GetInterpolatorStartIndex();
if (shaderGraphRequirements.requiresViewDir > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpaceViewDirection, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ObjSpaceViewDir(v.vertex);", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
surfaceInput.AddShaderChunk(string.Format("float3 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
interpolatorIndex++;
}
if (shaderGraphRequirements.requiresPosition > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpacePosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.vertex;", ShaderGeneratorNames.ObjectSpacePosition), false);
surfaceInput.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpacePosition), false);
interpolatorIndex++;
}
if (shaderGraphRequirements.NeedsTangentSpace())
{
surfaceInput.AddShaderChunk(string.Format("float3x3 tangentSpaceTransform = float3x3({0},{1},{2});",
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ObjectSpaceNormal), false);
}
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresNormal, surfaceInput,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal);
var localPixelShader = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresTangent, surfaceInput,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresBitangent, surfaceInput,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresViewDir, surfaceInput,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresPosition, surfaceInput,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition);
if (shaderGraphRequirements.requiresVertexColor)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
surfaceInput.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
}
if (shaderGraphRequirements.requiresScreenPosition)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(UnityObjectToClipPos(v.vertex)", ShaderGeneratorNames.ScreenPosition), false);
surfaceInput.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
interpolatorIndex++;
}
foreach (var channel in shaderGraphRequirements.requiresMeshUVs.Distinct())
{
interpolators.AddShaderChunk(string.Format("half4 {0} : TEXCOORD{1};", channel.GetUVName(), interpolatorIndex == 0 ? "" : interpolatorIndex.ToString()), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.texcoord{1};", channel.GetUVName(), (int)channel), false);
surfaceInput.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", channel.GetUVName()), false);
interpolatorIndex++;
}
ShaderGenerator.GenerateStandardTransforms(
GetInterpolatorStartIndex(),
interpolators,
vertexShader,
localPixelShader,
surfaceInputs,
graphRequirements,
GetNodeSpecificRequirements());
GetLightweightDefinesAndRemap(defines, surfaceOutputRemap);
GetLightweightDefinesAndRemap(defines, surfaceOutputRemap, remapper);
return string.Empty;
return new string[] {};
resultShader = resultShader.Replace("${SurfaceInputs}", surfaceInput.GetShaderString(0));
resultShader = resultShader.Replace("${SurfaceOutputRemap}", surfaceOutputRemap.GetShaderString(0));
resultShader = resultShader.Replace("${LocalPixelShader}", localPixelShader.GetShaderString(3));
resultShader = resultShader.Replace("${SurfaceInputs}", surfaceInputs.GetShaderString(3));
resultShader = resultShader.Replace("${SurfaceOutputRemap}", surfaceOutputRemap.GetShaderString(3));
resultShader = resultShader.Replace("${Tags}", tagsVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${Blending}", blendingVisitor.GetShaderString(2));

resultShader = resultShader.Replace("${LOD}", "" + m_MaterialOptions.lod);
return resultShader;
return new[] {resultShader};
}
protected abstract int GetInterpolatorStartIndex();

39
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/AbstractLightweightPBRMasterNode.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{

public const int SmoothnessSlotId = 4;
public const int OcclusionSlotId = 5;
public const int AlphaSlotId = 6;
public const int VertexOffsetId = 7;
protected override void GetLightweightDefinesAndRemap(ShaderGenerator defines, ShaderGenerator surfaceOutputRemap)
protected override void GetLightweightDefinesAndRemap(ShaderGenerator defines, ShaderGenerator surfaceOutputRemap, MasterRemapGraph remapper)
base.GetLightweightDefinesAndRemap(defines, surfaceOutputRemap);
base.GetLightweightDefinesAndRemap(defines, surfaceOutputRemap, remapper);
defines.AddShaderChunk("#define _GLOSSYREFLECTIONS_ON", true);
defines.AddShaderChunk("#define _SPECULARHIGHLIGHTS_ON", true);

var nm = FindSlot<MaterialSlot>(NormalSlotId);
return owner.GetEdges(nm.slotReference).Any();
}
/* public void GenerateNodeCode(ShaderGenerator shaderBody, ShaderGenerator propertyUsages, GenerationMode generationMode)
{
foreach (var slot in GetInputSlots<MaterialSlot>())
{
if (surfaceInputs.Contains(slot.id))
{
foreach (var edge in owner.GetEdges(slot.slotReference))
{
var outputRef = edge.outputSlot;
var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
if (fromNode == null)
continue;
var remapper = fromNode as INodeGroupRemapper;
if (remapper != null && !remapper.IsValidSlotConnection(outputRef.slotId))
continue;
shaderBody.AddShaderChunk("o." + slot.shaderOutputName + " = " + fromNode.GetVariableNameForSlot(outputRef.slotId) + ";", true);
if (slot.id == NormalSlotId)
shaderBody.AddShaderChunk("o." + slot.shaderOutputName + " += 1e-6;", true);
if (slot.id == AlphaSlotId)
propertyUsages.AddShaderChunk("#define _ALPHAPREMULTIPLY_ON", true);
}
}
}
}*/
}
}

20
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/LightweightMetallicMasterNode.cs


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

{
public const string MetallicSlotName = "Metallic";
public const int MetallicSlotId = 2;
public const string WorkflowName = "Metallic";
public LightweightMetallicMasterNode()
{

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(VertexOffsetId, VertexOffsetName, VertexOffsetName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Vertex));
AddSlot(new MaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(NormalSlotId, NormalSlotName, NormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, SlotValueType.Vector3, new Vector4(0.5f, 0.5f, 0.5f), ShaderStage.Fragment));
AddSlot(new MaterialSlot(NormalSlotId, NormalSlotName, NormalSlotName, SlotType.Input, SlotValueType.Vector3, new Vector4(0,0,1), ShaderStage.Fragment));
AddSlot(new MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.one, ShaderStage.Fragment));
// clear out slot names that do not match the slots
// we support

MetallicSlotId,
SmoothnessSlotId,
OcclusionSlotId,
AlphaSlotId,
VertexOffsetId
AlphaSlotId
});
}

}
protected override void GetLightweightDefinesAndRemap(ShaderGenerator defines, ShaderGenerator surfaceOutputRemap)
protected override void GetLightweightDefinesAndRemap(ShaderGenerator defines, ShaderGenerator surfaceOutputRemap, MasterRemapGraph remapper)
base.GetLightweightDefinesAndRemap(defines, surfaceOutputRemap);
base.GetLightweightDefinesAndRemap(defines, surfaceOutputRemap, remapper);
defines.AddShaderChunk("#define _METALLIC_SETUP 1", true);
}

{
get
{
return new[]
return new int[]
VertexOffsetId
};
}
}

33
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/LightweightSpecularMasterNode.cs


using System;
using System.Collections.Generic;
/* [Serializable]
[Serializable]
[Title("Master/Lightweight/PBR Specular")]
public class LightweightSpecularMasterNode : AbstractLightweightPBRMasterNode
{

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(VertexOffsetId, VertexOffsetName, VertexOffsetName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Vertex));
AddSlot(new MaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(NormalSlotId, NormalSlotName, NormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, SlotValueType.Vector3, new Vector4(0.5f, 0.5f, 0.5f, 0.5f), ShaderStage.Fragment));
AddSlot(new MaterialSlot(NormalSlotId, NormalSlotName, NormalSlotName, SlotType.Input, SlotValueType.Vector3, new Vector4(0,0,1), ShaderStage.Fragment));
AddSlot(new MaterialSlot(SpecularSlotId, SpecularSlotName, SpecularSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(SpecularSlotId, SpecularSlotName, SpecularSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.one, ShaderStage.Fragment));
// clear out slot names that do not match the slots
// we support

SpecularSlotId,
SmoothnessSlotId,
OcclusionSlotId,
AlphaSlotId,
VertexOffsetId
AlphaSlotId
protected override string GetTemplateName()
{
return "lightweightSubshaderPBR.template";
}
protected override int[] surfaceInputs
protected override IEnumerable<int> masterSurfaceInputs
{
get
{

}
}
protected override int[] vertexInputs
protected override IEnumerable<int> masterVertexInputs
return new[]
return new int[]
VertexOffsetId
public override string GetWorkflowName()
{
return WorkflowName;
}
}*/
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/LightweightPipeline/LightweightUnlitMasterNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text.RegularExpressions;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph

{
public const string ColorSlotName = "Color";
public const string AlphaSlotName = "Alpha";
public const string VertexOffsetName = "VertexPosition";
public const int VertexOffsetId = 2;
public LightweightUnlitMasterNode()
{

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(VertexOffsetId, VertexOffsetName, VertexOffsetName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Vertex));
AddSlot(new MaterialSlot(ColorSlotId, ColorSlotName, ColorSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero, ShaderStage.Fragment));
AddSlot(new MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero, ShaderStage.Fragment));

new[]
{
ColorSlotId,
AlphaSlotId,
VertexOffsetId
AlphaSlotId
});
}

{
get
{
return new[]
return new int[]
VertexOffsetId
};
}
}

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


get { return true; }
}
protected virtual bool generateDefaultInputs
{
get { return true; }
}
public override bool hasError
{
get { return m_HasError; }

public virtual void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
if (!generateDefaultInputs)
return;
if (!generationMode.IsPreview())
return;

if (edges.Any())
continue;
inputSlot.AddProperty(properties, generationMode);
inputSlot.AddDefaultProperty(properties, generationMode);
}
}

// preserve the old current value.
addingSlot.currentValue = foundSlot.currentValue;
}
public virtual ShaderGraphRequirements GetNodeSpecificRequirements()
{
return ShaderGraphRequirements.none;
}
}
}

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


properties.AddShaderProperty(new ColorShaderProperty()
{
name = GetVariableNameForNode(),
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,
value = color,
HDR = HDR

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


public NeededCoordinateSpace RequiresViewDirection()
{
return NeededCoordinateSpace.Object;
return NeededCoordinateSpace.World;
}
}
}

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


properties.AddShaderProperty(new FloatShaderProperty()
{
name = GetVariableNameForNode(),
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,
value = value
});

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


properties.AddShaderProperty(new Vector2ShaderProperty()
{
name = GetVariableNameForNode(),
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,
value = value
});

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


properties.AddShaderProperty(new Vector3ShaderProperty()
{
name = GetVariableNameForNode(),
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,
value = value
});

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


properties.AddShaderProperty(new Vector4ShaderProperty()
{
name = GetVariableNameForNode(),
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false,
value = value
});

189
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MasterNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
[Title("Master/Master")]
public abstract class MasterNode : AbstractMaterialNode
public abstract class MasterNode : AbstractMaterialNode, IMasterNode
{
[SerializeField]
protected SurfaceMaterialOptions m_MaterialOptions = new SurfaceMaterialOptions();

UpdateNodeAfterDeserialization();
}
public override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(0, "Test", "Test", SlotType.Input, SlotValueType.Vector4, Vector4.one));
RemoveSlotsNameNotMatching(new[] { 0 });
}
protected override bool generateDefaultInputs { get { return false; } }
public override IEnumerable<ISlot> GetInputsWithNoConnection()
{
return new List<ISlot>();
}
public override bool hasPreview
{
get { return true; }

get { return false; }
}
public virtual bool has3DPreview()
public override PreviewMode previewMode
return true;
get { return PreviewMode.Preview3D; }
public abstract string GetSubShader(ShaderGraphRequirements shaderGraphRequirements);
/*{
var tagsVisitor = new ShaderGenerator();
var blendingVisitor = new ShaderGenerator();
var cullingVisitor = new ShaderGenerator();
var zTestVisitor = new ShaderGenerator();
var zWriteVisitor = new ShaderGenerator();
m_MaterialOptions.GetTags(tagsVisitor);
m_MaterialOptions.GetBlend(blendingVisitor);
m_MaterialOptions.GetCull(cullingVisitor);
m_MaterialOptions.GetDepthTest(zTestVisitor);
m_MaterialOptions.GetDepthWrite(zWriteVisitor);
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this);
var interpolators = new ShaderGenerator();
var vertexShader = new ShaderGenerator();
var pixelShader = new ShaderGenerator();
// bitangent needs normal for x product
if (shaderGraphRequirements.requiresNormal > 0 || shaderGraphRequirements.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : NORMAL;", ShaderGeneratorNames.ObjectSpaceNormal), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.normal;", ShaderGeneratorNames.ObjectSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceNormal), false);
}
if (shaderGraphRequirements.requiresTangent > 0 || shaderGraphRequirements.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TANGENT;", ShaderGeneratorNames.ObjectSpaceTangent), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.tangent;", ShaderGeneratorNames.ObjectSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = normalize(cross(normalize(IN.{1}), normalize(IN.{2}.xyz)) * IN.{2}.w);",
ShaderGeneratorNames.ObjectSpaceBiTangent,
ShaderGeneratorNames.ObjectSpaceTangent,
ShaderGeneratorNames.ObjectSpaceNormal), false);
}
int interpolatorIndex = 0;
if (shaderGraphRequirements.requiresViewDir > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpaceViewDirection, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ObjSpaceViewDir(v.vertex);", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
interpolatorIndex++;
}
if (shaderGraphRequirements.requiresPosition > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpacePosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.vertex;", ShaderGeneratorNames.ObjectSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpacePosition), false);
interpolatorIndex++;
}
if (shaderGraphRequirements.NeedsTangentSpace())
{
pixelShader.AddShaderChunk(string.Format("float3x3 tangentSpaceTransform = float3x3({0},{1},{2});",
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ObjectSpaceNormal), false);
}
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresNormal, pixelShader,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresTangent, pixelShader,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresBitangent, pixelShader,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresViewDir, pixelShader,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection);
ShaderGenerator.GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresPosition, pixelShader,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition);
if (shaderGraphRequirements.requiresVertexColor)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
}
if (shaderGraphRequirements.requiresScreenPosition)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(UnityObjectToClipPos(v.vertex)", ShaderGeneratorNames.ScreenPosition), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
interpolatorIndex++;
}
foreach (var channel in shaderGraphRequirements.requiresMeshUVs.Distinct())
{
interpolators.AddShaderChunk(string.Format("half4 {0} : TEXCOORD{1};", channel.GetUVName(), interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.texcoord{1};", channel.GetUVName(), interpolatorIndex == 0 ? "" : interpolatorIndex.ToString()), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", channel.GetUVName()), false);
interpolatorIndex++;
}
var outputs = new ShaderGenerator();
var slot = FindSlot<MaterialSlot>(0);
var result = string.Format("surf.{0}", slot.shaderOutputName);
outputs.AddShaderChunk(string.Format("return {0};", ShaderGenerator.AdaptNodeOutputForPreview(this, 0, result)), true);
var resultShader = subShaderTemplate.Replace("{0}", interpolators.GetShaderString(0));
resultShader = resultShader.Replace("{1}", vertexShader.GetShaderString(0));
resultShader = resultShader.Replace("{2}", pixelShader.GetShaderString(0));
resultShader = resultShader.Replace("{3}", outputs.GetShaderString(0));
resultShader = resultShader.Replace("${Tags}", tagsVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${Blending}", blendingVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${Culling}", cullingVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${ZTest}", zTestVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${ZWrite}", zWriteVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${LOD}", "" + m_MaterialOptions.lod);
return resultShader;
public virtual ShaderGraphRequirements GetNodeSpecificRequirements()
{
return ShaderGraphRequirements.none;
private const string subShaderTemplate = @"
SubShader
{
Tags { ""RenderType""=""Opaque"" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include ""UnityCG.cginc""
struct GraphVertexOutput
public SurfaceMaterialOptions options
float4 position : POSITION;
{0}
};
get { return m_MaterialOptions; }
GraphVertexOutput vert (GraphVertexInput v)
{
v = PopulateVertexData(v);
GraphVertexOutput o;
o.position = UnityObjectToClipPos(v.vertex);
{1}
return o;
fixed4 frag (GraphVertexOutput IN) : SV_Target
{
SurfaceInputs surfaceInput;
{2}
SurfaceDescription surf = PopulateSurfaceData(surfaceInput);
{3}
}
ENDCG
}
}";*/
public abstract IEnumerable<string> GetSubshader(ShaderGraphRequirements graphRequirements, MasterRemapGraph remapper);
}
}

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


var result = string.Format("{0} {1} = {2};"
, precision
, GetVariableNameForSlot(OutputSlotId)
, property.name);
, property.referenceName);
visitor.AddShaderChunk(result, true);
}
else if (property is Vector2ShaderProperty)

, GetVariableNameForSlot(OutputSlotId)
, property.name);
, property.referenceName);
visitor.AddShaderChunk(result, true);
}
else if (property is Vector3ShaderProperty)

, GetVariableNameForSlot(OutputSlotId)
, property.name);
, property.referenceName);
visitor.AddShaderChunk(result, true);
}
else if (property is Vector4ShaderProperty)

, GetVariableNameForSlot(OutputSlotId)
, property.name);
, property.referenceName);
visitor.AddShaderChunk(result, true);
}
else if (property is ColorShaderProperty)

, GetVariableNameForSlot(OutputSlotId)
, property.name);
, property.referenceName);
visitor.AddShaderChunk(result, true);
}
else if (property is TextureShaderProperty)

var result = string.Format("{0}4 {1} = UNITY_SAMPLE_TEX2D({2},{3});"
, precision
, GetVariableNameForSlot(OutputSlotId)
, property.name
, property.referenceName
, uvName);
visitor.AddShaderChunk(result, true);
visitor.AddShaderChunk(string.Format("{0} {1} = {2}.r;", precision, GetVariableNameForSlot(ROutputSlotId), GetVariableNameForSlot(OutputSlotId)), true);

var graph = owner as AbstractMaterialGraph;
var property = graph.properties.FirstOrDefault(x => x.guid == propertyGuid);
return property.name;
return property.referenceName;
}
protected override bool CalculateNodeHasError()

124
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapGraph.cs


namespace UnityEngine.MaterialGraph
{
public interface INodeGroupRemapper
[Serializable]
public class MasterRemapGraph : AbstractSubGraph
void DepthFirstCollectNodesFromNodeSlotList(List<INode> nodeList, NodeUtils.IncludeSelf includeSelf);
bool IsValidSlotConnection(int id);
}
/* [Serializable]
public class MasterRemapGraph : AbstractMaterialGraph
{
[NonSerialized]
private MasterRemapInputNode m_InputNode;
public MasterRemapInputNode inputNode
{
get
{
// find existing node
if (m_InputNode == null)
m_InputNode = GetNodes<MasterRemapInputNode>().FirstOrDefault();
return m_InputNode;
}
}
public override void OnAfterDeserialize()
{
base.OnAfterDeserialize();
m_InputNode = null;
}
public override void AddNode(INode node)
{
if (inputNode != null && node is MasterRemapInputNode)
{
Debug.LogWarning("Attempting to add second SubGraphInputNode to SubGraph. This is not allowed.");
return;
}
var materialNode = node as AbstractMaterialNode;
if (materialNode != null)
{
var amn = materialNode;
if (!amn.allowedInRemapGraph)
{
Debug.LogWarningFormat("Attempting to add {0} to Remap Graph. This is not allowed.", amn.GetType());
return;
}
}
base.AddNode(node);
}
struct DisposeMeh : IDisposable
{
private readonly MasterRemapInputNode m_Graph;
public DisposeMeh(MasterRemapInputNode graph, RemapMasterNode master)
{
m_Graph = graph;
graph.m_RemapTarget = master;
}
public override void AddShaderProperty(IShaderProperty property)
{
if (property.GetType() == typeof(TextureShaderProperty))
{
Debug.LogWarning("Can not add Texture properties to remap graphs");
return;
}
public void Dispose()
{
m_Graph.m_RemapTarget = null;
}
}
base.AddShaderProperty(property);
}
public List<string> GetSubShadersFor(RemapMasterNode rmn, GenerationMode mode, PropertyGenerator shaderPropertiesVisitor)
{
var subShaders = new List<string>();
try
{
using (new DisposeMeh(inputNode, rmn))
{
foreach (var node in GetNodes<IMasterNode>())
subShaders.Add(node.GetSubShader(mode, shaderPropertiesVisitor));
}
}
catch (Exception e)
{
Debug.LogException(e);
}
return subShaders;
}
public override void AddNode(INode node)
{
var materialNode = node as AbstractMaterialNode;
if (materialNode != null)
{
var amn = materialNode;
if (!amn.allowedInRemapGraph)
{
Debug.LogWarningFormat("Attempting to add {0} to Sub Graph. This is not allowed.", amn.GetType());
return;
}
}
base.AddNode(node);
}
public void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
foreach (var node in GetNodes<AbstractMaterialNode>())
node.CollectPreviewMaterialProperties(properties);
}
public override IEnumerable<AbstractMaterialNode> activeNodes
{
get
{
var masters = GetNodes<MasterNode>();
var referencedNodes = new List<INode>();
foreach (var master in masters)
NodeUtils.DepthFirstCollectNodesFromNode(referencedNodes, master);
}*/
return referencedNodes.OfType<AbstractMaterialNode>();
}
}
}
}

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


{
public class MaterialSubGraphAsset : ScriptableObject
{
[SerializeField]
private SubGraph m_MaterialSubGraph = new SubGraph();
[SerializeField] private SubGraph m_MaterialSubGraph = new SubGraph();
public SubGraph subGraph
{

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


namespace UnityEngine.MaterialGraph
{
[Serializable]
public class SubGraph : AbstractMaterialGraph
, IGeneratesBodyCode
, IGeneratesFunction
, IGenerateProperties
public class SubGraph : AbstractSubGraph
private SubGraphInputNode m_InputNode;
[NonSerialized]
public SubGraphInputNode inputNode
{
get
{
// find existing node
if (m_InputNode == null)
m_InputNode = GetNodes<SubGraphInputNode>().FirstOrDefault();
return m_InputNode;
}
}
public SubGraphOutputNode outputNode
{
get

}
}
[NonSerialized]
private List<INode> m_ActiveNodes = new List<INode>();
public IEnumerable<AbstractMaterialNode> activeNodes
{
get
{
m_ActiveNodes.Clear();
NodeUtils.DepthFirstCollectNodesFromNode(m_ActiveNodes, outputNode);
return m_ActiveNodes.OfType<AbstractMaterialNode>();
}
}
m_InputNode = null;
if (inputNode != null && node is SubGraphInputNode)
{
Debug.LogWarning("Attempting to add second SubGraphInputNode to SubGraph. This is not allowed.");
return;
}
if (outputNode != null && node is SubGraphOutputNode)
{
Debug.LogWarning("Attempting to add second SubGraphOutputNode to SubGraph. This is not allowed.");

base.AddNode(node);
}
private IEnumerable<AbstractMaterialNode> usedNodes
public override IEnumerable<AbstractMaterialNode> activeNodes
var nodes = new List<INode>();
//Get the rest of the nodes for all the other slots
NodeUtils.DepthFirstCollectNodesFromNode(nodes, outputNode, NodeUtils.IncludeSelf.Exclude);
List<INode> nodes = new List<INode>();
NodeUtils.DepthFirstCollectNodesFromNode(nodes, outputNode);
public PreviewMode previewMode
{
get { return usedNodes.Any(x => x.previewMode == PreviewMode.Preview3D) ? PreviewMode.Preview3D : PreviewMode.Preview2D; }
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGeneratesBodyCode)
(node as IGeneratesBodyCode).GenerateNodeCode(visitor, generationMode);
}
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGeneratesFunction)
(node as IGeneratesFunction).GenerateNodeFunction(visitor, generationMode);
}
}
public void CollectShaderProperties(PropertyCollector visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGenerateProperties)
(node as IGenerateProperties).CollectShaderProperties(visitor, generationMode);
}
}
public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
//TODO: Fix
//if (node is IGeneratesVertexShaderBlock)
// (node as IGeneratesVertexShaderBlock).GenerateVertexShaderBlock(visitor, generationMode);
}
}
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
//TODO: Fix
//if (node is IGeneratesVertexToFragmentBlock)
// (node as IGeneratesVertexToFragmentBlock).GenerateVertexToFragmentBlock(visitor, generationMode);
}
}
public IEnumerable<PreviewProperty> GetPreviewProperties()
{
List<PreviewProperty> props = new List<PreviewProperty>();
foreach (var node in usedNodes)
node.CollectPreviewMaterialProperties(props);
return props;
}
}
}

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


using System;
using System.Collections.Generic;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;

namespace UnityEngine.MaterialGraph
{
[Title("Sub-graph/Sub-graph Node")]
public class SubGraphNode : AbstractMaterialNode
public class SubGraphNode : AbstractSubGraphNode
, IGeneratesFunction
, IOnAssetEnabled
, IMayRequireNormal
, IMayRequireTangent
, IMayRequireBitangent
, IMayRequireMeshUV
, IMayRequireScreenPosition
, IMayRequireViewDirection
, IMayRequirePosition
, IMayRequireVertexColor
, IMayRequireTime
{
[SerializeField]
private string m_SerializedSubGraph = string.Empty;

public MaterialSubGraphAsset subGraph;
}
protected override AbstractSubGraph referencedGraph
{
get
{
if (subGraphAsset == null)
return null;
return subGraphAsset.subGraph;
}
}
#if UNITY_EDITOR
public MaterialSubGraphAsset subGraphAsset

onModified(this, ModificationScope.Topological);
}
}
/*
// SAVED FOR LATER
if (serializedVersion<kCurrentSerializedVersion)
DoUpgrade();
[SerializeField]
private string m_SubGraphAssetGuid;
[SerializeField]
private int serializedVersion = 0;
const int kCurrentSerializedVersion = 1;
private void DoUpgrade()
{
var helper = new SubGraphHelper();
if (string.IsNullOrEmpty(m_SubGraphAssetGuid))
helper.subGraph = null;
var path = AssetDatabase.GUIDToAssetPath(m_SubGraphAssetGuid);
if (string.IsNullOrEmpty(path))
helper.subGraph = null;
helper.subGraph = AssetDatabase.LoadAssetAtPath<MaterialSubGraphAsset>(path);
m_SerializedSubGraph = EditorJsonUtility.ToJson(helper, true);
serializedVersion = kCurrentSerializedVersion;
m_SubGraphAssetGuid = string.Empty;
mark dirty damn
}*/
private SubGraph subGraph
public override INode outputNode
if (subGraphAsset == null)
return null;
return subGraphAsset.subGraph;
}
}
public override bool hasPreview
{
get { return subGraphAsset != null; }
}
public override PreviewMode previewMode
{
get
{
if (subGraphAsset == null)
return PreviewMode.Preview2D;
return PreviewMode.Preview3D;
if (subGraphAsset != null && subGraphAsset.subGraph != null)
return subGraphAsset.subGraph.outputNode;
return null;
}
}

}
public void OnEnable()
{
var validNames = new List<int>();
if (subGraphAsset == null)
{
RemoveSlotsNameNotMatching(validNames);
return;
}
var subGraphInputNode = subGraphAsset.subGraph.inputNode;
foreach (var slot in subGraphInputNode.GetOutputSlots<MaterialSlot>())
{
AddSlot(new MaterialSlot(slot.id, slot.displayName, slot.shaderOutputName, SlotType.Input, slot.valueType, slot.defaultValue));
validNames.Add(slot.id);
}
var subGraphOutputNode = subGraphAsset.subGraph.outputNode;
foreach (var slot in subGraphOutputNode.GetInputSlots<MaterialSlot>())
{
AddSlot(new MaterialSlot(slot.id, slot.displayName, slot.shaderOutputName, SlotType.Output, slot.valueType, slot.defaultValue));
validNames.Add(slot.id);
}
RemoveSlotsNameNotMatching(validNames);
}
if (subGraphAsset == null)
if (referencedGraph == null)
return;
var outputString = new ShaderGenerator();

// find out which output slots are actually used
//TODO: Be smarter about this and only output ones that are actually USED, not just connected
//var validOutputSlots = NodeUtils.GetSlotsThatOutputToNodeRecurse(this, (graph as BaseMaterialGraph).masterNode);
foreach (var slot in GetOutputSlots<MaterialSlot>())
{

// Step 3...
// For each input that is used and connects through we want to generate code.
// First we assign the input variables to the subgraph
var subGraphInputNode = subGraphAsset.subGraph.inputNode;
// we do this by renaming the properties to be the names of where the variables come from
// weird, but works.
var sSubGraph = SerializationHelper.Serialize(subGraphAsset.subGraph);
var dSubGraph = SerializationHelper.Deserialize<SubGraph>(sSubGraph, null);
var subGraphInputs = dSubGraph.properties;
var propertyGen = new PropertyCollector();
dSubGraph.CollectShaderProperties(propertyGen, GenerationMode.ForReals);
foreach (var slot in GetInputSlots<MaterialSlot>())
foreach (var prop in subGraphInputs)
var varName = subGraphInputNode.GetVariableNameForSlot(slot.id);
var varValue = GetSlotValue(slot.id, generationMode);
var inSlotId = prop.guid.GetHashCode();
var inSlot = FindInputSlot<MaterialSlot>(inSlotId);
var edges = owner.GetEdges(inSlot.slotReference).ToArray();
var outDimension = ConvertConcreteSlotValueTypeToString(slot.concreteValueType);
outputString.AddShaderChunk(
"float"
+ outDimension
+ " "
+ varName
+ " = "
+ varValue
+ ";", false);
string varValue = inSlot.GetDefaultValue(generationMode);
if (edges.Any())
{
var fromSocketRef = edges[0].outputSlot;
var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(fromSocketRef.nodeGuid);
if (fromNode != null)
{
var slot = fromNode.FindOutputSlot<MaterialSlot>(fromSocketRef.slotId);
if (slot != null)
prop.overrideReferenceName = fromNode.GetSlotValue(slot.id, generationMode);
}
}
else if (inSlot.concreteValueType == ConcreteSlotValueType.Texture2D)
{
prop.overrideReferenceName = MaterialSlot.DefaultTextureName;
}
else
{
var varName = prop.referenceName;
outputString.AddShaderChunk(
ConvertConcreteSlotValueTypeToString(precision, inSlot.concreteValueType)
+ " "
+ varName
+ " = "
+ varValue
+ ";", false);
}
subGraph.GenerateNodeCode(bodyGenerator, GenerationMode.ForReals);
var subGraphOutputNode = subGraphAsset.subGraph.outputNode;
dSubGraph.GenerateNodeCode(bodyGenerator, GenerationMode.ForReals);
var subGraphOutputNode = dSubGraph.outputNode;
outputString.AddShaderChunk(bodyGenerator.GetShaderString(0), false);
// Step 5...

outputString.AddShaderChunk("// Subgraph ends", false);
shaderBodyVisitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
public override void CollectShaderProperties(PropertyCollector visitor, GenerationMode generationMode)
{
base.CollectShaderProperties(visitor, generationMode);
if (subGraph == null)
return;
subGraph.CollectShaderProperties(visitor, GenerationMode.ForReals);
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
if (subGraph == null)
return;
properties.AddRange(subGraph.GetPreviewProperties());
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
if (subGraph == null)
return;
subGraph.GenerateNodeFunction(visitor, GenerationMode.ForReals);
}
public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
if (subGraph == null)
return;
subGraph.GenerateVertexShaderBlock(visitor, GenerationMode.ForReals);
}
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
if (subGraph == null)
return;
subGraph.GenerateVertexToFragmentBlock(visitor, GenerationMode.ForReals);
}
public NeededCoordinateSpace RequiresNormal()
{
if (subGraph == null)
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresNormal();
return mask;
});
}
public bool RequiresMeshUV(UVChannel channel)
{
if (subGraph == null)
return false;
return subGraph.activeNodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel));
}
public bool RequiresScreenPosition()
{
if (subGraph == null)
return false;
return subGraph.activeNodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
}
public NeededCoordinateSpace RequiresViewDirection()
{
if (subGraph == null)
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresViewDirection();
return mask;
});
}
public NeededCoordinateSpace RequiresPosition()
{
if (subGraph == null)
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresPosition();
return mask;
});
}
public NeededCoordinateSpace RequiresTangent()
{
if (subGraph == null)
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresTangent();
return mask;
});
}
public bool RequiresTime()
{
if (subGraph == null)
return false;
return subGraph.activeNodes.OfType<IMayRequireTime>().Any(x => x.RequiresTime());
}
public NeededCoordinateSpace RequiresBitangent()
{
if (subGraph == null)
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresBitangent();
return mask;
});
}
public bool RequiresVertexColor()
{
if (subGraph == null)
return false;
return subGraph.activeNodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
}
}
}

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


RemoveSlot(index);
}
public override bool allowedInRemapGraph { get; } = false;
}
}

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


public void AddShaderProperty(IShaderProperty chunk)
{
if (m_Properties.Any(x => x.name == chunk.name))
if (m_Properties.Any(x => x.referenceName == chunk.referenceName))
return;
m_Properties.Add(chunk);
}

var sb = new StringBuilder();
foreach (var prop in m_Properties)
foreach (var prop in m_Properties.Where(x => x.generatePropertyBlock))
{
for (var i = 0; i < baseIndentLevel; i++)
sb.Append("\t");

foreach (var prop in m_Properties.OfType<TextureShaderProperty>())
{
if (prop.name != null)
if (prop.referenceName != null)
name = prop.name,
name = prop.referenceName,
textureId = prop.value.texture != null ? prop.value.texture.GetInstanceID() : 0,
modifiable = prop.modifiable
};

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


get { return m_ShaderChunks.Count; }
}
public static void GenerateSpaceTranslationPixelShader(
NeededCoordinateSpace neededSpaces,
public static void GenerateStandardTransforms(
int interpolatorStartIndex,
ShaderGenerator interpolators,
ShaderGenerator vertexShader,
string objectSpaceName,
string viewSpaceName,
string worldSpaceName,
string tangentSpaceName,
bool isNormal = false)
{
if ((neededSpaces & NeededCoordinateSpace.Object) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.World) > 0)
{
if (isNormal)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToWorldNormal({1});", worldSpaceName, objectSpaceName), false);
else
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToWorldDir({1});", worldSpaceName, objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.View) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToViewPos({1});", viewSpaceName, objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.Tangent) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = mul(tangentSpaceTransform, {1})", tangentSpaceName, objectSpaceName), false);
}
}
public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements)
ShaderGenerator surfaceInputs,
ShaderGraphRequirements externalGraphRequiements,
ShaderGraphRequirements modelRequiements)
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
// step 1:
// *generate needed interpolators
// *generate output from the vertex shader that writes into these interpolators
// *generate the pixel shader code that declares needed variables in the local scope
var interpolators = new ShaderGenerator();
var vertexShader = new ShaderGenerator();
var pixelShader = new ShaderGenerator();
var combinedRequierments = externalGraphRequiements.Union(modelRequiements);
if (shaderGraphRequirements.requiresNormal > 0 || shaderGraphRequirements.requiresBitangent > 0)
if (combinedRequierments.requiresNormal > 0 || combinedRequierments.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : NORMAL;", ShaderGeneratorNames.ObjectSpaceNormal), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.normal;", ShaderGeneratorNames.ObjectSpaceNormal), false);

if (shaderGraphRequirements.requiresTangent > 0 || shaderGraphRequirements.requiresBitangent > 0)
if (combinedRequierments.requiresTangent > 0 || combinedRequierments.requiresBitangent > 0)
pixelShader.AddShaderChunk(string.Format("float4 {0} = normalize(cross(normalize(IN.{1}), normalize(IN.{2}.xyz)) * IN.{2}.w);",
pixelShader.AddShaderChunk(string.Format("float3 {0} = normalize(cross(normalize(IN.{1}), normalize(IN.{2}.xyz)) * IN.{2}.w);",
ShaderGeneratorNames.ObjectSpaceTangent,
ShaderGeneratorNames.ObjectSpaceNormal), false);
ShaderGeneratorNames.ObjectSpaceNormal,
ShaderGeneratorNames.ObjectSpaceTangent), false);
int interpolatorIndex = 0;
if (shaderGraphRequirements.requiresViewDir > 0)
int interpolatorIndex = interpolatorStartIndex;
if (combinedRequierments.requiresViewDir > 0)
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpaceViewDirection, interpolatorIndex), false);
interpolators.AddShaderChunk(string.Format("float3 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpaceViewDirection, interpolatorIndex), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
if (shaderGraphRequirements.requiresPosition > 0)
if (combinedRequierments.requiresPosition > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpacePosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.vertex;", ShaderGeneratorNames.ObjectSpacePosition), false);

if (shaderGraphRequirements.NeedsTangentSpace())
if (combinedRequierments.NeedsTangentSpace())
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresNormal, pixelShader,
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresNormal, pixelShader,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal, Dimension.Three, true);
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresTangent, pixelShader,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent, Dimension.Three);
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresBitangent, pixelShader,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent, Dimension.Three);
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresViewDir, pixelShader,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection, Dimension.Three);
ShaderGenerator.GenerateSpaceTranslationPixelShader(combinedRequierments.requiresPosition, pixelShader,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition, Dimension.Three);
if (combinedRequierments.requiresVertexColor)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
}
if (combinedRequierments.requiresScreenPosition)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(UnityObjectToClipPos(v.vertex));", ShaderGeneratorNames.ScreenPosition), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
interpolatorIndex++;
}
foreach (var channel in combinedRequierments.requiresMeshUVs.Distinct())
{
interpolators.AddShaderChunk(string.Format("half4 {0} : TEXCOORD{1};", channel.GetUVName(), interpolatorIndex == 0 ? "" : interpolatorIndex.ToString()), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.texcoord{1};", channel.GetUVName(), (int)channel), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", channel.GetUVName()), false);
interpolatorIndex++;
}
// step 2
// copy the locally defined values into the surface description
// structure using the requirements for ONLY the shader graph
// additional requirements have come from the lighting model
// and are not needed in the shader graph
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresNormal, surfaceInputs,
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresTangent, pixelShader,
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresTangent, surfaceInputs,
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresBitangent, pixelShader,
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresBitangent, surfaceInputs,
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresViewDir, pixelShader,
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresViewDir, surfaceInputs,
GenerateSpaceTranslationPixelShader(shaderGraphRequirements.requiresPosition, pixelShader,
ShaderGenerator.GenerateCopyToSurfaceInputs(externalGraphRequiements.requiresPosition, surfaceInputs,
if (shaderGraphRequirements.requiresVertexColor)
if (externalGraphRequiements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", ShaderGeneratorNames.VertexColor), false);
if (externalGraphRequiements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", ShaderGeneratorNames.ScreenPosition), false);
foreach (var channel in combinedRequierments.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("surfaceInput.{0} ={0};", channel.GetUVName()), false);
}
public enum Dimension
{
One,
Two,
Three,
Four
}
private static string DimensionToString(Dimension d)
{
switch (d)
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
case Dimension.One:
return string.Empty;
case Dimension.Two:
return "2";
case Dimension.Three:
return "3";
case Dimension.Four:
return "4";
return "error";
}
if (shaderGraphRequirements.requiresScreenPosition)
public static void GenerateSpaceTranslationPixelShader(
NeededCoordinateSpace neededSpaces,
ShaderGenerator pixelShader,
string objectSpaceName,
string viewSpaceName,
string worldSpaceName,
string tangentSpaceName,
Dimension dimension,
bool isNormal = false)
{
if ((neededSpaces & NeededCoordinateSpace.World) > 0)
{
if (isNormal)
pixelShader.AddShaderChunk(string.Format("float{0} {1} = UnityObjectToWorldNormal({2});", DimensionToString(dimension), worldSpaceName, objectSpaceName), false);
else
pixelShader.AddShaderChunk(string.Format("float{0} {1} = UnityObjectToWorldDir({2});", DimensionToString(dimension), worldSpaceName, objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.View) > 0)
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};;", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(UnityObjectToClipPos(v.vertex)", ShaderGeneratorNames.ScreenPosition), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
interpolatorIndex++;
pixelShader.AddShaderChunk(string.Format("float{0} {1} = UnityObjectToViewPos({2});", DimensionToString(dimension), viewSpaceName, objectSpaceName), false);
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
if ((neededSpaces & NeededCoordinateSpace.Tangent) > 0)
var channel = (UVChannel) uvIndex;
if (activeNodeList.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
{
interpolators.AddShaderChunk(string.Format("half4 meshUV{0} : TEXCOORD{1};", uvIndex, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.meshUV{0} = v.texcoord{1};", uvIndex, uvIndex), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.meshUV{1};", channel.GetUVName(), uvIndex), false);
interpolatorIndex++;
}
pixelShader.AddShaderChunk(string.Format("float{0} {1} = mul(tangentSpaceTransform, {2})", DimensionToString(dimension), tangentSpaceName, objectSpaceName), false);
}
public static void GenerateCopyToSurfaceInputs(
NeededCoordinateSpace neededSpaces,
ShaderGenerator pixelShader,
string objectSpaceName,
string viewSpaceName,
string worldSpaceName,
string tangentSpaceName)
{
if ((neededSpaces & NeededCoordinateSpace.Object) > 0)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", objectSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.World) > 0)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", worldSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.View) > 0)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0};", viewSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.Tangent) > 0)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = {0}", tangentSpaceName), false);
}
public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements)
{
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
var interpolators = new ShaderGenerator();
var vertexShader = new ShaderGenerator();
var pixelShader = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
ShaderGenerator.GenerateStandardTransforms(
0,
interpolators,
vertexShader,
pixelShader,
surfaceInputs,
shaderGraphRequirements,
ShaderGraphRequirements.none);
var outputs = new ShaderGenerator();
var outputSlot = node.GetOutputSlots<MaterialSlot>().FirstOrDefault();

else
outputs.AddShaderChunk("return 0;", true);
var res = subShaderTemplate.Replace("{0}", interpolators.GetShaderString(0));
res = res.Replace("{1}", vertexShader.GetShaderString(0));
res = res.Replace("{2}", pixelShader.GetShaderString(0));
res = res.Replace("{3}", outputs.GetShaderString(0));
var res = subShaderTemplate.Replace("${Interpolators}", interpolators.GetShaderString(0));
res = res.Replace("${VertexShader}", vertexShader.GetShaderString(0));
res = res.Replace("${LocalPixelShader}", pixelShader.GetShaderString(0));
res = res.Replace("${SurfaceInputs}", surfaceInputs.GetShaderString(0));
res = res.Replace("${SurfaceOutputRemap}", outputs.GetShaderString(0));
return res;
}

struct GraphVertexOutput
{
float4 position : POSITION;
{0}
${Interpolators}
};
GraphVertexOutput vert (GraphVertexInput v)

GraphVertexOutput o;
o.position = UnityObjectToClipPos(v.vertex);
{1}
${VertexShader}
SurfaceInputs surfaceInput;
{2}
${LocalPixelShader}
SurfaceInputs surfaceInput = (SurfaceInputs)0;;
${SurfaceInputs}
{3}
${SurfaceOutputRemap}
}
ENDCG
}

23
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporter.cs


using System.IO;
using System.Text;
using UnityEditor.Experimental.AssetImporters;
using UnityEngine;
using UnityEngine.MaterialGraph;
[ScriptedImporter(1, "ShaderRemapGraph")]
public class MasterRemapGraphImporter : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
{
var textGraph = File.ReadAllText(ctx.assetPath, Encoding.UTF8);
var graph = JsonUtility.FromJson<MasterRemapGraph>(textGraph);
if (graph == null)
return;
var graphAsset = ScriptableObject.CreateInstance<MasterRemapGraphAsset>();
graphAsset.remapGraph = graph;
ctx.AddObjectToAsset("MainAsset", graphAsset);
ctx.SetMainObject(graphAsset);
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporter.cs.meta


fileFormatVersion: 2
guid: 47e38a0256e24cec8792d9cfae7023b2
timeCreated: 1506845544

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


using UnityEditor;
using UnityEditor.Experimental.AssetImporters;
using UnityEditor.MaterialGraph.Drawing;
using UnityEngine;
using Debug = System.Diagnostics.Debug;
[CustomEditor(typeof(MasterRemapGraphImporter))]
public class MasterRemapGraphImporterEditor : ScriptedImporterEditor
{
public override void OnInspectorGUI()
{
if (GUILayout.Button("Open Shader Editor"))
{
AssetImporter importer = target as AssetImporter;
Debug.Assert(importer != null, "importer != null");
ShowGraphEditWindow(importer.assetPath);
}
}
private static void ShowGraphEditWindow(string path)
{
var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
var windows = Resources.FindObjectsOfTypeAll<MasterReampGraphEditWindow>();
bool foundWindow = false;
foreach (var w in windows)
{
if (w.selected == asset)
{
foundWindow = true;
w.Focus();
}
}
if (!foundWindow)
{
var window = CreateInstance<MasterReampGraphEditWindow>();
window.Show();
window.ChangeSelection(asset);
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporterEditor.cs.meta


fileFormatVersion: 2
guid: 4dd321ee05034e7a967503617a02c1f4
timeCreated: 1506845783

10
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/IMasterNode.cs


using System.Collections.Generic;
namespace UnityEngine.MaterialGraph
{
public interface IMasterNode
{
SurfaceMaterialOptions options { get; }
IEnumerable<string> GetSubshader(ShaderGraphRequirements graphRequirements, MasterRemapGraph remapper);
}
}

11
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/IMasterNode.cs.meta


fileFormatVersion: 2
guid: 570cf3dfbfc001e46a74d5f1342a3cfc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

15
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapGraphAsset.cs


namespace UnityEngine.MaterialGraph
{
public class MasterRemapGraphAsset : ScriptableObject
{
[SerializeField]
private MasterRemapGraph m_RemapGraph = new MasterRemapGraph();
public MasterRemapGraph remapGraph
{
get { return m_RemapGraph; }
set { m_RemapGraph = value; }
}
}
}

65
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraph.cs


using System;
using System.Collections.Generic;
using System.Linq;
namespace UnityEngine.MaterialGraph
{
[Serializable]
public class AbstractSubGraph : AbstractMaterialGraph
, IGeneratesBodyCode
, IGeneratesFunction
{
public virtual IEnumerable<AbstractMaterialNode> activeNodes { get; }
public PreviewMode previewMode
{
get { return activeNodes.Any(x => x.previewMode == PreviewMode.Preview3D) ? PreviewMode.Preview3D : PreviewMode.Preview2D; }
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in activeNodes)
{
if (node is IGeneratesBodyCode)
(node as IGeneratesBodyCode).GenerateNodeCode(visitor, generationMode);
}
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in activeNodes)
{
if (node is IGeneratesFunction)
(node as IGeneratesFunction).GenerateNodeFunction(visitor, generationMode);
}
}
public override void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
{
// if we are previewing the graph we need to
// export 'exposed props' if we are 'for real'
// then we are outputting the graph in the
// nested context and the needed values will
// be copied into scope.
if (generationMode == GenerationMode.Preview)
{
foreach (var prop in properties)
collector.AddShaderProperty(prop);
}
foreach (var node in activeNodes)
{
if (node is IGenerateProperties)
(node as IGenerateProperties).CollectShaderProperties(collector, generationMode);
}
}
public IEnumerable<PreviewProperty> GetPreviewProperties()
{
List<PreviewProperty> props = new List<PreviewProperty>();
foreach (var node in activeNodes)
node.CollectPreviewMaterialProperties(props);
return props;
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraph.cs.meta


fileFormatVersion: 2
guid: f2b67435729448498da7e7b90f052ebd
timeCreated: 1506844687

229
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
public abstract class AbstractSubGraphNode : AbstractMaterialNode
, IGeneratesFunction
, IOnAssetEnabled
, IMayRequireNormal
, IMayRequireTangent
, IMayRequireBitangent
, IMayRequireMeshUV
, IMayRequireScreenPosition
, IMayRequireViewDirection
, IMayRequirePosition
, IMayRequireVertexColor
, IMayRequireTime
{
protected virtual AbstractSubGraph referencedGraph { get; }
public override bool hasPreview
{
get { return referencedGraph != null; }
}
public override PreviewMode previewMode
{
get
{
if (referencedGraph == null)
return PreviewMode.Preview2D;
return PreviewMode.Preview3D;
}
}
public virtual INode outputNode { get; } = null;
public virtual void OnEnable()
{
var validNames = new List<int>();
if (referencedGraph == null)
{
RemoveSlotsNameNotMatching(validNames);
return;
}
var props = referencedGraph.properties;
foreach (var prop in props)
{
var propType = prop.propertyType;
SlotValueType slotType;
switch (propType)
{
case PropertyType.Color:
slotType = SlotValueType.Vector4;
break;
case PropertyType.Texture:
slotType = SlotValueType.Texture2D;
break;
case PropertyType.Float:
slotType = SlotValueType.Vector1;
break;
case PropertyType.Vector2:
slotType = SlotValueType.Vector2;
break;
case PropertyType.Vector3:
slotType = SlotValueType.Vector3;
break;
case PropertyType.Vector4:
slotType = SlotValueType.Vector4;
break;
case PropertyType.Matrix2:
slotType = SlotValueType.Matrix2;
break;
case PropertyType.Matrix3:
slotType = SlotValueType.Matrix3;
break;
case PropertyType.Matrix4:
slotType = SlotValueType.Matrix4;
break;
default:
throw new ArgumentOutOfRangeException();
}
var id = prop.guid.GetHashCode();
AddSlot(new MaterialSlot(id, prop.displayName, prop.referenceName, SlotType.Input, slotType, prop.defaultValue));
validNames.Add(id);
}
var subGraphOutputNode = outputNode;
if (outputNode != null)
{
foreach (var slot in subGraphOutputNode.GetInputSlots<MaterialSlot>())
{
AddSlot(new MaterialSlot(slot.id, slot.displayName, slot.shaderOutputName, SlotType.Output, slot.valueType, slot.defaultValue));
validNames.Add(slot.id);
}
}
RemoveSlotsNameNotMatching(validNames);
}
public override void CollectShaderProperties(PropertyCollector visitor, GenerationMode generationMode)
{
base.CollectShaderProperties(visitor, generationMode);
if (referencedGraph == null)
return;
referencedGraph.CollectShaderProperties(visitor, GenerationMode.ForReals);
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
if (referencedGraph == null)
return;
properties.AddRange(referencedGraph.GetPreviewProperties());
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
if (referencedGraph == null)
return;
referencedGraph.GenerateNodeFunction(visitor, GenerationMode.ForReals);
}
public NeededCoordinateSpace RequiresNormal()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresNormal();
return mask;
});
}
public bool RequiresMeshUV(UVChannel channel)
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel));
}
public bool RequiresScreenPosition()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
}
public NeededCoordinateSpace RequiresViewDirection()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresViewDirection();
return mask;
});
}
public NeededCoordinateSpace RequiresPosition()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresPosition();
return mask;
});
}
public NeededCoordinateSpace RequiresTangent()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresTangent();
return mask;
});
}
public bool RequiresTime()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireTime>().Any(x => x.RequiresTime());
}
public NeededCoordinateSpace RequiresBitangent()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresBitangent();
return mask;
});
}
public bool RequiresVertexColor()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphNode.cs.meta


fileFormatVersion: 2
guid: bc4cf774a7a6480ba543eb6069cd1c50
timeCreated: 1506847426

98
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MasterRemapNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
[Title("Master/Remap-Node")]
public class MasterRemapNode : AbstractSubGraphNode, IMasterNode
{
[SerializeField]
protected SurfaceMaterialOptions m_MaterialOptions = new SurfaceMaterialOptions();
public SurfaceMaterialOptions options
{
get { return m_MaterialOptions; }
}
public virtual PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
[SerializeField]
private string m_SerializedRemapGraph = string.Empty;
[Serializable]
private class RemapGraphHelper
{
public MasterRemapGraphAsset remapGraph;
}
protected override AbstractSubGraph referencedGraph
{
get
{
if (remapGraphAsset == null)
return null;
return remapGraphAsset.remapGraph;
}
}
#if UNITY_EDITOR
public MasterRemapGraphAsset remapGraphAsset
{
get
{
if (string.IsNullOrEmpty(m_SerializedRemapGraph))
return null;
var helper = new RemapGraphHelper();
EditorJsonUtility.FromJsonOverwrite(m_SerializedRemapGraph, helper);
return helper.remapGraph;
}
set
{
if (remapGraphAsset == value)
return;
var helper = new RemapGraphHelper();
helper.remapGraph = value;
m_SerializedRemapGraph = EditorJsonUtility.ToJson(helper, true);
OnEnable();
if (onModified != null)
onModified(this, ModificationScope.Topological);
}
}
#else
public MaterialSubGraphAsset subGraphAsset {get; set; }
#endif
public MasterRemapNode()
{
name = "RemapMaster";
}
public IEnumerable<string> GetSubshader(ShaderGraphRequirements graphRequirements, MasterRemapGraph remapper)
{
if (referencedGraph == null)
return new string[]{};
var masterNodes = referencedGraph.activeNodes.OfType<IMasterNode>().ToList();
if (masterNodes.Count == 0)
return new string[]{};
var results = new List<string>();
foreach (var master in masterNodes)
results.AddRange(master.GetSubshader(graphRequirements, referencedGraph as MasterRemapGraph));
return results;
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MasterRemapNode.cs.meta


fileFormatVersion: 2
guid: 861139fc6f60415cae2eb9a9625aaeb8
timeCreated: 1506873607

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeInspectors/SubgraphInputNodeInspector.cs.meta


fileFormatVersion: 2
guid: cd0ffd0e21a6644488dda4d0470a30c6
timeCreated: 1483808306
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

85
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeInspectors/SubgraphInputNodeInspector.cs


using System.Linq;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph.Drawing
{
public class SubgraphInputNodeInspector : BasicNodeInspector
{
protected enum UISlotValueType
{
Vector4,
Vector3,
Vector2,
Vector1
}
private static UISlotValueType ToUISlot(SlotValueType slot)
{
switch (slot)
{
case SlotValueType.Vector1:
return UISlotValueType.Vector1;
case SlotValueType.Vector2:
return UISlotValueType.Vector2;
case SlotValueType.Vector3:
return UISlotValueType.Vector3;
case SlotValueType.Vector4:
return UISlotValueType.Vector4;
}
return UISlotValueType.Vector4;
}
private static SlotValueType ToSlotValueType(UISlotValueType slot)
{
switch (slot)
{
case UISlotValueType.Vector1:
return SlotValueType.Vector1;
case UISlotValueType.Vector2:
return SlotValueType.Vector2;
case UISlotValueType.Vector3:
return SlotValueType.Vector3;
case UISlotValueType.Vector4:
return SlotValueType.Vector4;
}
return SlotValueType.Vector4;
}
protected override ModificationScope DoSlotsUI()
{
var slots = node.GetSlots<MaterialSlot>();
if (!slots.Any())
return ModificationScope.Node;
GUILayout.Label("Default Slot Values", EditorStyles.boldLabel);
bool valueChanged = false;
bool typeChanged = false;
foreach (var slot in node.GetSlots<MaterialSlot>())
{
EditorGUI.BeginChangeCheck();
GUILayout.Label(slot.displayName);
slot.currentValue = EditorGUILayout.Vector4Field("", slot.currentValue);
if (EditorGUI.EndChangeCheck())
valueChanged |= true;
EditorGUI.BeginChangeCheck();
var result = (UISlotValueType)EditorGUILayout.EnumPopup(ToUISlot(slot.valueType));
slot.valueType = ToSlotValueType(result);
if (EditorGUI.EndChangeCheck())
typeChanged |= true;
}
GUILayout.Space(10);
if (typeChanged)
return ModificationScope.Topological;
if (valueChanged)
return ModificationScope.Node;
return ModificationScope.Node;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapInputNode.cs.meta


fileFormatVersion: 2
guid: 39465109a68463a4b8a1a9c9dd20e46a
timeCreated: 1481188026
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/RemapMasterNode.cs.meta


fileFormatVersion: 2
guid: 8f94baf06fa91ad41bc0184e6d14cb0f
timeCreated: 1481188026
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

93
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapInputNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
/*
[Title("Remapper/Remap Input Node")]
public class MasterRemapInputNode : AbstractSubGraphIONode
, INodeGroupRemapper
{
[NonSerialized]
internal RemapMasterNode m_RemapTarget;
public MasterRemapInputNode()
{
name = "Inputs";
}
public override int AddSlot()
{
var nextSlotId = GetOutputSlots<ISlot>().Count() + 1;
AddSlot(new MaterialSlot(-nextSlotId, "Input " + nextSlotId, "Input" + nextSlotId, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
return -nextSlotId;
}
public override void RemoveSlot()
{
var lastSlotId = GetOutputSlots<ISlot>().Count();
if (lastSlotId == 0)
return;
RemoveSlot(-lastSlotId);
}
public void DepthFirstCollectNodesFromNodeSlotList(List<INode> nodeList, NodeUtils.IncludeSelf includeSelf)
{
NodeUtils.DepthFirstCollectNodesFromNode(nodeList, m_RemapTarget, NodeUtils.IncludeSelf.Exclude);
}
public bool IsValidSlotConnection(int slotId)
{
if (m_RemapTarget == null)
return false;
var slot = m_RemapTarget.FindSlot<MaterialSlot>(slotId);
if (slot == null)
return false;
var edge = m_RemapTarget.owner.GetEdges(slot.slotReference).FirstOrDefault();
if (edge == null)
return false;
var outputRef = edge.outputSlot;
var fromNode = m_RemapTarget.owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
if (fromNode == null)
return false;
return true;
}
public override string GetVariableNameForSlot(int slotId)
{
if (m_RemapTarget == null)
{
var defaultValueSlot = FindSlot<MaterialSlot>(slotId);
if (defaultValueSlot == 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 defaultValueSlot.GetDefaultValue(GenerationMode.ForReals);
}
var slot = m_RemapTarget.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");
if (slot.isOutputSlot)
throw new Exception(string.Format("Attempting to use OutputSlot({0}) on remap node)", slotId));
var edge = m_RemapTarget.owner.GetEdges(slot.slotReference).FirstOrDefault();
if (edge == null)
return slot.GetDefaultValue(GenerationMode.ForReals);
var outputRef = edge.outputSlot;
var fromNode = m_RemapTarget.owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
if (fromNode == null)
return slot.GetDefaultValue(GenerationMode.ForReals);
return fromNode.GetVariableNameForSlot(outputRef.slotId);
}
}*/
}

22
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MaterialRemapAsset.cs


using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
/* public class MaterialRemapAsset : AbstractMaterialGraphAsset
{
[SerializeField]
private MasterRemapGraph m_MasterRemapGraph = new MasterRemapGraph();
public override IGraph graph
{
get { return m_MasterRemapGraph; }
}
public MasterRemapGraph masterRemapGraph
{
get { return m_MasterRemapGraph; }
}
}*/
}

140
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/RemapMasterNode.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
/* [Serializable]
[Title("Master/Remapper")]
public class RemapMasterNode : AbstractMasterNode
, IOnAssetEnabled
{
[SerializeField]
private string m_SerialziedRemapGraph = string.Empty;
[Serializable]
private class RemapGraphHelper
{
public MaterialRemapAsset subGraph;
}
public override bool allowedInRemapGraph
{
get { return false; }
}
public override string GetFullShader(GenerationMode mode, string name, out List<PropertyGenerator.TextureInfo> configuredTextures)
{
var shaderTemplateLocation = ShaderGenerator.GetTemplatePath("shader.template");
if (remapAsset == null || !File.Exists(shaderTemplateLocation))
{
configuredTextures = new List<PropertyGenerator.TextureInfo>();
return string.Empty;
}
var shaderPropertiesVisitor = new PropertyGenerator();
// Step 1: Set this node as the remap target
// Pass in the shader properties visitor here as
// high level properties are shared
// this is only used for the header
var subShaders = remapAsset.masterRemapGraph.GetSubShadersFor(this, mode, shaderPropertiesVisitor);
var templateText = File.ReadAllText(shaderTemplateLocation);
var resultShader = templateText.Replace("${ShaderName}", name);
resultShader = resultShader.Replace("${ShaderPropertiesHeader}", shaderPropertiesVisitor.GetShaderString(2));
if (subShaders != null)
resultShader = resultShader.Replace("${SubShader}", subShaders.Aggregate(string.Empty, (i, j) => i + Environment.NewLine + j));
else
resultShader = resultShader.Replace("${SubShader}", string.Empty);
configuredTextures = shaderPropertiesVisitor.GetConfiguredTexutres();
return Regex.Replace(resultShader, @"\r\n|\n\r|\n|\r", Environment.NewLine);
}
public override string GetSubShader(GenerationMode mode, PropertyGenerator shaderPropertiesVisitor)
{
throw new NotImplementedException();
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
if (remapAsset == null)
return;
remapAsset.masterRemapGraph.CollectPreviewMaterialProperties(properties);
}
#if UNITY_EDITOR
public MaterialRemapAsset remapAsset
{
get
{
if (string.IsNullOrEmpty(m_SerialziedRemapGraph))
return null;
var helper = new RemapGraphHelper();
EditorJsonUtility.FromJsonOverwrite(m_SerialziedRemapGraph, helper);
return helper.subGraph;
}
set
{
if (remapAsset == value)
return;
var helper = new RemapGraphHelper();
helper.subGraph = value;
m_SerialziedRemapGraph = EditorJsonUtility.ToJson(helper, true);
OnEnable();
if (onModified != null)
onModified(this, ModificationScope.Topological);
}
}
#else
public MaterialSubGraphAsset subGraphAsset {get; set; }
#endif
public override PreviewMode previewMode
{
get
{
if (remapAsset == null)
return PreviewMode.Preview2D;
return PreviewMode.Preview3D;
}
}
public RemapMasterNode()
{
name = "Remapper";
}
public void OnEnable()
{
var validNames = new List<int>();
if (remapAsset == null)
{
RemoveSlotsNameNotMatching(validNames);
return;
}
var inputNode = remapAsset.masterRemapGraph.inputNode;
foreach (var slot in inputNode.GetOutputSlots<MaterialSlot>())
{
AddSlot(new MaterialSlot(slot.id, slot.displayName, slot.shaderOutputName, SlotType.Input, slot.valueType, slot.defaultValue));
validNames.Add(slot.id);
}
RemoveSlotsNameNotMatching(validNames);
}
}*/
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs.meta


fileFormatVersion: 2
guid: efdb88070ae74e94a9ed2f6ac04e6862
timeCreated: 1465559219
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
public class SubGraphInputNode : AbstractSubGraphIONode
{
public SubGraphInputNode()
{
name = "SubGraphInputs";
}
public override int AddSlot()
{
var nextSlotId = GetOutputSlots<ISlot>().Count() + 1;
AddSlot(new MaterialSlot(-nextSlotId, "Input " + nextSlotId, "Input" + nextSlotId, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
return -nextSlotId;
}
public override void RemoveSlot()
{
var lastSlotId = GetOutputSlots<ISlot>().Count();
if (lastSlotId == 0)
return;
RemoveSlot(-lastSlotId);
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
if (!generationMode.IsPreview())
return;
foreach (var slot in GetOutputSlots<MaterialSlot>())
{
IShaderProperty property;
switch (slot.concreteValueType)
{
case ConcreteSlotValueType.Vector4:
property = new Vector4ShaderProperty();
break;
case ConcreteSlotValueType.Vector3:
property = new Vector3ShaderProperty();
break;
case ConcreteSlotValueType.Vector2:
property = new Vector2ShaderProperty();
break;
case ConcreteSlotValueType.Vector1:
property = new FloatShaderProperty();
break;
default:
throw new ArgumentOutOfRangeException();
}
property.generatePropertyBlock = false;
properties.AddShaderProperty(property);
}
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
foreach (var s in GetOutputSlots<MaterialSlot>())
{
properties.Add
(
new PreviewProperty
{
m_Name = GetVariableNameForSlot(s.id),
m_PropType = ConvertConcreteSlotValueTypeToPropertyType(s.concreteValueType),
m_Vector4 = s.currentValue,
m_Float = s.currentValue.x,
m_Color = s.currentValue
}
);
}
}
}
}

/MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MaterialRemapAsset.cs.meta → /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapGraphAsset.cs.meta

正在加载...
取消
保存