浏览代码

Refactored subgraph to abstract subgraph + remap subgraph. This is groundwork to allow for real remap master nodes.

/main
Tim Cooper 7 年前
当前提交
76430e32
共有 22 个文件被更改,包括 457 次插入689 次删除
  1. 7
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/NodeUtils.cs
  2. 1
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableGraph.cs
  3. 18
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/AbstractMaterialGraphEditWindow.cs
  4. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs
  5. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/IGenerateProperties.cs
  6. 116
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapGraph.cs
  7. 75
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MasterRemapInputNode.cs
  8. 15
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/MaterialRemapAsset.cs
  9. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/MaterialSubGraphAsset.cs
  10. 94
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraph.cs
  11. 290
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs
  12. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphOutputNode.cs
  13. 23
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporter.cs
  14. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporter.cs.meta
  15. 41
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporterEditor.cs
  16. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Importers/MasterRemapGraphImporterEditor.cs.meta
  17. 65
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraph.cs
  18. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraph.cs.meta
  19. 229
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphNode.cs
  20. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/AbstractSubGraphNode.cs.meta
  21. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/RemapMasterNode.cs.meta
  22. 140
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Remapper/RemapMasterNode.cs

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


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

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


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

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


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

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

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

private void UpdateShaderGraphOnDisk(string path)
{

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


collector.AddShaderProperty(prop);
}
public void AddShaderProperty(IShaderProperty property)
public virtual void AddShaderProperty(IShaderProperty property)
{
if (property == null)
return;

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


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

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


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

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


namespace UnityEngine.MaterialGraph
{
/*
, INodeGroupRemapper
[NonSerialized]
internal RemapMasterNode m_RemapTarget;
public MasterRemapInputNode()
{
name = "Inputs";

{
var nextSlotId = GetOutputSlots<ISlot>().Count() + 1;
AddSlot(new MaterialSlot(-nextSlotId, "Input " + nextSlotId, "Input" + nextSlotId, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
return -nextSlotId;
var index = GetInputSlots<ISlot>().Count() + 1;
AddSlot(new MaterialSlot(index, "Output " + index, "Output" + index, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
return index;
var lastSlotId = GetOutputSlots<ISlot>().Count();
if (lastSlotId == 0)
var index = GetInputSlots<ISlot>().Count();
if (index == 0)
RemoveSlot(-lastSlotId);
}
public void DepthFirstCollectNodesFromNodeSlotList(List<INode> nodeList, NodeUtils.IncludeSelf includeSelf)
{
NodeUtils.DepthFirstCollectNodesFromNode(nodeList, m_RemapTarget, NodeUtils.IncludeSelf.Exclude);
RemoveSlot(index);
public bool IsValidSlotConnection(int slotId)
{
if (m_RemapTarget == null)
return false;
var slot = m_RemapTarget.FindSlot<MaterialSlot>(slotId);
if (slot == null)
return false;
var edge = m_RemapTarget.owner.GetEdges(slot.slotReference).FirstOrDefault();
if (edge == null)
return false;
var outputRef = edge.outputSlot;
var fromNode = m_RemapTarget.owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
if (fromNode == null)
return false;
return true;
}
public override string GetVariableNameForSlot(int slotId)
{
if (m_RemapTarget == null)
{
var defaultValueSlot = FindSlot<MaterialSlot>(slotId);
if (defaultValueSlot == null)
throw new ArgumentException(string.Format("Attempting to use MaterialSlot({0}) on node of type {1} where this slot can not be found", slotId, this), "slotId");
return defaultValueSlot.GetDefaultValue(GenerationMode.ForReals);
}
var slot = m_RemapTarget.FindSlot<MaterialSlot>(slotId);
if (slot == null)
throw new ArgumentException(string.Format("Attempting to use MaterialSlot({0}) on node of type {1} where this slot can not be found", slotId, this), "slotId");
if (slot.isOutputSlot)
throw new Exception(string.Format("Attempting to use OutputSlot({0}) on remap node)", slotId));
var edge = m_RemapTarget.owner.GetEdges(slot.slotReference).FirstOrDefault();
if (edge == null)
return slot.GetDefaultValue(GenerationMode.ForReals);
var outputRef = edge.outputSlot;
var fromNode = m_RemapTarget.owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
if (fromNode == null)
return slot.GetDefaultValue(GenerationMode.ForReals);
return fromNode.GetVariableNameForSlot(outputRef.slotId);
}
}*/
}
}

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


namespace UnityEngine.MaterialGraph
{
/* public class MaterialRemapAsset : AbstractMaterialGraphAsset
public class MasterRemapGraphAsset : ScriptableObject
private MasterRemapGraph m_MasterRemapGraph = new MasterRemapGraph();
private MasterRemapGraph m_RemapGraph = new MasterRemapGraph();
public override IGraph graph
public MasterRemapGraph remapGraph
get { return m_MasterRemapGraph; }
get { return m_RemapGraph; }
set { m_RemapGraph = value; }
}
public MasterRemapGraph masterRemapGraph
{
get { return m_MasterRemapGraph; }
}
}*/
}

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


set { m_MaterialSubGraph = value; }
}
}
}

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


namespace UnityEngine.MaterialGraph
{
[Serializable]
public class SubGraph : AbstractMaterialGraph
, IGeneratesBodyCode
, IGeneratesFunction
public class SubGraph : AbstractSubGraph
{
[NonSerialized]
private SubGraphOutputNode m_OutputNode;

}
}
[NonSerialized]
private List<INode> m_ActiveNodes = new List<INode>();
public IEnumerable<AbstractMaterialNode> activeNodes
{
get
{
m_ActiveNodes.Clear();
NodeUtils.DepthFirstCollectNodesFromNode(m_ActiveNodes, outputNode);
return m_ActiveNodes.OfType<AbstractMaterialNode>();
}
}
public override void OnAfterDeserialize()
{
base.OnAfterDeserialize();

base.AddNode(node);
}
private IEnumerable<AbstractMaterialNode> usedNodes
public override IEnumerable<AbstractMaterialNode> activeNodes
var nodes = new List<INode>();
//Get the rest of the nodes for all the other slots
NodeUtils.DepthFirstCollectNodesFromNode(nodes, outputNode, NodeUtils.IncludeSelf.Exclude);
List<INode> nodes = new List<INode>();
NodeUtils.DepthFirstCollectNodesFromNode(nodes, outputNode);
public PreviewMode previewMode
{
get { return usedNodes.Any(x => x.previewMode == PreviewMode.Preview3D) ? PreviewMode.Preview3D : PreviewMode.Preview2D; }
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGeneratesBodyCode)
(node as IGeneratesBodyCode).GenerateNodeCode(visitor, generationMode);
}
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
if (node is IGeneratesFunction)
(node as IGeneratesFunction).GenerateNodeFunction(visitor, generationMode);
}
}
public override void CollectShaderProperties(PropertyCollector collector, GenerationMode generationMode)
{
// if we are previewing the graph we need to
// export 'exposed props' if we are 'for real'
// then we are outputting the graph in the
// nested context and the needed values will
// be copied into scope.
if (generationMode == GenerationMode.Preview)
{
foreach (var prop in properties)
collector.AddShaderProperty(prop);
}
foreach (var node in usedNodes)
{
if (node is IGenerateProperties)
(node as IGenerateProperties).CollectShaderProperties(collector, generationMode);
}
}
public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
//TODO: Fix
//if (node is IGeneratesVertexShaderBlock)
// (node as IGeneratesVertexShaderBlock).GenerateVertexShaderBlock(visitor, generationMode);
}
}
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var node in usedNodes)
{
//TODO: Fix
//if (node is IGeneratesVertexToFragmentBlock)
// (node as IGeneratesVertexToFragmentBlock).GenerateVertexToFragmentBlock(visitor, generationMode);
}
}
public IEnumerable<PreviewProperty> GetPreviewProperties()
{
List<PreviewProperty> props = new List<PreviewProperty>();
foreach (var node in usedNodes)
node.CollectPreviewMaterialProperties(props);
return props;
}
}
}

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


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

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

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

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

}
public void OnEnable()
{
var validNames = new List<int>();
if (subGraphAsset == null)
{
RemoveSlotsNameNotMatching(validNames);
return;
}
var props = subGraph.properties;
foreach (var prop in props)
{
var propType = prop.propertyType;
SlotValueType slotType;
switch (propType)
{
case PropertyType.Color:
slotType = SlotValueType.Vector4;
break;
case PropertyType.Texture:
slotType = SlotValueType.Texture2D;
break;
case PropertyType.Float:
slotType = SlotValueType.Vector1;
break;
case PropertyType.Vector2:
slotType = SlotValueType.Vector2;
break;
case PropertyType.Vector3:
slotType = SlotValueType.Vector3;
break;
case PropertyType.Vector4:
slotType = SlotValueType.Vector4;
break;
case PropertyType.Matrix2:
slotType = SlotValueType.Matrix2;
break;
case PropertyType.Matrix3:
slotType = SlotValueType.Matrix3;
break;
case PropertyType.Matrix4:
slotType = SlotValueType.Matrix4;
break;
default:
throw new ArgumentOutOfRangeException();
}
var id = prop.guid.GetHashCode();
AddSlot(new MaterialSlot(id, prop.referenceName, prop.referenceName, SlotType.Input, slotType, prop.defaultValue));
validNames.Add(id);
}
var subGraphOutputNode = subGraphAsset.subGraph.outputNode;
foreach (var slot in subGraphOutputNode.GetInputSlots<MaterialSlot>())
{
AddSlot(new MaterialSlot(slot.id, slot.displayName, slot.shaderOutputName, SlotType.Output, slot.valueType, slot.defaultValue));
validNames.Add(slot.id);
}
RemoveSlotsNameNotMatching(validNames);
}
if (subGraphAsset == null)
if (subGraph == null)
return;
var outputString = new ShaderGenerator();

// we do this by renaming the properties to be the names of where the variables come from
// weird, but works.
var sSubGraph = SerializationHelper.Serialize(subGraphAsset.subGraph);
var subGraph = SerializationHelper.Deserialize<SubGraph>(sSubGraph, null);
var dSubGraph = SerializationHelper.Deserialize<SubGraph>(sSubGraph, null);
var subGraphInputs = subGraph.properties;
var subGraphInputs = dSubGraph.properties;
subGraph.CollectShaderProperties(propertyGen, GenerationMode.ForReals);
dSubGraph.CollectShaderProperties(propertyGen, GenerationMode.ForReals);
foreach (var prop in subGraphInputs)
{

// Step 4...
// Using the inputs we can now generate the shader body :)
var bodyGenerator = new ShaderGenerator();
subGraph.GenerateNodeCode(bodyGenerator, GenerationMode.ForReals);
var subGraphOutputNode = subGraph.outputNode;
dSubGraph.GenerateNodeCode(bodyGenerator, GenerationMode.ForReals);
var subGraphOutputNode = dSubGraph.outputNode;
outputString.AddShaderChunk(bodyGenerator.GetShaderString(0), false);
// Step 5...

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

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


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

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


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

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


fileFormatVersion: 2
guid: 47e38a0256e24cec8792d9cfae7023b2
timeCreated: 1506845544

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


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

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


fileFormatVersion: 2
guid: 4dd321ee05034e7a967503617a02c1f4
timeCreated: 1506845783

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


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

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


fileFormatVersion: 2
guid: f2b67435729448498da7e7b90f052ebd
timeCreated: 1506844687

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


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

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


fileFormatVersion: 2
guid: bc4cf774a7a6480ba543eb6069cd1c50
timeCreated: 1506847426

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


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

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


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