浏览代码

Fix nodes so that the master node now can do a mapping from vertex input to usage by the master node.

/main
Tim Cooper 8 年前
当前提交
bc6130d7
共有 20 个文件被更改,包括 200 次插入123 次删除
  1. 10
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Testing/IntegrationTests/SerializationTests.cs
  2. 17
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableGraph.cs
  3. 2
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableNode.cs
  4. 24
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Util/SerializationHelper.cs
  5. 1
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/ShaderGenerationTest.cs
  6. 29
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs
  7. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractSurfaceMasterNode.cs
  8. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ScreenPosNode.cs
  9. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TextureNode.cs
  10. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UVNode.cs
  11. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceNormalNode.cs
  12. 26
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs
  13. 50
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpacePositionNode.cs
  14. 50
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceViewDirectionNode.cs
  15. 45
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ViewDirectionNode.cs
  16. 45
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldPosNode.cs
  17. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceNormalNode.cs.meta
  18. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceViewDirectionNode.cs.meta
  19. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpacePositionNode.cs.meta
  20. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceNormalNode.cs

10
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Editor/Testing/IntegrationTests/SerializationTests.cs


var serialized = SerializationHelper.Serialize<SimpleSerializeClass>(toSerialize);
Assert.AreEqual(1, serialized.Count);
var loaded = SerializationHelper.Deserialize<SimpleSerializeClass>(serialized);
var loaded = SerializationHelper.Deserialize<SimpleSerializeClass>(serialized, null);
Assert.AreEqual(1, loaded.Count);
Assert.IsInstanceOf<SimpleSerializeClass>(loaded[0]);
loaded[0].AssertAsReference();

var serialized = SerializationHelper.Serialize<SimpleSerializeClass>(toSerialize);
Assert.AreEqual(3, serialized.Count);
var loaded = SerializationHelper.Deserialize<SimpleSerializeClass>(serialized);
var loaded = SerializationHelper.Deserialize<SimpleSerializeClass>(serialized, null);
Assert.AreEqual(3, loaded.Count);
Assert.IsInstanceOf<SimpleSerializeClass>(loaded[0]);
Assert.IsInstanceOf<ChildClassA>(loaded[1]);

var serialized = SerializationHelper.Serialize<ITestInterface>(toSerialize);
Assert.AreEqual(3, serialized.Count);
var loaded = SerializationHelper.Deserialize<SimpleSerializeClass>(serialized);
var loaded = SerializationHelper.Deserialize<SimpleSerializeClass>(serialized, null);
Assert.AreEqual(3, loaded.Count);
Assert.IsInstanceOf<SimpleSerializeClass>(loaded[0]);
Assert.IsInstanceOf<ChildClassA>(loaded[1]);

var serializedContainer = JsonUtility.ToJson(container, true);
var deserializedContainer = JsonUtility.FromJson<SerializationContainer>(serializedContainer);
var loaded = SerializationHelper.Deserialize<SimpleSerializeClass>(deserializedContainer.serializedElements);
var loaded = SerializationHelper.Deserialize<SimpleSerializeClass>(deserializedContainer.serializedElements, null);
Assert.AreEqual(1, loaded.Count);
Assert.IsInstanceOf<SimpleSerializeClass>(loaded[0]);
loaded[0].AssertAsReference();

};
var serialized = SerializationHelper.Serialize<SerializableSlot>(toSerialize);
var loaded = SerializationHelper.Deserialize<SerializableSlot>(serialized);
var loaded = SerializationHelper.Deserialize<SerializableSlot>(serialized, null);
Assert.AreEqual(2, loaded.Count);
Assert.IsInstanceOf<SerializableSlot>(loaded[0]);

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


m_Nodes.Remove(node);
}
public virtual Dictionary<SerializationHelper.TypeSerializationInfo, SerializationHelper.TypeSerializationInfo> GetLegacyTypeRemapping()
{
return new Dictionary<SerializationHelper.TypeSerializationInfo, SerializationHelper.TypeSerializationInfo>();
}
public virtual IEdge Connect(SlotReference fromSlotRef, SlotReference toSlotRef)
{
if (fromSlotRef == null || toSlotRef == null)

if (s == null)
return new Edge[0];
var edges = m_Edges.Where(x =>
var foundEdges = m_Edges.Where(x =>
if (edges.Count == 0)
if (foundEdges.Count == 0)
{
var slot = GetNodeFromGuid(s.nodeGuid).FindInputSlot<ISlot>(s.slotId);
if (slot is IGenerateDefaultInput)

m_VirtualNodes.Add(defaultNode);
node = defaultNode;
}
edges.Add(new Edge(new SlotReference(node.guid, defaultInputProvider.defaultSlotID), s));
foundEdges.Add(new Edge(new SlotReference(node.guid, defaultInputProvider.defaultSlotID), s));
return edges;
return foundEdges;
}
public virtual void OnBeforeSerialize()

public virtual void OnAfterDeserialize()
{
m_Nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes);
m_Nodes = SerializationHelper.Deserialize<INode>(m_SerializableNodes, GetLegacyTypeRemapping());
m_Edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges);
m_Edges = SerializationHelper.Deserialize<IEdge>(m_SerializableEdges, null);
m_SerializableEdges = null;
m_VirtualNodes = new List<INode>();

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


else
m_Guid = Guid.NewGuid();
m_Slots = SerializationHelper.Deserialize<ISlot>(m_SerializableSlots);
m_Slots = SerializationHelper.Deserialize<ISlot>(m_SerializableSlots, null);
m_SerializableSlots = null;
foreach (var s in m_Slots)
s.owner = this;

24
MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Util/SerializationHelper.cs


}
}
private static TypeSerializationInfo GetTypeSerializableAsString(Type type)
public static TypeSerializationInfo GetTypeSerializableAsString(Type type)
{
return new TypeSerializationInfo
{

};
}
public static T Deserialize<T>(JSONSerializedElement item, params object[] constructorArgs) where T : class
private static TypeSerializationInfo DoTypeRemap(TypeSerializationInfo info, Dictionary<TypeSerializationInfo, TypeSerializationInfo> remapper)
{
TypeSerializationInfo foundInfo;
if (remapper.TryGetValue(info, out foundInfo))
return foundInfo;
return info;
}
public static T Deserialize<T>(JSONSerializedElement item, Dictionary<TypeSerializationInfo, TypeSerializationInfo> remapper, params object[] constructorArgs) where T : class
var type = GetTypeFromSerializedString(item.typeInfo);
TypeSerializationInfo info = item.typeInfo;
if (remapper != null)
info = DoTypeRemap(info, remapper);
var type = GetTypeFromSerializedString(info);
throw new ArgumentException(string.Format("Can not deserialize {0}, type {1} is invalid", item.typeInfo));
throw new ArgumentException(string.Format("Can not deserialize {0}, type {1} is invalid", info));
T instance;
try

return result;
}
public static List<T> Deserialize<T>(IEnumerable<JSONSerializedElement> list, params object[] constructorArgs) where T : class
public static List<T> Deserialize<T>(IEnumerable<JSONSerializedElement> list, Dictionary<TypeSerializationInfo, TypeSerializationInfo> remapper, params object[] constructorArgs) where T : class
{
var result = new List<T>();
if (list == null)

{
try
{
result.Add(Deserialize<T>(element));
result.Add(Deserialize<T>(element, remapper));
}
catch (Exception e)
{

1
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/IntegrationTests/ShaderGenerationTest.cs


using UnityEngine.MaterialGraph;
using Object = UnityEngine.Object;
namespace UnityEditor.MaterialGraph.IntegrationTests
{
public class ShaderGenerationTest

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


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

{
Debug.LogWarningFormat("Trying to add node {0} to Material graph, but it is not a {1}", node, typeof(AbstractMaterialNode));
}
}
public override Dictionary<SerializationHelper.TypeSerializationInfo, SerializationHelper.TypeSerializationInfo> GetLegacyTypeRemapping()
{
var result = base.GetLegacyTypeRemapping();
var viewNode = new SerializationHelper.TypeSerializationInfo
{
fullName = "UnityEngine.MaterialGraph.ViewDirectionNode",
assemblyName = "Assembly-CSharp"
};
result[viewNode] = SerializationHelper.GetTypeSerializableAsString(typeof(WorldSpaceViewDirectionNode));
var normalNode = new SerializationHelper.TypeSerializationInfo
{
fullName = "UnityEngine.MaterialGraph.NormalNode",
assemblyName = "Assembly-CSharp"
};
result[normalNode] = SerializationHelper.GetTypeSerializableAsString(typeof(WorldSpaceNormalNode));
var worldPosNode = new SerializationHelper.TypeSerializationInfo
{
fullName = "UnityEngine.MaterialGraph.WorldPosNode",
assemblyName = "Assembly-CSharp"
};
result[worldPosNode] = SerializationHelper.GetTypeSerializableAsString(typeof(WorldSpacePositionNode));
return result;
}
}
}

9
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractSurfaceMasterNode.cs


if (activeNodeList.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV()))
{
shaderInputVisitor.AddShaderChunk("half4 meshUV0 : TEXCOORD0;", true);
shaderInputVisitor.AddShaderChunk("half4 meshUV0;", true);
shaderBody.AddShaderChunk("half4 " + ShaderGeneratorNames.UV0 + " = IN.meshUV0;", true);
shaderBody.AddShaderChunk("fixed3 worldViewDir = IN.worldViewDir;", true);
shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceViewDirection + " = IN.worldViewDir;", true);
shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpacePosition + " = IN.worldPos;", true);
shaderBody.AddShaderChunk("float4 " + ShaderGeneratorNames.ScreenPosition + " = IN.screenPos;", true);
}
if (activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal()))

shaderInputVisitor.AddShaderChunk("float3 worldNormal;", true);
if (edges.Any())
shaderInputVisitor.AddShaderChunk("INTERNAL_DATA", true);
shaderBody.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceNormal + " = normalize(IN.worldNormal);", true);
}
GenerateNodeCode(shaderBody, mode);

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ScreenPosNode.cs


public override string GetVariableNameForSlot(int slotId)
{
return "IN.screenPos";
return ShaderGeneratorNames.ScreenPosition;
}
public bool RequiresScreenPosition()

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


defaultTexture, m_TextureType,
PropertyChunk.HideState.Visible,
exposedState == ExposedState.Exposed ?
TexturePropertyChunk.ModifiableState.Modifiable
: TexturePropertyChunk.ModifiableState.NonModifiable));
TexturePropertyChunk.ModifiableState.Modifiable
: TexturePropertyChunk.ModifiableState.NonModifiable));
}
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode)

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


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
string uvValue = "IN.meshUV0";
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(OutputSlotId) + " = " + uvValue + ";", true);
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(OutputSlotId) + " = " + ShaderGeneratorNames.UV0 + ";", true);
}
public bool RequiresMeshUV()

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


}
[Title("Input/World Normal Node")]
public class NormalNode : AbstractMaterialNode, IMayRequireNormal
public class WorldSpaceNormalNode : AbstractMaterialNode, IMayRequireNormal
public NormalNode()
public WorldSpaceNormalNode()
{
name = "World Normal";
UpdateNodeAfterDeserialization();

public override string GetVariableNameForSlot(int slotId)
{
return "IN.worldNormal";
return ShaderGeneratorNames.WorldSpaceNormal;
}
public bool RequiresNormal()

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


namespace UnityEngine.MaterialGraph
{
public static class ShaderGeneratorNames
{
public const string WorldSpaceNormal = "worldSpaceNormal";
public const string WorldSpacePosition = "worldPosition";
public const string WorldSpaceViewDirection = "worldSpaceViewDirection";
public const string ScreenPosition = "screenPosition";
public const string UV0 = "uv0";
}
public class ShaderGenerator
{
private struct ShaderChunk

bool needsWorldPos = activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
if (needsWorldPos || activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition()))
{
shaderInputVisitor.AddShaderChunk("float3 worldPos : TEXCOORD2;", true);
shaderInputVisitor.AddShaderChunk("float3 worldPos : TEXCOORD0;", true);
shaderBodyVisitor.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpacePosition + " = IN.worldPos;", true);
shaderInputVisitor.AddShaderChunk("float3 worldNormal : TEXCOORD3;", true);
shaderInputVisitor.AddShaderChunk("float3 worldNormal : TEXCOORD1;", true);
shaderBodyVisitor.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceNormal + " = normalize(IN.worldNormal);", true);
shaderInputVisitor.AddShaderChunk("half4 meshUV0 : TEXCOORD0;", true);
shaderInputVisitor.AddShaderChunk("half4 meshUV0 : TEXCOORD2;", true);
shaderBodyVisitor.AddShaderChunk("half4 " + ShaderGeneratorNames.UV0 + " = IN.meshUV0;", true);
shaderBodyVisitor.AddShaderChunk("fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(IN.worldPos));", true);
shaderBodyVisitor.AddShaderChunk(
"float3 "
+ ShaderGeneratorNames.WorldSpaceViewDirection
+ " = normalize(UnityWorldSpaceViewDir("
+ ShaderGeneratorNames.WorldSpacePosition
+ "));", true);
}
if (activeNodeList.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition()))

shaderBodyVisitor.AddShaderChunk("half4 " + ShaderGeneratorNames.ScreenPosition + " = IN.screenPos;", true);
}
var generationMode = GenerationMode.Preview;

50
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpacePositionNode.cs


using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
interface IMayRequireWorldPosition
{
bool RequiresWorldPosition();
}
[Title("Input/World Space Position Node")]
public class WorldSpacePositionNode : AbstractMaterialNode, IMayRequireWorldPosition
{
private const int kOutputSlotId = 0;
public override bool hasPreview { get { return true; } }
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
public WorldSpacePositionNode()
{
name = "World Space Pos";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(
kOutputSlotId,
ShaderGeneratorNames.WorldSpacePosition,
ShaderGeneratorNames.WorldSpacePosition,
SlotType.Output,
SlotValueType.Vector3,
Vector4.zero));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.WorldSpacePosition;
}
public bool RequiresWorldPosition()
{
return true;
}
}
}

50
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceViewDirectionNode.cs


using System.ComponentModel;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
interface IMayRequireViewDirection
{
bool RequiresViewDirection();
}
[Title("Input/World Space View Direction Node")]
public class WorldSpaceViewDirectionNode : AbstractMaterialNode, IMayRequireViewDirection
{
private const int kOutputSlotId = 0;
public override bool hasPreview { get { return true; } }
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
public WorldSpaceViewDirectionNode()
{
name = "World View Direction";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(
kOutputSlotId,
ShaderGeneratorNames.WorldSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection,
SlotType.Output,
SlotValueType.Vector3,
Vector4.zero));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.WorldSpaceViewDirection;
}
public bool RequiresViewDirection()
{
return true;
}
}
}

45
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ViewDirectionNode.cs


using System.ComponentModel;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
interface IMayRequireViewDirection
{
bool RequiresViewDirection();
}
[Title("Input/View Direction Node")]
public class ViewDirectionNode : AbstractMaterialNode, IMayRequireViewDirection
{
private const int kOutputSlotId = 0;
private const string kOutputSlotName = "ViewDirection";
public override bool hasPreview { get { return true; } }
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
public ViewDirectionNode()
{
name = "View Direction";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(kOutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector3, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(int slotId)
{
return "worldViewDir";
}
public bool RequiresViewDirection()
{
return true;
}
}
}

45
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldPosNode.cs


using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
interface IMayRequireWorldPosition
{
bool RequiresWorldPosition();
}
[Title("Input/World Pos Node")]
public class WorldPosNode : AbstractMaterialNode, IMayRequireWorldPosition
{
private const int kOutputSlotId = 0;
private const string kOutputSlotName = "WorldPos";
public override bool hasPreview { get { return true; } }
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
public WorldPosNode()
{
name = "WorldPos";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(kOutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector3, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(int slotId)
{
return "IN.worldPos";
}
public bool RequiresWorldPosition()
{
return true;
}
}
}

/MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/NormalNode.cs.meta → /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceNormalNode.cs.meta

/MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ViewDirectionNode.cs.meta → /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceViewDirectionNode.cs.meta

/MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldPosNode.cs.meta → /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpacePositionNode.cs.meta

/MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/NormalNode.cs → /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldSpaceNormalNode.cs

正在加载...
取消
保存