浏览代码

Outside node controls for texture slots + various fixes

/main
Peter Bay Bastian 7 年前
当前提交
d50eb6bb
共有 15 个文件被更改,包括 299 次插入74 次删除
  1. 3
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Implementation/SerializableGraph.cs
  2. 4
      MaterialGraphProject/Assets/SRP/PostProcessing/PostProcessing/Runtime/Utils/TextureFormatUtilities.cs
  3. 81
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs
  4. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Texture2DInputMaterialSlot.cs
  5. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs
  6. 47
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
  7. 85
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs
  8. 34
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Resources/Styles/MaterialGraph.uss
  9. 2
      MaterialGraphProject/ProjectSettings/ProjectVersion.txt
  10. 59
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/PortInputView.cs
  11. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/PortInputView.cs.meta
  12. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/Slots.meta
  13. 35
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/Slots/TextureSlotControlView.cs
  14. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/Slots/TextureSlotControlView.cs.meta

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


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

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


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

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


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

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

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

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

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


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

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

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


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

}
if (e.commandName == "Delete" || e.commandName == "SoftDelete")
{
graphObject.RegisterCompleteObjectUndo("Delete");
graphObject.graph.RemoveElements(graphView.selection.OfType<MaterialNodeView>().Select(x => x.node as INode), graphView.selection.OfType<Edge>().Select(x => x.userData as IEdge));
graphObject.graph.ValidateGraph();
// graphObject.RegisterCompleteObjectUndo("Delete");
// graphObject.graph.RemoveElements(graphView.selection.OfType<MaterialNodeView>().Select(x => x.node as INode), graphView.selection.OfType<Edge>().Select(x => x.userData as IEdge));
// graphObject.graph.ValidateGraph();
}
}

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


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

Add(content);
}
List<INode> nodesToRemove = new List<INode>();
List<IEdge> edgesToRemove = new List<IEdge>();
m_Graph.owner.RegisterCompleteObjectUndo("Delete");
m_Graph.owner.RegisterCompleteObjectUndo("Delete");
if (nodeView != null)
m_Graph.RemoveNode(nodeView.node);
if (nodeView != null && nodeView.node != null)
nodesToRemove.Add(nodeView.node);
m_Graph.RemoveEdge(edgeView.userData as IEdge);
{
var edge = edgeView.userData as IEdge;
if (edge != null)
edgesToRemove.Add(edge);
}
m_Graph.RemoveElements(nodesToRemove, edgesToRemove);
nodesToRemove.Clear();
edgesToRemove.Clear();
}
if (graphViewChange.edgesToCreate != null)

if (edgeView != null)
nodesToUpdate.Add((MaterialNodeView)edgeView.input.node);
}
foreach (var node in nodesToUpdate)
node.UpdatePortInputVisibilities();
UpdateEdgeColors(nodesToUpdate);
}

var nodeView = new MaterialNodeView(node as AbstractMaterialNode, m_PreviewManager) { userData = node };
var nodeView = new MaterialNodeView { userData = node };
m_GraphView.AddElement(nodeView);
nodeView.Initialize(m_GraphView, node as AbstractMaterialNode, m_PreviewManager);
m_GraphView.AddElement(nodeView);
}
Edge AddEdge(IEdge edge)

m_GraphView.AddElement(edgeView);
sourceNodeView.RefreshAnchors();
targetNodeView.RefreshAnchors();
sourceNodeView.UpdatePortInputTypes();
targetNodeView.UpdatePortInputTypes();
return edgeView;
}

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

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

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


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

m_GraphView = graphView;
node = inNode;
UpdateTitle();

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

}
UpdateControls();
UpdatePortInputVisibilities();
}
}

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

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

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

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


background-color: rgb(0, 225, 25);
}
PortInputView {
width: 212;
height: 22;
flex-direction: row;
justify-content: flex-end;
}
PortInputView > #controlContainer {
background-color: #393939;
flex-direction: row;
align-items: center;
padding-left: 8;
padding-right: 20;
border-left-width: 1;
border-top-width: 1;
border-right-width: 1;
border-bottom-width: 1;
border-color: rgba(25, 25, 25, 0.8);
border-radius: 2;
}
TextureSlotControlView {
flex-direction: row;
align-items: center;
}
TextureSlotControlView > ObjectField {
margin-top: 0;
margin-bottom: 0;
margin-left: 0;
margin-right: 0;
width: 100;
}
.edge.fromMatrix4, .edge.fromMatrix3, .edge.fromMatrix2 {
edge-output-color: #8FC1DF;
}

2
MaterialGraphProject/ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2018.1.0a1
m_EditorVersion: 2018.1.0a3

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


using System;
using UnityEditor.Experimental.UIElements;
using UnityEditor.Experimental.UIElements.GraphView;
using UnityEditor.Graphing;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph.Drawing
{
public class PortInputView : GraphElement, IDisposable
{
MaterialSlot m_Slot;
ConcreteSlotValueType m_SlotType;
VisualElement m_Control;
VisualElement m_ControlContainer;
public PortInputView(MaterialSlot slot)
{
m_Slot = slot;
ClearClassList();
m_SlotType = slot.concreteValueType;
m_ControlContainer = new VisualElement { name = "controlContainer" };
Add(m_ControlContainer);
m_Control = m_Slot.InstantiateControl();
if (m_Control != null)
m_ControlContainer.Add(m_Control);
else
m_ControlContainer.visible = false;
}
public void UpdateSlotType()
{
if (m_Slot.concreteValueType != m_SlotType)
{
m_SlotType = m_Slot.concreteValueType;
if (m_Control != null)
{
var disposable = m_Control as IDisposable;
if (disposable != null)
disposable.Dispose();
m_ControlContainer.Remove(m_Control);
}
m_Control = m_Slot.InstantiateControl();
m_ControlContainer.visible = true;
if (m_Control != null)
m_ControlContainer.Add(m_Control);
else
m_ControlContainer.visible = false;
}
}
public void Dispose()
{
var disposable = m_Control as IDisposable;
if (disposable != null)
disposable.Dispose();
}
}
}

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


fileFormatVersion: 2
guid: 9f69414f1afe45f794ec4b5d5bc2bcb5
timeCreated: 1509629683

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/Slots.meta


fileFormatVersion: 2
guid: 56e544af973b458ea7e8051cd0848d24
timeCreated: 1509718923

35
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/Slots/TextureSlotControlView.cs


using System;
using UnityEditor.Experimental.UIElements;
using UnityEditor.Graphing;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
using UnityEngine.Experimental.UIElements.StyleSheets;
using Object = UnityEngine.Object;
namespace UnityEditor.ShaderGraph.Drawing.Slots
{
public class TextureSlotControlView : VisualElement
{
Texture2DInputMaterialSlot m_Slot;
public TextureSlotControlView(Texture2DInputMaterialSlot slot)
{
m_Slot = slot;
var objectField = new ObjectField { objectType = typeof(Texture), value = m_Slot.texture };
objectField.OnValueChanged(OnValueChanged);
Add(objectField);
}
void OnValueChanged(ChangeEvent<Object> evt)
{
var texture = evt.newValue as Texture2D;
if (texture != m_Slot.texture)
{
m_Slot.owner.owner.owner.RegisterCompleteObjectUndo("Change Texture");
m_Slot.texture = texture;
if (m_Slot.owner.onModified != null)
m_Slot.owner.onModified(m_Slot.owner, ModificationScope.Node);
}
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/Slots/TextureSlotControlView.cs.meta


fileFormatVersion: 2
guid: 49f18880b4854ccc8f383c55a7bc47b3
timeCreated: 1509718979
正在加载...
取消
保存