浏览代码

[shader graph]

*Use GUID for node identifier instead of instance ID (Stable between runs)
*Cash hash of last generated preview shader string, do not regenerate if it's the same
*Serialize node preview shaders / materials / last generated shader hash (load time optimisation)
*Add node property: canDeleteNode returns false by default. True for pixel master node
*Rarrange popup menu
/main
Tim Cooper 9 年前
当前提交
798bca64
共有 15 个文件被更改,包括 86 次插入52 次删除
  1. 10
      UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs
  2. 10
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs
  3. 79
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs
  4. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorNode.cs
  5. 11
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs
  6. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PropertyNode.cs
  7. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinTimeNode.cs
  8. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphNode.cs
  9. 1
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SwizzleNode.cs
  10. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/TimeNode.cs
  11. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector1Node.cs
  12. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector2Node.cs
  13. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector3Node.cs
  14. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs
  15. 5
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/WorldPosNode.cs

10
UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs


base.RemoveEdge(e);
}
public override void RemoveNode(Node node, bool destroyNode = false)
{
if (node is BaseMaterialNode)
{
if (!((BaseMaterialNode) node).canDeleteNode)
return;
}
base.RemoveNode(node, destroyNode);
}
public override Edge Connect(Slot fromSlot, Slot toSlot)
{
Slot outputSlot = null;

10
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs


foreach (var e in elements.Where(x => x is DrawableMaterialNode))
{
var node = ((DrawableMaterialNode) e).m_Node;
if (!node.canDeleteNode)
continue;
foreach (var slot in node.slots)
{

// now delete the nodes
foreach (var e in elements.Where(x => x is DrawableMaterialNode))
{
Debug.Log("Deleting node " + e + " " + ((DrawableMaterialNode) e).m_Node);
graph.currentGraph.RemoveNode(((DrawableMaterialNode) e).m_Node);
var node = ((DrawableMaterialNode)e).m_Node;
if (!node.canDeleteNode)
continue;
Debug.Log("Deleting node " + e + " " + node);
graph.currentGraph.RemoveNode(node);
}
graph.currentGraph.RevalidateGraph();
}

79
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs


#region Fields
private const int kPreviewWidth = 64;
private const int kPreviewHeight = 64;
[SerializeField]
private List<SlotDefaultValueKVP> m_SlotDefaultValues;
[NonSerialized]
private Material m_Material;
[SerializeField]
private string m_GUID = string.Empty;
[SerializeField]
private List<SlotDefaultValueKVP> m_SlotDefaultValues;
protected string guid
{
get
{
if (string.IsNullOrEmpty(m_GUID))
{
var newGUID = Guid.NewGuid();
m_GUID = newGUID.ToString("N");
}
return m_GUID;
}
}
[SerializeField]
private DrawMode m_DrawMode = DrawMode.Full;

public string[] m_PrecisionNames = {"half"};
protected virtual bool generateDefaultInputs { get { return true; } }
public virtual bool canDeleteNode { get { return true; } }
public SlotValue GetSlotDefaultValue(string slotName)
{

private static Shader s_DefaultPreviewShader;
[SerializeField]
private int m_LastShaderHash;
protected static Shader defaultPreviewShader
{
get
{
if (s_DefaultPreviewShader == null)
s_DefaultPreviewShader = Shader.Find("Diffuse");
[SerializeField]
private Shader m_PreviewShader;
return s_DefaultPreviewShader;
}
}
[SerializeField]
private Material m_PreviewMaterial;
public Material previewMaterial
{

if (m_Material == null)
if (m_PreviewMaterial == null)
m_Material = new Material(defaultPreviewShader) {hideFlags = HideFlags.DontSave};
UpdatePreviewMaterial();
UpdatePreviewShader();
m_PreviewMaterial = new Material(m_PreviewShader) {hideFlags = HideFlags.HideInHierarchy};
m_PreviewMaterial.hideFlags = HideFlags.HideInHierarchy;
AssetDatabase.AddObjectToAsset(m_PreviewMaterial, this);
return m_Material;
return m_PreviewMaterial;
}
}

#region Previews
protected virtual bool UpdatePreviewMaterial()
protected virtual bool UpdatePreviewShader()
{
if (hasError)
return false;

protected bool InternalUpdatePreviewShader(string resultShader)
{
MaterialWindow.DebugMaterialGraph("RecreateShaderAndMaterial : " + name + "_" + GetInstanceID() + "\n" + resultShader);
if (previewMaterial.shader != defaultPreviewShader)
DestroyImmediate(previewMaterial.shader, true);
previewMaterial.shader = ShaderUtil.CreateShaderAsset(resultShader);
previewMaterial.shader.hideFlags = HideFlags.DontSave;
MaterialWindow.DebugMaterialGraph("RecreateShaderAndMaterial : " + name + "_" + guid + "\n" + resultShader);
if (m_PreviewShader == null)
{
m_PreviewShader = ShaderUtil.CreateShaderAsset(resultShader);
m_PreviewShader.hideFlags = HideFlags.HideInHierarchy;
AssetDatabase.AddObjectToAsset(m_PreviewShader, this);
m_LastShaderHash = resultShader.GetHashCode();
}
else
{
var hash = resultShader.GetHashCode();
if (hash != m_LastShaderHash)
{
ShaderUtil.UpdateShaderAsset(m_PreviewShader, resultShader);
m_LastShaderHash = hash;
}
}
var result = hasErrorsCall.Invoke(null, new object[] {previewMaterial.shader});
var result = hasErrorsCall.Invoke(null, new object[] {m_PreviewShader});
return (int)result == 0;
}

public virtual string GetOutputVariableNameForNode()
{
return name + "_" + Math.Abs(GetInstanceID());
return name + "_" + guid;
}
public virtual Vector4 GetNewSlotDefaultValue(SlotValueType type)
{

if (!hasError)
{
bool valid = UpdatePreviewMaterial();
bool valid = UpdatePreviewShader();
if (!valid)
hasError = true;
}

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/ColorNode.cs


using System;
using System.Linq;
[Title("Generate/Color Node")]
[Title("Input/Color Node")]
class ColorNode : PropertyNode, IGeneratesBodyCode
{
[SerializeField]

11
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Output/Pixel Shader")]
public class PixelShaderNode : BaseMaterialNode, IGeneratesBodyCode
//[Title("Output/Pixel Shader")]
public class PixelShaderNode : BaseMaterialNode, IGeneratesBodyCode
[SerializeField]
private string m_LightFunctionClassName;

}
protected override bool generateDefaultInputs { get { return false; } }
public override bool canDeleteNode { get { return false; } }
public override void OnEnable()
{

get { return true; }
}
protected override bool UpdatePreviewMaterial()
protected override bool UpdatePreviewShader()
var shaderName = "Hidden/PreviewShader/" + name + "_" + Math.Abs(GetInstanceID());
var shaderName = "Hidden/PreviewShader/" + name + "_" + guid;
List<PropertyGenerator.TextureInfo> defaultTextures;
var resultShader = ShaderGenerator.GenerateSurfaceShader(pixelGraph.owner, shaderName, true, out defaultTextures);
m_GeneratedShaderMode = PreviewMode.Preview3D;

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PropertyNode.cs


get
{
if (!exposed || string.IsNullOrEmpty(m_PropertyName))
return string.Format("{0}_{1}_Uniform", name, Math.Abs(GetInstanceID()));
return string.Format("{0}_{1}_Uniform", name, guid);
return m_PropertyName + "_Uniform";
}

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SinTimeNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Time/Sin Time Node")]
[Title("Input/Sine Time Node")]
public class SinTimeNode : BaseMaterialNode, IRequiresTime
{
private const string kOutputSlotName = "SinTime";

base.OnCreate();
name = "Sin Time";
name = "Sine Time";
}
public override void OnEnable()

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SubGraphNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Sub-graph/Sub-graph Node")]
//[Title("Sub-graph/Sub-graph Node")]
public class SubGraphNode : BaseMaterialNode, IGeneratesBodyCode, IGeneratesVertexToFragmentBlock, IGeneratesFunction, IGeneratesVertexShaderBlock
{
[SerializeField]

1
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/SwizzleNode.cs


using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/TimeNode.cs


namespace UnityEditor.MaterialGraph
{
[Title("Time/Time Node")]
[Title("Input/Time Node")]
public class TimeNode : BaseMaterialNode, IRequiresTime
{
private const string kOutputSlotName = "Time";

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector1Node.cs


namespace UnityEditor.MaterialGraph
{
[Title("Generate/Vector 1 Node")]
[Title("Input/Vector 1 Node")]
class Vector1Node : PropertyNode, IGeneratesBodyCode
{
[SerializeField]

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector2Node.cs


namespace UnityEditor.MaterialGraph
{
[Title("Generate/Vector 2 Node")]
[Title("Input/Vector 2 Node")]
class Vector2Node : PropertyNode, IGeneratesBodyCode
{
private const string kOutputSlotName = "Value";

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector3Node.cs


namespace UnityEditor.MaterialGraph
{
[Title("Generate/Vector 3 Node")]
[Title("Input/Vector 3 Node")]
class Vector3Node : PropertyNode, IGeneratesBodyCode
{
private const string kOutputSlotName = "Value";

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Vector4Node.cs


namespace UnityEditor.MaterialGraph
{
[Title("Generate/Vector 4 Node")]
[Title("Input/Vector 4 Node")]
class Vector4Node : PropertyNode, IGeneratesBodyCode
{
private const string kOutputSlotName = "Value";

5
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/WorldPosNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{

正在加载...
取消
保存