浏览代码

Merge branch 'master' into node-matrix

/main
Matt Dean 6 年前
当前提交
3df359f2
共有 43 个文件被更改,包括 640 次插入161 次删除
  1. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateShaderSubGraph.cs
  2. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs
  3. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/AbstractMaterialNode.cs
  4. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/AbsoluteNode.cs
  5. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ExponentialNode.cs
  6. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/LengthNode.cs
  7. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/LogNode.cs
  8. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ModuloNode.cs
  9. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/NegateNode.cs
  10. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/NormalizeNode.cs
  11. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/PosterizeNode.cs
  12. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ReciprocalNode.cs
  13. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ReciprocalSquareRootNode.cs
  14. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/AddNode.cs
  15. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/DivideNode.cs
  16. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/MultiplyNode.cs
  17. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/PowerNode.cs
  18. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/SquareRootNode.cs
  19. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/SubtractNode.cs
  20. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/RandomRangeNode.cs
  21. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/MasterPreviewView.cs
  22. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs
  23. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
  24. 44
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs
  25. 239
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs
  26. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/PortInputView.cs
  27. 53
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss
  28. 4
      MaterialGraphProject/Assets/UnityShaderEditor/package.json
  29. 23
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreatePBRShaderGraph.cs
  30. 23
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateUnlitShaderGraph.cs
  31. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateUnlitShaderGraph.cs.meta
  32. 58
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Noise/GradientNoiseNode.cs
  33. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Noise/GradientNoiseNode.cs.meta
  34. 34
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Scrollable.cs
  35. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Scrollable.cs.meta
  36. 59
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/PixelCacheProfilerView.cs
  37. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/PixelCacheProfilerView.cs.meta
  38. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/PixelCacheProfiler.uss
  39. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/PixelCacheProfiler.uss.meta
  40. 39
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/UXML/PixelCacheProfiler.uxml
  41. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/UXML/PixelCacheProfiler.uxml.meta
  42. 23
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateShaderGraph.cs
  43. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreatePBRShaderGraph.cs.meta

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


{
public class CreateShaderSubGraph : EndNameEditAction
{
[MenuItem("Assets/Create/Shader Sub Graph", false, 208)]
[MenuItem("Assets/Create/Shader/Sub Graph", false, 208)]
public static void CreateMaterialSubGraph()
{
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance<CreateShaderSubGraph>(),

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


[NonSerialized]
public Quaternion rotation = Quaternion.identity;
[NonSerialized]
public float scale = 1f;
}
}

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


set { m_Name = value; }
}
public virtual string documentationURL
{
get { return null; }
}
public virtual bool canDeleteNode
{
get { return true; }

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


name = "Absolute";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Absolute-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Absolute", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Exponential";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Exponential-Node"; }
}
[SerializeField]
private ExponentialBase m_ExponentialBase = ExponentialBase.BaseE;

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


name = "Length";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Length-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Length", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Log";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Log-Node"; }
}
[SerializeField]
private LogBase m_LogBase = LogBase.BaseE;

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ModuloNode.cs


name = "Modulo";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Modulo-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Modulo", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Negate";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Negate-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Negate", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Normalize";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Normalize-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Normalize", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Posterize";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Posterize-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Posterize", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Reciprocal";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Reciprocal-Node"; }
}
[SerializeField]
private ReciprocalMethod m_ReciprocalMethod = ReciprocalMethod.Default;

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Advanced/ReciprocalSquareRootNode.cs


name = "Reciprocal Square Root";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Reciprocal-Square-Root-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Rsqrt", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Add";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Add-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Add", BindingFlags.Static | BindingFlags.NonPublic);

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Basic/DivideNode.cs


name = "Divide";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Divide-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Divide", BindingFlags.Static | BindingFlags.NonPublic);

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


UpdateNodeAfterDeserialization();
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Multiply-Node"; }
}
const int Input1SlotId = 0;
const int Input2SlotId = 1;
const int OutputSlotId = 2;

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


name = "Power";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Power-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Power", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Square Root";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Square-Root-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_SquareRoot", BindingFlags.Static | BindingFlags.NonPublic);

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


name = "Subtract";
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Subtract-Node"; }
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_Subtract", BindingFlags.Static | BindingFlags.NonPublic);

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Math/Range/RandomRangeNode.cs


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

}
static string Unity_RandomRange(
[Slot(0, Binding.None)] Vector1 Seed,
[Slot(0, Binding.None)] Vector2 Seed,
[Slot(1, Binding.None)] Vector1 Min,
[Slot(2, Binding.None, 1, 1, 1, 1)] Vector1 Max,
[Slot(3, Binding.None)] out Vector1 Out)

{
{precision} randomno = frac(sin(dot({precision}2(Seed, Seed), float2(12.9898, 78.233)))*43758.5453);
Out = floor(randomno * (Max - Min + 1)) + Min;
{precision} randomno = frac(sin(dot(Seed, float2(12.9898, 78.233)))*43758.5453);
Out = lerp(Min, Max, randomno);
}";
}
}

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/MasterPreviewView.cs


m_PreviewScrollPosition = new Vector2(0f, 0f);
middleContainer.Add(m_PreviewTextureView);
middleContainer.AddManipulator(new Scrollable(OnScroll));
void OnScroll(float scrollValue)
{
float rescaleAmount = -scrollValue * .03f;
m_Graph.previewData.scale = Mathf.Clamp(m_Graph.previewData.scale + rescaleAmount, 0.2f, 5f);
}
{
{
foreach (var primitiveTypeName in Enum.GetNames(typeof(PrimitiveType)))
{
if(m_DoNotShowPrimitives.Contains(primitiveTypeName))

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


{
var mesh = m_Graph.previewData.serializedMesh.mesh ? m_Graph.previewData.serializedMesh.mesh : m_SceneResources.sphere;
var previewTransform = Matrix4x4.Rotate(m_Graph.previewData.rotation);
previewTransform *= Matrix4x4.Scale(Vector3.one * (Vector3.one).magnitude / mesh.bounds.size.magnitude);
var scale = m_Graph.previewData.scale;
previewTransform *= Matrix4x4.Scale(scale * Vector3.one * (Vector3.one).magnitude / mesh.bounds.size.magnitude);
previewTransform *= Matrix4x4.Translate(-mesh.bounds.center);
RenderPreview(masterRenderData, mesh, previewTransform);
}

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


m_GraphView.RegisterCallback<KeyDownEvent>(OnSpaceDown);
content.Add(m_GraphView);
// Uncomment to enable pixel caching profiler
// m_ProfilerView = new PixelCacheProfilerView(this);
// m_GraphView.Add(m_ProfilerView);
m_BlackboardProvider = new BlackboardProvider(assetName, graph);
m_GraphView.Add(m_BlackboardProvider.blackboard);
m_BlackboardProvider.blackboard.layout = new Rect(new Vector2(10f, 10f), m_BlackboardProvider.blackboard.layout.size);

graphView.nodeCreationRequest(new NodeCreationContext() { screenMousePosition = screenPoint });
}
else if (evt.keyCode == KeyCode.F1)
{
if (m_GraphView.selection.OfType<MaterialNodeView>().Count() == 1)
{
var nodeView = (MaterialNodeView)graphView.selection.First();
if(nodeView.node.documentationURL != null)
System.Diagnostics.Process.Start(nodeView.node.documentationURL);
}
}
}
GraphViewChange GraphViewChanged(GraphViewChange graphViewChange)

node.UpdatePortInputVisibilities();
UpdateEdgeColors(nodesToUpdate);
if (m_ProfilerView != null)
m_ProfilerView.Profile();
}
void AddNode(INode node)

}
Stack<MaterialNodeView> m_NodeStack = new Stack<MaterialNodeView>();
PixelCacheProfilerView m_ProfilerView;
void UpdateEdgeColors(HashSet<MaterialNodeView> nodeViews)
{

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


evt.menu.AppendAction("Convert To Sub-graph", ConvertToSubgraph, ConvertToSubgraphStatus);
evt.menu.AppendAction("Convert To Inline Node", ConvertToInlineNode, ConvertToInlineNodeStatus);
evt.menu.AppendAction("Convert To Property", ConvertToProperty, ConvertToPropertyStatus);
if (selection.OfType<MaterialNodeView>().Count() == 1)
{
evt.menu.AppendSeparator();
evt.menu.AppendAction("Open Documentation", SeeDocumentation, SeeDocumentationStatus);
}
if (evt.target is MaterialGraphView)
{
evt.menu.AppendAction("Collapse Previews", CollapsePreviews, ContextualMenu.MenuAction.AlwaysEnabled);
evt.menu.AppendAction("Expand Previews", ExpandPreviews, ContextualMenu.MenuAction.AlwaysEnabled);
evt.menu.AppendSeparator();
}
}
void CollapsePreviews(EventBase evt)
{
graph.owner.RegisterCompleteObjectUndo("Collapse Previews");
foreach (AbstractMaterialNode node in graph.GetNodes<AbstractMaterialNode>())
{
node.previewExpanded = false;
}
}
void ExpandPreviews(EventBase evt)
{
graph.owner.RegisterCompleteObjectUndo("Expand Previews");
foreach (AbstractMaterialNode node in graph.GetNodes<AbstractMaterialNode>())
{
node.previewExpanded = true;
}
}
void SeeDocumentation(EventBase evt)
{
var node = selection.OfType<MaterialNodeView>().First().node;
if (node.documentationURL != null)
System.Diagnostics.Process.Start(node.documentationURL);
}
ContextualMenu.MenuAction.StatusFlags SeeDocumentationStatus(EventBase eventBase)
{
if (selection.OfType<MaterialNodeView>().First().node.documentationURL == null)
return ContextualMenu.MenuAction.StatusFlags.Disabled;
return ContextualMenu.MenuAction.StatusFlags.Normal;
}
ContextualMenu.MenuAction.StatusFlags ConvertToPropertyStatus(EventBase eventBase)

graph.RemoveShaderProperty(property.guid);
}
}
selection.Clear();
}
public bool CanAcceptDrop(List<ISelectable> selection)

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


using UnityEngine.Experimental.UIElements;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine.Experimental.UIElements.StyleEnums;
using Node = UnityEditor.Experimental.UIElements.GraphView.Node;
namespace UnityEditor.ShaderGraph.Drawing

List<VisualElement> m_ControlViews;
PreviewTextureView m_PreviewTextureView;
VisualElement m_ControlsContainer;
Image m_PreviewImage;
List<Attacher> m_Attachers;
VisualElement m_ControlItems;
VisualElement m_PreviewFiller;
VisualElement m_PortInputContainer;
public void Initialize(AbstractMaterialNode inNode, PreviewManager previewManager, IEdgeConnectorListener connectorListener)
{

return;
var contents = this.Q("contents");
m_ControlsContainer = new VisualElement
// Add controls container
var controlsContainer = new VisualElement { name = "controls" };
name = "controls"
};
extensionContainer.Add(m_ControlsContainer);
m_ControlsDivider = new VisualElement { name = "divider" };
m_ControlsDivider.AddToClassList("horizontal");
m_ControlsDivider = new VisualElement { name = "divider" };
m_ControlsDivider.AddToClassList("horizontal");
controlsContainer.Add(m_ControlsDivider);
m_ControlItems = new VisualElement { name = "items" };
controlsContainer.Add(m_ControlItems);
// Instantiate control views from node
foreach (var propertyInfo in node.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
foreach (IControlAttribute attribute in propertyInfo.GetCustomAttributes(typeof(IControlAttribute), false))
m_ControlItems.Add(attribute.InstantiateControl(node, propertyInfo));
}
if (m_ControlItems.childCount > 0)
contents.Add(controlsContainer);
m_PreviewContainer = new VisualElement { name = "previewContainer" };
m_PreviewContainer.AddToClassList("expanded");
// Add actual preview which floats on top of the node
m_PreviewContainer = new VisualElement
m_PreviewTextureView = new PreviewTextureView
{
name = "preview",
pickingMode = PickingMode.Ignore,
image = Texture2D.whiteTexture
};
m_PreviewRenderData = previewManager.GetPreview(inNode);
m_PreviewRenderData.onPreviewChanged += UpdatePreviewTexture;
UpdatePreviewTexture();
name = "previewContainer",
clippingOptions = ClippingOptions.ClipAndCacheContents,
pickingMode = PickingMode.Ignore
};
m_PreviewImage = new Image
{
name = "preview",
pickingMode = PickingMode.Ignore,
image = Texture2D.whiteTexture,
};
{
// Add preview collapse button on top of preview
var collapsePreviewButton = new VisualElement { name = "collapse" };
collapsePreviewButton.Add(new VisualElement { name = "icon" });
collapsePreviewButton.AddManipulator(new Clickable(() =>

}));
UpdatePreviewExpandedState(node.previewExpanded);
m_PreviewTextureView.Add(collapsePreviewButton);
m_PreviewImage.Add(collapsePreviewButton);
}
m_PreviewContainer.Add(m_PreviewImage);
// Hook up preview image to preview manager
m_PreviewRenderData = previewManager.GetPreview(inNode);
m_PreviewRenderData.onPreviewChanged += UpdatePreviewTexture;
UpdatePreviewTexture();
// Add fake preview which pads out the node to provide space for the floating preview
m_PreviewFiller = new VisualElement { name = "previewFiller" };
m_PreviewFiller.AddToClassList("expanded");
{
var previewDivider = new VisualElement { name = "divider" };
previewDivider.AddToClassList("horizontal");
m_PreviewFiller.Add(previewDivider);
var expandPreviewButton = new VisualElement { name = "expand" };
expandPreviewButton.Add(new VisualElement { name = "icon" });

UpdatePreviewExpandedState(true);
}));
m_PreviewContainer.Add(expandPreviewButton);
m_PreviewFiller.Add(expandPreviewButton);
contents.Add(m_PreviewFiller);
extensionContainer.Add(m_PreviewContainer);
UpdatePreviewExpandedState(node.previewExpanded);
m_ControlViews = new List<VisualElement>();
foreach (var propertyInfo in node.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
foreach (IControlAttribute attribute in propertyInfo.GetCustomAttributes(typeof(IControlAttribute), false))
m_ControlViews.Add(attribute.InstantiateControl(node, propertyInfo));
m_Attachers = new List<Attacher>(node.GetInputSlots<MaterialSlot>().Count());
// Add port input container, which acts as a pixel cache for all port inputs
m_PortInputContainer = new VisualElement
{
name = "portInputContainer",
clippingOptions = ClippingOptions.ClipAndCacheContents,
pickingMode = PickingMode.Ignore
};
Add(m_PortInputContainer);
UpdateSlotAttachers();
UpdatePortInputs();
UpdateControls();
if (node is PreviewNode)
{

UpdateSize();
}
m_PortInputContainer.SendToBack();
if (node.hasPreview)
m_PreviewFiller.BringToFront();
}
public AbstractMaterialNode node { get; private set; }

node.drawState = ds;
}
UpdateControls();
UpdatePortInputVisibilities();
UpdatePortInputVisibilities();
if (node.hasPreview)
m_PreviewFiller.BringToFront();
}
}

void UpdatePreviewExpandedState(bool expanded)
{
node.previewExpanded = expanded;
if (m_PreviewContainer == null)
if (m_PreviewFiller == null)
if (m_PreviewTextureView.parent != m_PreviewContainer)
if (m_PreviewContainer.parent != this)
m_PreviewContainer.Add(m_PreviewTextureView);
Add(m_PreviewContainer);
m_PreviewContainer.AddToClassList("expanded");
m_PreviewContainer.RemoveFromClassList("collapsed");
m_PreviewFiller.AddToClassList("expanded");
m_PreviewFiller.RemoveFromClassList("collapsed");
if (m_PreviewTextureView.parent == m_PreviewContainer)
if (m_PreviewContainer.parent == m_PreviewFiller)
m_PreviewTextureView.RemoveFromHierarchy();
m_PreviewContainer.RemoveFromHierarchy();
m_PreviewContainer.RemoveFromClassList("expanded");
m_PreviewContainer.AddToClassList("collapsed");
m_PreviewFiller.RemoveFromClassList("expanded");
m_PreviewFiller.AddToClassList("collapsed");
}
}

// Slot doesn't exist anymore, remove it
inputContainer.Remove(port);
// We also need to remove the attacher along with the element it's attaching
var attacher = m_Attachers.FirstOrDefault(a => a.target == port);
if (attacher != null)
{
attacher.Detach();
attacher.element.parent.Remove(attacher.element);
m_Attachers.Remove(attacher);
}
// We also need to remove the inline input
var portInputView = m_PortInputContainer.OfType<PortInputView>().FirstOrDefault(v => Equals(v.slot, port.slot));
if (portInputView != null)
portInputView.RemoveFromHierarchy();
}
else
{

outputContainer.Sort((x, y) => slots.IndexOf(((ShaderPort)x).slot) - slots.IndexOf(((ShaderPort)y).slot));
}
UpdateControls();
UpdateSlotAttachers();
UpdatePortInputs();
foreach (var control in m_ControlViews)
foreach (var control in m_ControlItems)
{
var listener = control as INodeModificationListener;
if (listener != null)

}
}
void UpdateSlotAttachers()
void UpdatePortInputs()
if (!m_Attachers.Any(a => a.target == port))
if (!m_PortInputContainer.OfType<PortInputView>().Any(a => Equals(a.slot, port.slot)))
var portInputView = new PortInputView(port.slot);
Add(portInputView);
mainContainer.BringToFront();
m_Attachers.Add(new Attacher(portInputView, port, SpriteAlignment.LeftCenter) { distance = -8f });
var portInputView = new PortInputView(port.slot) { style = { positionType = PositionType.Absolute } };
m_PortInputContainer.Add(portInputView);
port.RegisterCallback<PostLayoutEvent>(evt => UpdatePortInput((ShaderPort)evt.target));
void UpdatePortInput(ShaderPort port)
{
var inputView = m_PortInputContainer.OfType<PortInputView>().First(x => Equals(x.slot, port.slot));
var currentRect = new Rect(inputView.style.positionLeft, inputView.style.positionTop, inputView.style.width, inputView.style.height);
var targetRect = new Rect(0.0f, 0.0f, port.layout.width, port.layout.height);
targetRect = port.ChangeCoordinatesTo(inputView.shadow.parent, targetRect);
var centerY = targetRect.center.y;
var centerX = targetRect.xMax - currentRect.width;
currentRect.center = new Vector2(centerX, centerY);
inputView.style.positionTop = currentRect.yMin;
var newHeight = inputView.parent.layout.height;
foreach (var element in inputView.parent.Children())
newHeight = Mathf.Max(newHeight, element.style.positionTop + element.layout.height);
if (Math.Abs(inputView.parent.style.height - newHeight) > 1e-3)
inputView.parent.style.height = newHeight;
}
foreach (var attacher in m_Attachers)
foreach (var portInputView in m_PortInputContainer.OfType<PortInputView>())
var slot = ((ShaderPort)attacher.target).slot;
attacher.element.visible = expanded && !node.owner.GetEdges(node.GetSlotReference(slot.id)).Any();
var slot = portInputView.slot;
var oldVisibility = portInputView.visible;
portInputView.visible = expanded && !node.owner.GetEdges(node.GetSlotReference(slot.id)).Any();
if (portInputView.visible != oldVisibility)
m_PortInputContainer.Dirty(ChangeType.Repaint);
}
}

anchor.visualClass = slot.concreteValueType.ToClassName();
}
foreach (var attacher in m_Attachers)
{
var portInputView = (PortInputView)attacher.element;
foreach (var portInputView in m_PortInputContainer.OfType<PortInputView>())
}
var updatedHeight = m_PreviewTextureView.layout.height + deltaSize.y;
var updatedHeight = m_PreviewImage.layout.height + deltaSize.y;
var previewNode = node as PreviewNode;
if (previewNode != null)

{
if (m_PreviewRenderData.texture == null || !node.previewExpanded)
{
m_PreviewTextureView.visible = false;
m_PreviewTextureView.image = Texture2D.blackTexture;
m_PreviewImage.visible = false;
m_PreviewImage.image = Texture2D.blackTexture;
m_PreviewTextureView.visible = true;
m_PreviewTextureView.AddToClassList("visible");
m_PreviewTextureView.RemoveFromClassList("hidden");
if (m_PreviewTextureView.image != m_PreviewRenderData.texture)
m_PreviewTextureView.image = m_PreviewRenderData.texture;
m_PreviewImage.visible = true;
m_PreviewImage.AddToClassList("visible");
m_PreviewImage.RemoveFromClassList("hidden");
if (m_PreviewImage.image != m_PreviewRenderData.texture)
m_PreviewImage.image = m_PreviewRenderData.texture;
m_PreviewTextureView.Dirty(ChangeType.Repaint);
m_PreviewImage.Dirty(ChangeType.Repaint);
void UpdateControls()
{
if (!expanded)
{
m_ControlsContainer.Clear();
m_ControlsDivider.RemoveFromHierarchy();
}
else if (m_ControlsContainer.childCount != m_ControlViews.Count)
{
m_ControlsContainer.Clear();
foreach (var view in m_ControlViews)
m_ControlsContainer.Add(view);
extensionContainer.Add(m_ControlsDivider);
if (m_PreviewContainer != null)
m_ControlsDivider.PlaceBehind(m_PreviewContainer);
}
if (m_ControlsContainer.childCount == 0)
m_ControlsContainer.RemoveFromClassList("notEmpty");
else
m_ControlsContainer.AddToClassList("notEmpty");
}
void UpdateSize()
{
var previewNode = node as PreviewNode;

var width = previewNode.width;
var height = previewNode.height;
m_PreviewTextureView.style.height = height;
m_PreviewTextureView.style.width = width;
m_PreviewImage.style.height = height;
m_PreviewImage.style.width = width;
foreach (var attacher in m_Attachers)
{
((PortInputView)attacher.element).Dispose();
attacher.Detach();
attacher.element.parent.Remove(attacher.element);
}
m_Attachers.Clear();
foreach (var portInputView in m_PortInputContainer.OfType<PortInputView>())
portInputView.Dispose();
node = null;
if (m_PreviewRenderData != null)

14
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/PortInputView.cs


get { return m_EdgeColor.GetSpecifiedValueOrDefault(Color.red); }
}
public MaterialSlot slot
{
get { return m_Slot; }
}
MaterialSlot m_Slot;
ConcreteSlotValueType m_SlotType;
VisualElement m_Control;

m_Container = new VisualElement { name = "container" };
{
m_Control = m_Slot.InstantiateControl();
m_Control = this.slot.InstantiateControl();
if (m_Control != null)
m_Container.Add(m_Control);

Add(m_Container);
m_Container.visible = m_EdgeControl.visible = m_Control != null;
m_Container.clippingOptions = ClippingOptions.ClipAndCacheContents;
}
protected override void OnStyleResolved(ICustomStyle styles)

public void UpdateSlotType()
{
if (m_Slot.concreteValueType != m_SlotType)
if (slot.concreteValueType != m_SlotType)
m_SlotType = m_Slot.concreteValueType;
m_SlotType = slot.concreteValueType;
AddToClassList("type" + m_SlotType);
if (m_Control != null)
{

m_Container.Remove(m_Control);
}
m_Control = m_Slot.InstantiateControl();
m_Control = slot.InstantiateControl();
if (m_Control != null)
m_Container.Insert(0, m_Control);

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


margin-right: 0;
}
MaterialNodeView #previewContainer,
MaterialNodeView #collapsible-area {
width: 0;
height: 0;
}
MaterialNodeView #previewFiller.expanded {
width: 200;
padding-bottom: 200;
}
MaterialNodeView #previewFiller,
MaterialNodeView #controls.notEmpty {
MaterialNodeView #controls > #items {
MaterialNodeView #previewContainer > #preview {
MaterialNodeView > #previewContainer {
position-type: absolute;
position-bottom: 4;
position-left: 4;
border-radius: 6;
padding-top: 6;
}
MaterialNodeView > #previewContainer > #preview {
MaterialNodeView #previewContainer > #preview > #collapse {
MaterialNodeView > #previewContainer > #preview > #collapse {
background-color: #000;
border-color: #F0F0F0;
width: 0;

}
MaterialNodeView #previewContainer:hover > #preview > #collapse {
MaterialNodeView:hover > #previewContainer > #preview > #collapse {
MaterialNodeView #previewContainer > #preview > #collapse > #icon
{
MaterialNodeView > #previewContainer > #preview > #collapse > #icon {
MaterialNodeView #previewContainer > #preview > #collapse:hover {
MaterialNodeView > #previewContainer > #preview > #collapse:hover {
MaterialNodeView #previewContainer.collapsed > #preview > #collapse {
height: 0;
}
MaterialNodeView #previewContainer > #expand {
MaterialNodeView #previewFiller > #expand {
align-self: center;
width: 56;
height: 16;

MaterialNodeView #previewContainer > #expand > #icon {
MaterialNodeView #previewFiller > #expand > #icon {
align-self: center;
background-image : resource("GraphView/Nodes/PreviewExpand.png");
width: 16;

MaterialNodeView #previewContainer.collapsed > #expand:hover {
MaterialNodeView #previewFiller.collapsed > #expand:hover {
MaterialNodeView #previewContainer.expanded > #expand {
MaterialNodeView #previewFiller.expanded > #expand {
height: 0;
}

width: 10;
height: 10;
cursor: resize-up-left;
}
MaterialNodeView > #portInputContainer {
position-type: absolute;
width: 212;
position-left: -200;
position-top: 46;
}
PortInputView {

4
MaterialGraphProject/Assets/UnityShaderEditor/package.json


{
"name": "com.unity.shadergraph",
"description": "Shader Graph",
"version": "0.1.16",
"version": "0.1.17",
}
}

23
MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreatePBRShaderGraph.cs


using System.IO;
using UnityEditor.ProjectWindowCallback;
namespace UnityEditor.ShaderGraph
{
public class CreatePBRShaderGraph : EndNameEditAction
{
[MenuItem("Assets/Create/Shader/PBR Graph", false, 208)]
public static void CreateMaterialGraph()
{
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance<CreatePBRShaderGraph>(),
"New Shader Graph.ShaderGraph", null, null);
}
public override void Action(int instanceId, string pathName, string resourceFile)
{
var graph = new MaterialGraph();
graph.AddNode(new PBRMasterNode());
File.WriteAllText(pathName, EditorJsonUtility.ToJson(graph));
AssetDatabase.Refresh();
}
}
}

23
MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateUnlitShaderGraph.cs


using System.IO;
using UnityEditor.ProjectWindowCallback;
namespace UnityEditor.ShaderGraph
{
public class CreateUnlitShaderGraph : EndNameEditAction
{
[MenuItem("Assets/Create/Shader/Unlit Graph", false, 208)]
public static void CreateMaterialGraph()
{
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance<CreateUnlitShaderGraph>(),
"New Shader Graph.ShaderGraph", null, null);
}
public override void Action(int instanceId, string pathName, string resourceFile)
{
var graph = new MaterialGraph();
graph.AddNode(new UnlitMasterNode());
File.WriteAllText(pathName, EditorJsonUtility.ToJson(graph));
AssetDatabase.Refresh();
}
}
}

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateUnlitShaderGraph.cs.meta


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

58
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Noise/GradientNoiseNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Title("Procedural", "Noise", "Gradient Noise")]
public class GradientNoiseNode : CodeFunctionNode
{
public GradientNoiseNode()
{
name = "Gradient Noise";
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_GradientNoise", BindingFlags.Static | BindingFlags.NonPublic);
}
static string Unity_GradientNoise(
[Slot(0, Binding.MeshUV0)] Vector2 UV,
[Slot(1, Binding.None, 10, 10, 10, 10)] Vector1 Scale,
[Slot(2, Binding.None)] out Vector1 Out)
{
return "{ Out = unity_gradientNoise(UV * Scale) + 0.5; }";
}
public override void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
registry.ProvideFunction("unity_gradientNoise_dir", s => s.Append(@"
float2 unity_gradientNoise_dir(float2 p)
{
// Permutation and hashing used in webgl-nosie goo.gl/pX7HtC
p = p % 289;
float x = (34 * p.x + 1) * p.x % 289 + p.y;
x = (34 * x + 1) * x % 289;
x = frac(x / 41) * 2 - 1;
return normalize(float2(x - floor(x + 0.5), abs(x) - 0.5));
}
"));
registry.ProvideFunction("unity_gradientNoise", s => s.Append(@"
float unity_gradientNoise(float2 p)
{
float2 ip = floor(p);
float2 fp = frac(p);
float d00 = dot(unity_gradientNoise_dir(ip), fp);
float d01 = dot(unity_gradientNoise_dir(ip + float2(0, 1)), fp - float2(0, 1));
float d10 = dot(unity_gradientNoise_dir(ip + float2(1, 0)), fp - float2(1, 0));
float d11 = dot(unity_gradientNoise_dir(ip + float2(1, 1)), fp - float2(1, 1));
fp = fp * fp * fp * (fp * (fp * 6 - 15) + 10);
return lerp(lerp(d00, d01, fp.y), lerp(d10, d11, fp.y), fp.x);
}
"));
base.GenerateNodeFunction(registry, generationMode);
}
}
}

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Procedural/Noise/GradientNoiseNode.cs.meta


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

34
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Scrollable.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
using System;
namespace UnityEditor.ShaderGraph.Drawing
{
public class Scrollable : MouseManipulator
{
Action<float> m_Handler;
public Scrollable(Action<float> handler)
{
m_Handler = handler;
}
protected override void RegisterCallbacksOnTarget()
{
target.RegisterCallback<WheelEvent>(HandleMouseWheelEvent);
}
protected override void UnregisterCallbacksFromTarget()
{
target.UnregisterCallback<WheelEvent>(HandleMouseWheelEvent);
}
void HandleMouseWheelEvent(WheelEvent evt)
{
m_Handler(evt.delta.y);
evt.StopPropagation();
}
}
}

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Manipulators/Scrollable.cs.meta


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

59
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/PixelCacheProfilerView.cs


using System.Linq;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph.Drawing
{
public class PixelCacheProfilerView : VisualElement
{
readonly VisualElement m_Target;
Label m_TotalLabel;
Label m_DirtyLabel;
Label m_TotalNodeContentsLabel;
Label m_DirtyNodeContentsLabel;
Label m_TotalPreviewsLabel;
Label m_DirtyPreviewsLabel;
Label m_TotalInlinesLabel;
Label m_DirtyInlinesLabel;
public PixelCacheProfilerView(VisualElement target)
{
m_Target = target;
var tpl = Resources.Load<VisualTreeAsset>("UXML/PixelCacheProfiler");
tpl.CloneTree(this, null);
m_TotalLabel = this.Q<Label>("totalLabel");
m_DirtyLabel = this.Q<Label>("dirtyLabel");
m_TotalNodeContentsLabel = this.Q<Label>("totalNodeContentsLabel");
m_DirtyNodeContentsLabel = this.Q<Label>("dirtyNodeContentsLabel");
m_TotalPreviewsLabel = this.Q<Label>("totalPreviewsLabel");
m_DirtyPreviewsLabel = this.Q<Label>("dirtyPreviewsLabel");
m_TotalInlinesLabel = this.Q<Label>("totalInlinesLabel");
m_DirtyInlinesLabel = this.Q<Label>("dirtyInlinesLabel");
}
public void Profile()
{
var caches = m_Target.Query().Where(ve => ve.clippingOptions == ClippingOptions.ClipAndCacheContents).Build().ToList();
var dirtyCaches = caches.Where(ve => ve.IsDirty(ChangeType.Repaint)).ToList();
m_TotalLabel.text = caches.Count.ToString();
m_DirtyLabel.text = dirtyCaches.Count.ToString();
var nodeContentsCaches = caches.Where(ve => ve.name == "node-border").ToList();
var dirtyNodeContentsCaches = nodeContentsCaches.Where(ve => ve.IsDirty(ChangeType.Repaint)).ToList();
m_TotalNodeContentsLabel.text = nodeContentsCaches.Count.ToString();
m_DirtyNodeContentsLabel.text = dirtyNodeContentsCaches.Count.ToString();
var previewCaches = caches.Where(ve => ve.name == "previewContainer").ToList();
var dirtyPreviewCaches = previewCaches.Where(ve => ve.IsDirty(ChangeType.Repaint)).ToList();
m_TotalPreviewsLabel.text = previewCaches.Count.ToString();
m_DirtyPreviewsLabel.text = dirtyPreviewCaches.Count.ToString();
var inlineCaches = caches.Where(ve => ve.name == "portInputContainer").ToList();
var dirtyInlineCaches = inlineCaches.Where(ve => ve.IsDirty(ChangeType.Repaint)).ToList();
m_TotalInlinesLabel.text = inlineCaches.Count.ToString();
m_DirtyInlinesLabel.text = dirtyInlineCaches.Count.ToString();
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/PixelCacheProfilerView.cs.meta


fileFormatVersion: 2
guid: 7147f25b12dd4427b4c8afd44624f35b
timeCreated: 1517227822

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/PixelCacheProfiler.uss


PixelCacheProfilerView > #content > #title {
font-style: bold;
}
PixelCacheProfilerView > #content > .row {
flex-direction: row;
}
PixelCacheProfilerView > #content > .indented {
padding-left: 8;
}

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/PixelCacheProfiler.uss.meta


fileFormatVersion: 2
guid: 61cf67e9c1f54ceab08d2bd16ffd3c53
ScriptedImporter:
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}

39
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/UXML/PixelCacheProfiler.uxml


<UXML xmlns:ui="UnityEngine.Experimental.UIElements">
<ui:VisualElement name="content">
<Style path="Styles/PixelCacheProfiler"/>
<ui:Label name="title" text="Pixel Cache Profiler"/>
<ui:VisualElement class="row">
<ui:Label text="Total pixel caches: "/>
<ui:Label name="totalLabel" text="-"/>
</ui:VisualElement>
<ui:VisualElement class="indented row">
<ui:Label text="Node contents: "/>
<ui:Label name="totalNodeContentsLabel" text="-"/>
</ui:VisualElement>
<ui:VisualElement class="indented row">
<ui:Label text="Node previews: "/>
<ui:Label name="totalPreviewsLabel" text="-"/>
</ui:VisualElement>
<ui:VisualElement class="indented row">
<ui:Label text="Inline inputs: "/>
<ui:Label name="totalInlinesLabel" text="-"/>
</ui:VisualElement>
<ui:VisualElement class="row">
<ui:Label text="Dirty pixel caches: "/>
<ui:Label name="dirtyLabel" text="-"/>
</ui:VisualElement>
<ui:VisualElement class="indented row">
<ui:Label text="Node contents: "/>
<ui:Label name="dirtyNodeContentsLabel" text="-"/>
</ui:VisualElement>
<ui:VisualElement class="indented row">
<ui:Label text="Node previews: "/>
<ui:Label name="dirtyPreviewsLabel" text="-"/>
</ui:VisualElement>
<ui:VisualElement class="indented row">
<ui:Label text="Inline inputs: "/>
<ui:Label name="dirtyInlinesLabel" text="-"/>
</ui:VisualElement>
</ui:VisualElement>
</UXML>

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/UXML/PixelCacheProfiler.uxml.meta


fileFormatVersion: 2
guid: 0fda1aff5a5744478f70542e95fd3d42
ScriptedImporter:
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

23
MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateShaderGraph.cs


using System.IO;
using UnityEditor.ProjectWindowCallback;
namespace UnityEditor.ShaderGraph
{
public class CreateShaderGraph : EndNameEditAction
{
[MenuItem("Assets/Create/Shader Graph", false, 208)]
public static void CreateMaterialGraph()
{
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance<CreateShaderGraph>(),
"New Shader Graph.ShaderGraph", null, null);
}
public override void Action(int instanceId, string pathName, string resourceFile)
{
var graph = new MaterialGraph();
graph.AddNode(new PBRMasterNode());
File.WriteAllText(pathName, EditorJsonUtility.ToJson(graph));
AssetDatabase.Refresh();
}
}
}

/MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreateShaderGraph.cs.meta → /MaterialGraphProject/Assets/UnityShaderEditor/Editor/AssetCallbacks/CreatePBRShaderGraph.cs.meta

正在加载...
取消
保存