浏览代码

Custom UI for PixelShaderNode.

Add Slot priority + tests
Make shader generation static functions (they do not need to be members
/main
Tim Cooper 8 年前
当前提交
01366ee3
共有 23 个文件被更改,包括 410 次插入316 次删除
  1. 19
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DrawableNode.cs
  2. 92
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Tests/SerializedGraphTests.cs
  3. 7
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableNode.cs
  4. 13
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableSlot.cs
  5. 11
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/DrawingData.cs
  6. 1
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/INode.cs
  7. 1
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/ISlot.cs
  8. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector4NodeUI.cs
  9. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/ShaderGeneration/ShaderGenerationTest.cs
  10. 27
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Light/BaseLightFunction.cs
  11. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs
  12. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AddNode.cs
  13. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function2Input.cs
  14. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MaterialSlot.cs
  15. 16
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PixelShaderNode.cs
  16. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Vector4Node.cs
  17. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/PixelGraph.cs
  18. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs
  19. 199
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/AbstractMaterialNodeUI.cs
  20. 62
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/PixelShaderNodeUI.cs
  21. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/PixelShaderNodeUI.cs.meta
  22. 198
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/BaseMaterialNodeUI.cs
  23. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/AbstractMaterialNodeUI.cs.meta

19
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Drawing/DrawableNode.cs


float GetNodeUiHeight(float width);
GUIModificationType Render(Rect area);
void SetNode(INode node);
float GetNodeWidth();
}
public class DrawableNode : CanvasElement

public readonly INode m_Node;
private readonly ICustomNodeUi m_Ui;
private const int kDefaultWidth = 200;
const int width = 200;
scale = new Vector2(drawData.width, drawData.width);
var width = ui != null ? ui.GetNodeWidth() : kDefaultWidth;
scale = new Vector2(width, width);
m_Node = node;
m_Ui = ui;

}
else if (modificationType == GUIModificationType.ModelChanged)
{
ParentCanvas().Invalidate();
/* if (m_Node.hasPreview
&& m_Node.drawMode != DrawMode.Collapsed
&& m_PreviewArea.width > 0
&& m_PreviewArea.height > 0)
{
GL.sRGBWrite = (QualitySettings.activeColorSpace == ColorSpace.Linear);
GUI.DrawTexture(m_PreviewArea, m_Node.RenderPreview(new Rect(0, 0, m_PreviewArea.width, m_PreviewArea.height)), ScaleMode.StretchToFill, false);
GL.sRGBWrite = false;
}*/
base.Render(parentRect, canvas);
}

92
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Tests/SerializedGraphTests.cs


{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));
node.name = "Test Node";
graph.AddNode(node);

public void TestCanRemoveSlotFromSerializableNode()
{
var node = new SerializableNode(null);
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));
Assert.AreEqual(2, node.slots.Count());
Assert.AreEqual(1, node.inputSlots.Count());

public void TestCanRemoveSlotsWithNonMathingNameFromSerializableNode()
{
var node = new SerializableNode(null);
node.AddSlot(new SerializableSlot("input1", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("input2", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("input3", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("input4", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("input1", "input", SlotType.Input, 0));
node.AddSlot(new SerializableSlot("input2", "input", SlotType.Input, 0));
node.AddSlot(new SerializableSlot("input3", "input", SlotType.Input, 0));
node.AddSlot(new SerializableSlot("input4", "input", SlotType.Input, 0));
Assert.AreEqual(4, node.slots.Count());
Assert.AreEqual(4, node.inputSlots.Count());

{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.name = "Test Node";
graph.AddNode(node);

{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("output", "output_updated", SlotType.Output));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("output", "output_updated", SlotType.Output, 0));
Assert.AreEqual(0 ,found.inputSlots.Count());
Assert.AreEqual(0, found.inputSlots.Count());
}
[Test]
public void TestCanUpdatePriorityByReaddingSlotToSerializableNode()
{
var graph = new SerializableGraph();
var node = new SerializableNode(graph);
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 1));
node.name = "Test Node";
graph.AddNode(node);
Assert.AreEqual(1, graph.nodes.Count());
var found = graph.nodes.FirstOrDefault();
Assert.AreEqual(0, found.inputSlots.Count());
Assert.AreEqual(1, found.outputSlots.Count());
Assert.AreEqual(1, found.slots.Count());
var slot = found.outputSlots.FirstOrDefault();
Assert.AreEqual(1, slot.priority);
}
[Test]

node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));
Assert.AreEqual(2, node.slots.Count());
Assert.IsNotNull(node.FindInputSlot("input"));

public void TestCanFindSlotReferenceOnSerializableNode()
{
var node = new SerializableNode(null);
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input));
node.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
node.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));
Assert.AreEqual(2, node.slots.Count());
Assert.IsNotNull(node.GetSlotReference("input"));

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output, 0);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input, 0);
inputNode.AddSlot(inputSlot);
graph.AddNode(inputNode);

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output, 0);
var outputSlot2 = new SerializableSlot("output", "output", SlotType.Output);
var outputSlot2 = new SerializableSlot("output", "output", SlotType.Output, 0);
outputNode2.AddSlot(outputSlot2);
graph.AddNode(outputNode2);

{
var graph = new SerializableGraph();
var inputNode = new SerializableNode(graph);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input, 0);
var inputSlot2 = new SerializableSlot("input", "input", SlotType.Input);
var inputSlot2 = new SerializableSlot("input", "input", SlotType.Input, 0);
inputNode2.AddSlot(inputSlot2);
graph.AddNode(inputNode2);

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output, 0);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input, 0);
inputNode.AddSlot(inputSlot);
graph.AddNode(inputNode);

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output, 0);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input, 0);
inputNode.AddSlot(inputSlot);
graph.AddNode(inputNode);

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output, 0);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input, 0);
inputNode.AddSlot(inputSlot);
graph.AddNode(inputNode);

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output);
var outputSlot = new SerializableSlot("output", "output", SlotType.Output, 0);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input);
var inputSlot = new SerializableSlot("input", "input", SlotType.Input, 0);
inputNode.AddSlot(inputSlot);
graph.AddNode(inputNode);

{
var graph = new SerializableGraph();
var outputNode = new SerializableNode(graph);
outputNode.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
graph.AddNode(outputNode);
outputNode.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
graph.AddNode(outputNode);
inputNode.AddSlot(new SerializableSlot("input", "input", SlotType.Input));
inputNode.AddSlot(new SerializableSlot("input2", "input2", SlotType.Input));
inputNode.AddSlot(new SerializableSlot("output", "output", SlotType.Output));
inputNode.AddSlot(new SerializableSlot("input", "input", SlotType.Input, 0));
inputNode.AddSlot(new SerializableSlot("input2", "input2", SlotType.Input, 1));
inputNode.AddSlot(new SerializableSlot("output", "output", SlotType.Output, 0));
graph.AddNode(inputNode);
Assert.AreEqual(2, graph.nodes.Count());

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


set { m_DrawData = value; }
}
public virtual bool hasError { get; set; }
public virtual bool hasError { get; protected set; }
public virtual void ValidateNode()
{}

public SerializableNode(IGraph theOwner)
{
m_DrawData.expanded = true;
m_DrawData.width = 200;
owner = theOwner;
m_Guid = Guid.NewGuid();
}

m_Slots = SerializationHelper.Deserialize<ISlot>(m_SerializableSlots, new object[] {});
m_SerializableSlots = null;
UpdateSlots();
}
public virtual IEnumerable<ISlot> GetInputsWithNoConnection()

public virtual void UpdateSlots()
{}
}
}

13
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableSlot.cs


using System;
using System.Runtime.InteropServices;
namespace UnityEngine.Graphing
{

[SerializeField]
private SlotType m_SlotType;
[SerializeField]
private int m_Priority;
public string name
{

get { return m_SlotType == SlotType.Output; }
}
public SerializableSlot(string name, string displayName, SlotType slotType)
public int priority
{
get { return m_Priority; }
set { m_Priority = value; }
}
public SerializableSlot(string name, string displayName, SlotType slotType, int priority)
m_Priority = priority;
}
// used via reflection / serialization after deserialize

11
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/DrawingData.cs


[SerializeField]
private Rect m_Position;
[SerializeField]
private int m_Width;
public bool expanded
{
get { return m_Expanded; }

{
get { return m_Position; }
set { m_Position = value; }
}
public int width
{
get { return m_Width; }
set { m_Width = value; }
}
}
}

1
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/INode.cs


DrawingData drawState { get; set; }
bool hasError { get; }
void ValidateNode();
void UpdateSlots();
}
}

1
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Interfaces/ISlot.cs


string displayName { get; set; }
bool isInputSlot { get; }
bool isOutputSlot { get; }
int priority { get; set; }
}
}

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/Vector4NodeUI.cs


if (node is Vector4Node)
m_Node = (Vector4Node) node;
}
public float GetNodeWidth()
{
return 200;
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/ShaderGeneration/ShaderGenerationTest.cs


// Generate the shader
List<PropertyGenerator.TextureInfo> buff;
string shader = ShaderGenerator.GenerateSurfaceShader(graph.graph, graph.name, false, out buff);
//TODO: FIX
string shader = null;//ShaderGenerator.GenerateSurfaceShader(graph.graph, graph.name, false, out buff);
// find the 'reference' shader
var dumpFileLocation = string.Format("{0}.{1}", file, "dump");

27
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Light/BaseLightFunction.cs


public override string GetSurfaceOutputStructureName() { return "SurfaceOutputStandard"; }
public override void DoSlotsForConfiguration(PixelShaderNode node)
{
node.AddSlot(new MaterialSlot(kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kNormalSlotName, kNormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kMetallicSlotName, kMetallicSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kOcclusion, kOcclusion, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlphaSlotName, kAlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, 0, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kNormalSlotName, kNormalSlotName, SlotType.Input, 1, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kEmissionSlotName, kEmissionSlotName, SlotType.Input, 2, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kMetallicSlotName, kMetallicSlotName, SlotType.Input, 4, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, 4, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kOcclusion, kOcclusion, SlotType.Input, 5, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlphaSlotName, kAlphaSlotName, SlotType.Input, 6, SlotValueType.Vector1, Vector4.zero));
// clear out slot names that do not match the slots
// we support

public override string GetSurfaceOutputStructureName() { return "SurfaceOutputStandardSpecular"; }
public override void DoSlotsForConfiguration(PixelShaderNode node)
{
node.AddSlot(new MaterialSlot(kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kNormalSlotName, kNormalSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kSpecularSlotName, kSpecularSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kEmissionSlotName, kEmissionSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kOcclusion, kOcclusion, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlphaSlotName, kAlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, 0, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kNormalSlotName, kNormalSlotName, SlotType.Input, 1, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kSpecularSlotName, kSpecularSlotName, SlotType.Input, 2, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kEmissionSlotName, kEmissionSlotName, SlotType.Input, 3, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, 4, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kOcclusion, kOcclusion, SlotType.Input, 5, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlphaSlotName, kAlphaSlotName, SlotType.Input, 6, SlotValueType.Vector1, Vector4.zero));
// clear out slot names that do not match the slots
// we support

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


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

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

6
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AddNode.cs


visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
/*
public override float GetNodeUIHeight(float width)
{
return EditorGUIUtility.singleLineHeight;
}*/
}
}

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


UpdateSlots();
}
private void UpdateSlots()
public sealed override void UpdateSlots()
{
AddSlot(GetInputSlot1());
AddSlot(GetInputSlot2());

protected MaterialSlot GetInputSlot1()
{
return new MaterialSlot(GetInputSlot1Name(), GetInputSlot1Name(), SlotType.Input, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(GetInputSlot1Name(), GetInputSlot1Name(), SlotType.Input, 0, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(GetInputSlot2Name(), GetInputSlot2Name(), SlotType.Input, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(GetInputSlot2Name(), GetInputSlot2Name(), SlotType.Input, 1, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(GetOutputSlotName(), GetOutputSlotName(), SlotType.Output, SlotValueType.Dynamic, Vector4.zero);
return new MaterialSlot(GetOutputSlotName(), GetOutputSlotName(), SlotType.Output, 2, SlotValueType.Dynamic, Vector4.zero);
}
protected virtual string GetInputSlot1Name()

public string input2Dimension
{
get { return ConvertConcreteSlotValueTypeToString(FindMaterialInputSlot(GetInputSlot2Name()).concreteValueType); }
}
public override void OnAfterDeserialize()
{
base.OnAfterDeserialize();
UpdateSlots();
}
}
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MaterialSlot.cs


public MaterialSlot() { }
public MaterialSlot(string name, string displayName, SlotType slotType, SlotValueType valueType, Vector4 defaultValue)
: base(name, displayName, slotType)
public MaterialSlot(string name, string displayName, SlotType slotType, int priority, SlotValueType valueType, Vector4 defaultValue)
: base(name, displayName, slotType, priority)
{
m_ValueType = valueType;
m_DefaultValue = defaultValue;

16
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PixelShaderNode.cs


namespace UnityEngine.MaterialGraph
{
[Serializable]
[Title("Pixel Shader Node")]
public class PixelShaderNode : AbstractMaterialNode, IGeneratesBodyCode
{
[SerializeField]

private static List<BaseLightFunction> s_LightFunctions;
public PixelShaderNode(AbstractMaterialGraph owner)
public PixelShaderNode(IGraph owner)
GetLightFunction().DoSlotsForConfiguration(this);
UpdateSlots();
}
public sealed override void UpdateSlots()
{
GetLightFunction().DoSlotsForConfiguration(this);
public override bool canDeleteNode { get { return false; } }
// public override bool canDeleteNode { get { return false; } }
private static List<BaseLightFunction> GetLightFunctions()
public static List<BaseLightFunction> GetLightFunctions()
{
if (s_LightFunctions == null)
{

return s_LightFunctions;
}
private BaseLightFunction GetLightFunction()
public BaseLightFunction GetLightFunction()
{
var lightFunctions = GetLightFunctions();
var lightFunction = lightFunctions.FirstOrDefault(x => x.GetType().ToString() == lightFunctionClassName);

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


UpdateSlots();
}
private void UpdateSlots()
public sealed override void UpdateSlots()
AddSlot(new MaterialSlot(kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotName, kOutputSlotName, SlotType.Output, 0, SlotValueType.Vector4, Vector4.zero));
}
public override PropertyType propertyType

m_PropType = PropertyType.Vector4,
m_Vector4 = m_Value
};
}
public override void OnAfterDeserialize()
{
base.OnAfterDeserialize();
UpdateSlots();
}
}
}

17
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/PixelGraph.cs


base.AddNode(node);
}
public void GenerateSurfaceShader(
public static void GenerateSurfaceShader(
PixelShaderNode pixelNode,
ShaderGenerator shaderBody,
ShaderGenerator inputStruct,
ShaderGenerator lightFunction,

ShaderGenerator vertexShader,
bool isPreview)
{
pixelMasterNode.GenerateLightFunction(lightFunction);
pixelMasterNode.GenerateSurfaceOutput(surfaceOutput);
pixelNode.GenerateLightFunction(lightFunction);
pixelNode.GenerateSurfaceOutput(surfaceOutput);
foreach (var node in activeNodes)
var activeNodes = new List<INode>();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodes, pixelNode);
var activeMaterialNodes = activeNodes.OfType<AbstractMaterialNode>();
foreach (var node in activeMaterialNodes)
{
if (node is IGeneratesFunction) (node as IGeneratesFunction).GenerateNodeFunction(nodeFunction, genMode);
if (node is IGeneratesVertexToFragmentBlock) (node as IGeneratesVertexToFragmentBlock).GenerateVertexToFragmentBlock(inputStruct, genMode);

}
}
pixelMasterNode.GenerateNodeCode(shaderBody, genMode);
pixelNode.GenerateNodeCode(shaderBody, genMode);
}
/*
public Material GetMaterial()

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


return template;
}
public static string GenerateSurfaceShader(MaterialGraph graph, string shaderName, bool isPreview, out List<PropertyGenerator.TextureInfo> configuredTxtures)
public static string GenerateSurfaceShader(PixelShaderNode node, MaterialOptions options, string shaderName, bool isPreview, out List<PropertyGenerator.TextureInfo> configuredTxtures)
{
var templateLocation = GetTemplatePath("shader.template");

var shaderPropertyUsagesVisitor = new ShaderGenerator();
var vertexShaderBlock = new ShaderGenerator();
(graph.currentGraph as PixelGraph).GenerateSurfaceShader(
PixelGraph.GenerateSurfaceShader(
node,
shaderBodyVisitor,
shaderInputVisitor,
shaderLightFunctionVisitor,

var zTestVisitor = new ShaderGenerator();
var zWriteVisitor = new ShaderGenerator();
var options = graph.materialOptions;
options.GetTags(tagsVisitor);
options.GetBlend(blendingVisitor);
options.GetCull(cullingVisitor);

199
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/AbstractMaterialNodeUI.cs


using System;
using System.Reflection;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(AbstractMaterialNode))]
public class AbstractMaterialNodeUI : ICustomNodeUi
{
private MaterialGraphPreviewGenerator m_PreviewGenerator;
[NonSerialized]
private int m_LastShaderVersion = -1;
[NonSerialized]
private Material m_PreviewMaterial;
[NonSerialized]
protected Shader m_PreviewShader;
protected AbstractMaterialNode m_Node;
protected PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D;
public Material previewMaterial
{
get
{
if (m_PreviewMaterial == null)
{
m_PreviewMaterial = new Material(Shader.Find("Unlit/Color")) {hideFlags = HideFlags.HideInHierarchy};
m_PreviewMaterial.hideFlags = HideFlags.HideInHierarchy;
}
return m_PreviewMaterial;
}
}
private MaterialGraphPreviewGenerator previewGenerator
{
get
{
if (m_PreviewGenerator == null)
{
m_PreviewGenerator = new MaterialGraphPreviewGenerator();
}
return m_PreviewGenerator;
}
}
private float m_PreviewWidth;
public virtual float GetNodeUiHeight(float width)
{
if (!m_Node.drawState.expanded)
return 0;
m_PreviewWidth = width - 20;
return m_PreviewWidth;
}
public void SetNode(INode node)
{
if (node is AbstractMaterialNode)
m_Node = (AbstractMaterialNode)node;
}
public virtual float GetNodeWidth()
{
return 200;
}
public virtual GUIModificationType Render(Rect area)
{
if (m_Node == null || !m_Node.drawState.expanded)
return GUIModificationType.None;
if (m_LastShaderVersion != m_Node.version)
{
UpdatePreviewShader();
m_LastShaderVersion = m_Node.version;
}
var preview = RenderPreview(area);
GL.sRGBWrite = QualitySettings.activeColorSpace == ColorSpace.Linear;
GUI.DrawTexture(area, preview, ScaleMode.StretchToFill, false);
GL.sRGBWrite = false;
return GUIModificationType.None;
}
protected virtual string GetPreviewShaderString()
{
return ShaderGenerator.GeneratePreviewShader(m_Node, out m_GeneratedShaderMode);
}
private bool UpdatePreviewShader()
{
if (m_Node == null)
return false;
var resultShader = GetPreviewShaderString();
Debug.Log("RecreateShaderAndMaterial : " + m_Node.GetVariableNameForNode() + "\n" + resultShader);
if (string.IsNullOrEmpty(resultShader))
return false;
// workaround for some internal shader compiler weirdness
// if we are in error we sometimes to not properly clean
// out the error flags and will stay in error, even
// if we are now valid
if (m_PreviewShader && ShaderHasError(m_PreviewShader))
{
Object.DestroyImmediate(m_PreviewShader, true);
m_PreviewShader = null;
}
if (m_PreviewShader == null)
{
m_PreviewShader = ShaderUtil.CreateShaderAsset(resultShader);
m_PreviewShader.hideFlags = HideFlags.HideInHierarchy;
}
else
{
ShaderUtil.UpdateShaderAsset(m_PreviewShader, resultShader);
}
return !ShaderHasError(m_PreviewShader);
}
protected static bool ShaderHasError(Shader shader)
{
var hasErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic);
var result = hasErrorsCall.Invoke(null, new object[] {shader});
return (int) result != 0;
}
/// <summary>
/// RenderPreview gets called in OnPreviewGUI. Nodes can override
/// RenderPreview and do their own rendering to the render texture
/// </summary>
public Texture RenderPreview(Rect targetSize)
{
previewMaterial.shader = m_PreviewShader;
UpdateMaterialProperties(m_Node, previewMaterial);
return previewGenerator.DoRenderPreview(previewMaterial, m_GeneratedShaderMode, targetSize);
}
private static void SetPreviewMaterialProperty(PreviewProperty previewProperty, Material mat)
{
switch (previewProperty.m_PropType)
{
case PropertyType.Texture2D:
mat.SetTexture(previewProperty.m_Name, previewProperty.m_Texture);
break;
case PropertyType.Color:
mat.SetColor(previewProperty.m_Name, previewProperty.m_Color);
break;
case PropertyType.Vector2:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector3:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector4:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Float:
mat.SetFloat(previewProperty.m_Name, previewProperty.m_Float);
break;
}
}
public static void UpdateMaterialProperties(AbstractMaterialNode target, Material material)
{
var childNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(childNodes, target);
var pList = ListPool<PreviewProperty>.Get();
for (var index = 0; index < childNodes.Count; index++)
{
var node = childNodes[index] as AbstractMaterialNode;
if (node == null)
continue;
node.CollectPreviewMaterialProperties(pList);
}
foreach (var prop in pList)
SetPreviewMaterialProperty(prop, material);
ListPool<INode>.Release(childNodes);
ListPool<PreviewProperty>.Release(pList);
}
}
}

62
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/PixelShaderNodeUI.cs


using System.Collections.Generic;
using System.Linq;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(PixelShaderNode))]
public class PixelShaderNodeUI : AbstractMaterialNodeUI
{
public override float GetNodeWidth()
{
return 300;
}
public override float GetNodeUiHeight(float width)
{
return base.GetNodeUiHeight(width) + EditorGUIUtility.singleLineHeight;
}
public override GUIModificationType Render(Rect area)
{
var node = m_Node as PixelShaderNode;
if (node == null)
return base.Render(area);
var lightFunctions = PixelShaderNode.GetLightFunctions();
var lightFunction = node.GetLightFunction();
int lightFuncIndex = 0;
if (lightFunction != null)
lightFuncIndex = lightFunctions.IndexOf(lightFunction);
EditorGUI.BeginChangeCheck();
lightFuncIndex = EditorGUI.Popup(new Rect(area.x, area.y, area.width, EditorGUIUtility.singleLineHeight), lightFuncIndex, lightFunctions.Select(x => x.GetLightFunctionName()).ToArray(), EditorStyles.popup);
node.m_LightFunctionClassName = lightFunctions[lightFuncIndex].GetType().ToString();
var toReturn = GUIModificationType.None;
if (EditorGUI.EndChangeCheck())
{
node.UpdateSlots();
toReturn = GUIModificationType.ModelChanged;
}
area.y += EditorGUIUtility.singleLineHeight;
area.height -= EditorGUIUtility.singleLineHeight;
toReturn |= base.Render(area);
return toReturn;
}
protected override string GetPreviewShaderString()
{
var shaderName = "Hidden/PreviewShader/" + m_Node.GetVariableNameForNode();
List<PropertyGenerator.TextureInfo> defaultTextures;
//TODO: Need to get the real options somehow
var resultShader = ShaderGenerator.GenerateSurfaceShader(m_Node as PixelShaderNode, new MaterialOptions(), shaderName, true, out defaultTextures);
m_GeneratedShaderMode = PreviewMode.Preview3D;
return resultShader;
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/PixelShaderNodeUI.cs.meta


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

198
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/BaseMaterialNodeUI.cs


using System;
using System.Reflection;
using UnityEditor.Graphing;
using UnityEditor.Graphing.Drawing;
using UnityEngine;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph
{
[CustomNodeUI(typeof(AbstractMaterialNode))]
class BaseMaterialNodeUI : ICustomNodeUi
{
private const int kPreviewWidth = 64;
private const int kPreviewHeight = 64;
private MaterialGraphPreviewGenerator m_PreviewGenerator;
[NonSerialized]
private int m_LastShaderVersion = -1;
[NonSerialized]
private Material m_PreviewMaterial;
[NonSerialized]
private Shader m_PreviewShader;
private AbstractMaterialNode m_Node;
private PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D;
public Material previewMaterial
{
get
{
if (m_PreviewMaterial == null)
{
m_PreviewMaterial = new Material(Shader.Find("Unlit/Color")) {hideFlags = HideFlags.HideInHierarchy};
m_PreviewMaterial.hideFlags = HideFlags.HideInHierarchy;
}
return m_PreviewMaterial;
}
}
public MaterialGraphPreviewGenerator previewGenerator
{
get
{
if (m_PreviewGenerator == null)
{
m_PreviewGenerator = new MaterialGraphPreviewGenerator();
}
return m_PreviewGenerator;
}
}
private float m_PreviewWidth;
public virtual float GetNodeUiHeight(float width)
{
if (!m_Node.drawState.expanded)
return 0;
m_PreviewWidth = width - 20;
return m_PreviewWidth;
}
public void SetNode(INode node)
{
if (node is AbstractMaterialNode)
m_Node = (AbstractMaterialNode)node;
}
public virtual GUIModificationType Render(Rect area)
{
if (m_Node == null || !m_Node.drawState.expanded)
return GUIModificationType.None;
if (m_LastShaderVersion != m_Node.version)
{
UpdatePreviewShader();
m_LastShaderVersion = m_Node.version;
}
GUILayout.BeginArea(area);
GUILayout.BeginHorizontal(GUILayout.MinWidth(m_PreviewWidth + 10), GUILayout.MinWidth(m_PreviewWidth + 10));
GUILayout.FlexibleSpace();
var rect = GUILayoutUtility.GetRect(m_PreviewWidth, m_PreviewWidth, GUILayout.ExpandWidth(false));
var preview = RenderPreview(rect);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GL.sRGBWrite = QualitySettings.activeColorSpace == ColorSpace.Linear;
GUI.DrawTexture(rect, preview, ScaleMode.StretchToFill, false);
GL.sRGBWrite = false;
GUILayout.EndArea();
return GUIModificationType.None;
}
private bool UpdatePreviewShader()
{
if (m_Node == null)
return false;
var resultShader = ShaderGenerator.GeneratePreviewShader(m_Node, out m_GeneratedShaderMode);
Debug.Log("RecreateShaderAndMaterial : " + m_Node.name + "_" + m_Node.guid.ToString().Replace("-", "_") + "\n" + resultShader);
// workaround for some internal shader compiler weirdness
// if we are in error we sometimes to not properly clean
// out the error flags and will stay in error, even
// if we are now valid
if (m_PreviewShader && ShaderHasError(m_PreviewShader))
{
Object.DestroyImmediate(m_PreviewShader, true);
m_PreviewShader = null;
}
if (m_PreviewShader == null)
{
m_PreviewShader = ShaderUtil.CreateShaderAsset(resultShader);
m_PreviewShader.hideFlags = HideFlags.HideInHierarchy;
}
else
{
ShaderUtil.UpdateShaderAsset(m_PreviewShader, resultShader);
}
return !ShaderHasError(m_PreviewShader);
}
private static bool ShaderHasError(Shader shader)
{
var hasErrorsCall = typeof(ShaderUtil).GetMethod("GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic);
var result = hasErrorsCall.Invoke(null, new object[] {shader});
return (int) result != 0;
}
/// <summary>
/// RenderPreview gets called in OnPreviewGUI. Nodes can override
/// RenderPreview and do their own rendering to the render texture
/// </summary>
public Texture RenderPreview(Rect targetSize)
{
previewMaterial.shader = m_PreviewShader;
UpdateMaterialProperties(m_Node, previewMaterial);
return previewGenerator.DoRenderPreview(previewMaterial, m_GeneratedShaderMode, targetSize);
}
private static void SetPreviewMaterialProperty(PreviewProperty previewProperty, Material mat)
{
switch (previewProperty.m_PropType)
{
case PropertyType.Texture2D:
mat.SetTexture(previewProperty.m_Name, previewProperty.m_Texture);
break;
case PropertyType.Color:
mat.SetColor(previewProperty.m_Name, previewProperty.m_Color);
break;
case PropertyType.Vector2:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector3:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Vector4:
mat.SetVector(previewProperty.m_Name, previewProperty.m_Vector4);
break;
case PropertyType.Float:
mat.SetFloat(previewProperty.m_Name, previewProperty.m_Float);
break;
}
}
public static void UpdateMaterialProperties(AbstractMaterialNode target, Material material)
{
var childNodes = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(childNodes, target);
var pList = ListPool<PreviewProperty>.Get();
for (var index = 0; index < childNodes.Count; index++)
{
var node = childNodes[index] as AbstractMaterialNode;
if (node == null)
continue;
node.CollectPreviewMaterialProperties(pList);
}
foreach (var prop in pList)
SetPreviewMaterialProperty(prop, material);
ListPool<INode>.Release(childNodes);
ListPool<PreviewProperty>.Release(pList);
}
}
}

/MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/BaseMaterialNodeUI.cs.meta → /MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/NodeDrawers/AbstractMaterialNodeUI.cs.meta

正在加载...
取消
保存