浏览代码

[Material Graph]Use slotid's instead of slots.

/main
Tim Cooper 8 年前
当前提交
6ef35ae3
共有 25 个文件被更改,包括 197 次插入220 次删除
  1. 33
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/NodeUtils.cs
  2. 15
      MaterialGraphProject/Assets/GraphFramework/SerializableGraph/Runtime/Implementation/SerializableNode.cs
  3. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/Function1InputTests.cs
  4. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/Function2InputTests.cs
  5. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/Function3InputTests.cs
  6. 71
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/ShaderGeneratorTests.cs
  7. 48
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Light/BaseLightFunction.cs
  8. 18
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/AbstractMaterialNode.cs
  9. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function1Input.cs
  10. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function2Input.cs
  11. 20
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function3Input.cs
  12. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MaterialSlot.cs
  13. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/NormalNode.cs
  14. 16
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PixelShaderNode.cs
  15. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/PropertyNode.cs
  16. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ScreenPosNode.cs
  17. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/SinTimeNode.cs
  18. 47
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TextureNode.cs
  19. 34
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TimeNode.cs
  20. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/UVNode.cs
  21. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/ViewDirectionNode.cs
  22. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/WorldPosNode.cs
  23. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs
  24. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs
  25. 24
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs

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


using System;
using System.Collections.Generic;
using System.Linq;

{
public class SlotConfigurationException : Exception
{
public SlotConfigurationException()
{ }
public SlotConfigurationException(string message)
: base(message)
{}
public SlotConfigurationException(string message, Exception inner)
: base(message, inner)
{}
}
public static void SlotConfigurationExceptionIfBadConfiguration(INode node, IEnumerable<int> expectedInputSlots, IEnumerable<int> expectedOutputSlots )
{
var missingSlots = new List<int>();
var inputSlots = expectedInputSlots as IList<int> ?? expectedInputSlots.ToList();
missingSlots.AddRange(inputSlots.Except(node.GetInputSlots<ISlot>().Select(x => x.id)));
var outputSlots = expectedOutputSlots as IList<int> ?? expectedOutputSlots.ToList();
missingSlots.AddRange(outputSlots.Except(node.GetOutputSlots<ISlot>().Select(x => x.id)));
if (missingSlots.Count == 0)
return;
var toPrint = missingSlots.Select(x => x.ToString());
throw new SlotConfigurationException(string.Format("Missing slots {0} on node {1}", string.Join(", ", toPrint.ToArray()), node));
}
public static IEnumerable<IEdge> GetAllEdges(INode node)
{
var result = new List<IEdge>();

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


public T FindSlot<T>(int slotId) where T: ISlot
{
var slot = GetSlots<T>().FirstOrDefault(x => x.id == slotId);
if (slot == null)
Debug.LogErrorFormat("Input Slot: {0} could be found on node {1}", name, this);
return slot;
return GetSlots<T>().FirstOrDefault(x => x.id == slotId);
var slot = GetInputSlots<T>().FirstOrDefault(x => x.id == slotId);
if (slot == null)
Debug.LogErrorFormat("Input Slot: {0} could be found on node {1}", name, this);
return slot;
return GetInputSlots<T>().FirstOrDefault(x => x.id == slotId);
var slot = GetOutputSlots<T>().FirstOrDefault(x => x.id == slotId);
if (slot == null)
Debug.LogErrorFormat("Output Slot: {0} could be found on node {1}", name, this);
return slot;
return GetOutputSlots<T>().FirstOrDefault(x => x.id == slotId);
}
public virtual void OnBeforeSerialize()

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/Function1InputTests.cs


public void TestGenerateNodeCodeGeneratesCorrectCode()
{
string expected = string.Format("half {0} = unity_test_half ({1});"
, m_TestNode.GetVariableNameForSlot(m_TestNode.GetOutputSlots<MaterialSlot>().FirstOrDefault())
, m_InputOne.GetVariableNameForSlot(m_InputOne.GetOutputSlots<MaterialSlot>().FirstOrDefault())
, m_TestNode.GetVariableNameForSlot(Function1Input.OutputSlotId)
, m_InputOne.GetVariableNameForSlot(Vector1Node.OutputSlotId)
);
ShaderGenerator visitor = new ShaderGenerator();

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/Function2InputTests.cs


public void TestGenerateNodeCodeGeneratesCorrectCode()
{
string expected = string.Format("half {0} = unity_test_half ({1}, {2});"
, m_TestNode.GetVariableNameForSlot(m_TestNode.GetOutputSlots<MaterialSlot>().FirstOrDefault())
, m_InputOne.GetVariableNameForSlot(m_InputOne.GetOutputSlots<MaterialSlot>().FirstOrDefault())
, m_InputTwo.GetVariableNameForSlot(m_InputTwo.GetOutputSlots<MaterialSlot>().FirstOrDefault())
, m_TestNode.GetVariableNameForSlot(Function2Input.OutputSlotId)
, m_InputOne.GetVariableNameForSlot(Vector1Node.OutputSlotId)
, m_InputTwo.GetVariableNameForSlot(Vector1Node.OutputSlotId)
);
ShaderGenerator visitor = new ShaderGenerator();

9
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/Function3InputTests.cs


public void TestGenerateNodeCodeGeneratesCorrectCode()
{
string expected = string.Format("half {0} = unity_test_half ({1}, {2}, {3});"
, m_TestNode.GetVariableNameForSlot(m_TestNode.GetOutputSlots<MaterialSlot>().FirstOrDefault())
, m_InputOne.GetVariableNameForSlot(m_InputOne.GetOutputSlots<MaterialSlot>().FirstOrDefault())
, m_InputTwo.GetVariableNameForSlot(m_InputTwo.GetOutputSlots<MaterialSlot>().FirstOrDefault())
, m_InputThree.GetVariableNameForSlot(m_InputThree.GetOutputSlots<MaterialSlot>().FirstOrDefault())
);
, m_TestNode.GetVariableNameForSlot(Function3Input.OutputSlotId)
, m_InputOne.GetVariableNameForSlot(Vector1Node.OutputSlotId)
, m_InputTwo.GetVariableNameForSlot(Vector1Node.OutputSlotId)
, m_InputThree.GetVariableNameForSlot(Vector1Node.OutputSlotId));
ShaderGenerator visitor = new ShaderGenerator();
m_TestNode.GenerateNodeCode(visitor, GenerationMode.SurfaceShader);

71
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Testing/UnitTests/ShaderGeneratorTests.cs


public void AdaptNodeOutput1To1Works()
{
var node = new TestNode();
var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V1Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V1Out, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(TestNode.V1Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V1Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V1Out, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(TestNode.V1Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V1Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V1Out, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(TestNode.V1Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V1Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector4);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V1Out, ConcreteSlotValueType.Vector4);
Assert.AreEqual(string.Format("({0})", node.GetVariableNameForSlot(TestNode.V1Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V2Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V2Out, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(TestNode.V2Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V2Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V2Out, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(TestNode.V2Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V2Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector3);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V2Out, ConcreteSlotValueType.Vector3);
Assert.AreEqual("ERROR!", result);
}

var node = new TestNode();
var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V2Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector4);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V2Out, ConcreteSlotValueType.Vector4);
Assert.AreEqual("ERROR!", result);
}

var node = new TestNode();
var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V3Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V3Out, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(TestNode.V3Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V3Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0}.xy)", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V3Out, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0}.xy)", node.GetVariableNameForSlot(TestNode.V3Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V3Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V3Out, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(TestNode.V3Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V3Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector4);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V3Out, ConcreteSlotValueType.Vector4);
Assert.AreEqual("ERROR!", result);
}

var node = new TestNode();
var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V4Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V4Out, ConcreteSlotValueType.Vector1);
Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(TestNode.V4Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V4Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0}.xy)", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V4Out, ConcreteSlotValueType.Vector2);
Assert.AreEqual(string.Format("({0}.xy)", node.GetVariableNameForSlot(TestNode.V4Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V4Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("({0}.xyz)", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V4Out, ConcreteSlotValueType.Vector3);
Assert.AreEqual(string.Format("({0}.xyz)", node.GetVariableNameForSlot(TestNode.V4Out)), result);
}
[Test]

var slot = node.FindOutputSlot<MaterialSlot>(TestNode.V4Out);
var result = ShaderGenerator.AdaptNodeOutput(node, slot, ConcreteSlotValueType.Vector4);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(slot)), result);
var result = ShaderGenerator.AdaptNodeOutput(node, TestNode.V4Out, ConcreteSlotValueType.Vector4);
Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(TestNode.V4Out)), result);
}

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


class PBRMetalicLightFunction : BaseLightFunction
{
public const string kAlbedoSlotName = "Albedo";
public const string kMetallicSlotName = "Metallic";
public const string kEmissionSlotName = "Emission";
public const string kSmoothnessSlotName = "Smoothness";
public const string kOcclusionSlotName = "Occlusion";
public const string kAlphaSlotName = "Alpha";
public const string AlbedoSlotName = "Albedo";
public const string MetallicSlotName = "Metallic";
public const string EmissionSlotName = "Emission";
public const string SmoothnessSlotName = "Smoothness";
public const string OcclusionSlotName = "Occlusion";
public const string AlphaSlotName = "Alpha";
public const int kAlbedoSlotId = 0;
public const int kMetallicSlotId = 2;
public const int kEmissionSlotId = 3;
public const int kSmoothnessSlotId = 4;
public const int kOcclusionSlotId = 5;
public const int kAlphaSlotId = 6;
public const int AlbedoSlotId = 0;
public const int MetallicSlotId = 2;
public const int EmissionSlotId = 3;
public const int SmoothnessSlotId = 4;
public const int OcclusionSlotId = 5;
public const int AlphaSlotId = 6;
node.AddSlot(new MaterialSlot(kAlbedoSlotId, kAlbedoSlotName, kAlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(AlbedoSlotId, AlbedoSlotName, AlbedoSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kEmissionSlotId, kEmissionSlotName, kEmissionSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(kMetallicSlotId, kMetallicSlotName, kMetallicSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kSmoothnessSlotId, kSmoothnessSlotName, kSmoothnessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kOcclusionSlotId, kOcclusionSlotName, kOcclusionSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(kAlphaSlotId, kAlphaSlotName, kAlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(EmissionSlotId, EmissionSlotName, EmissionSlotName, SlotType.Input, SlotValueType.Vector3, Vector4.zero));
node.AddSlot(new MaterialSlot(MetallicSlotId, MetallicSlotName, MetallicSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(SmoothnessSlotId, SmoothnessSlotName, SmoothnessSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(OcclusionSlotId, OcclusionSlotName, OcclusionSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
node.AddSlot(new MaterialSlot(AlphaSlotId, AlphaSlotName, AlphaSlotName, SlotType.Input, SlotValueType.Vector1, Vector4.zero));
// clear out slot names that do not match the slots
// we support

kAlbedoSlotId,
AlbedoSlotId,
kEmissionSlotId,
kMetallicSlotId,
kSmoothnessSlotId,
kOcclusionSlotId,
kAlphaSlotId
EmissionSlotId,
MetallicSlotId,
SmoothnessSlotId,
OcclusionSlotId,
AlphaSlotId
});
}
}

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


}
}
public string GetSlotValue(MaterialSlot inputSlot, GenerationMode generationMode)
public string GetSlotValue(int inputSlotId, GenerationMode generationMode)
var inputSlot = FindSlot<MaterialSlot>(inputSlotId);
var edges = owner.GetEdges(inputSlot.slotReference).ToArray();
if (edges.Any())

if (slot == null)
return string.Empty;
return ShaderGenerator.AdaptNodeOutput(fromNode, slot, inputSlot.concreteValueType);
return ShaderGenerator.AdaptNodeOutput(fromNode, slot.id, slot.concreteValueType);
}
return inputSlot.GetDefaultValue(generationMode, this);

var pp = new PreviewProperty
{
m_Name = GetVariableNameForSlot(s),
m_Name = GetVariableNameForSlot(s.id),
m_PropType = PropertyType.Vector4,
m_Vector4 = s.currentValue
};

public virtual string GetVariableNameForSlot(MaterialSlot s)
public virtual string GetVariableNameForSlot(int slotId)
if (!GetSlots<MaterialSlot>().Contains(s))
Debug.LogError("Attempting to use MaterialSlot (" + s + ") on a node that does not have this MaterialSlot!");
return GetVariableNameForNode() + "_" + s.id;
var slot = 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");
return GetVariableNameForNode() + "_" + slot.shaderOutputName;
}
public virtual string GetVariableNameForNode()

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


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindOutputSlot<MaterialSlot>(OutputSlotId);
var inputSlot = FindInputSlot<MaterialSlot>(InputSlotId);
if (inputSlot == null || outputSlot == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return;
}
var inputValue = GetSlotValue(inputSlot, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(inputValue) + ";", true);
NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new []{InputSlotId}, new[] {OutputSlotId});
var inputValue = GetSlotValue(InputSlotId, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(OutputSlotId) + " = " + GetFunctionCallBody(inputValue) + ";", true);
}
protected virtual string GetFunctionCallBody(string inputValue)

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


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindOutputSlot<MaterialSlot>(OutputSlotId);
var inputSlot1 = FindInputSlot<MaterialSlot>(InputSlot1Id);
var inputSlot2 = FindInputSlot<MaterialSlot>(InputSlot2Id);
if (inputSlot1 == null || inputSlot2 == null || outputSlot == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return;
}
string input1Value = GetSlotValue(inputSlot1, generationMode);
string input2Value = GetSlotValue(inputSlot2, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(input1Value, input2Value) + ";", true);
NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new[] { InputSlot1Id, InputSlot2Id }, new[] { OutputSlotId });
string input1Value = GetSlotValue(InputSlot1Id, generationMode);
string input2Value = GetSlotValue(InputSlot2Id, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(OutputSlotId) + " = " + GetFunctionCallBody(input1Value, input2Value) + ";", true);
}
protected virtual string GetFunctionCallBody(string input1Value, string input2Value)

20
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Function3Input.cs


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindOutputSlot<MaterialSlot>(OutputSlotId);
var inputSlot1 = FindInputSlot<MaterialSlot>(InputSlot1Id);
var inputSlot2 = FindInputSlot<MaterialSlot>(InputSlot2Id);
var inputSlot3 = FindInputSlot<MaterialSlot>(InputSlot3Id);
if (inputSlot1 == null || inputSlot2 == null || inputSlot3 == null || outputSlot == null)
{
Debug.LogError("Invalid slot configuration on node: " + name);
return;
}
string input1Value = GetSlotValue(inputSlot1, generationMode);
string input2Value = GetSlotValue(inputSlot2, generationMode);
string input3Value = GetSlotValue(inputSlot3, generationMode);
NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new[] { InputSlot1Id, InputSlot2Id, InputSlot3Id }, new[] { OutputSlotId });
string input1Value = GetSlotValue(InputSlot1Id, generationMode);
string input2Value = GetSlotValue(InputSlot2Id, generationMode);
string input3Value = GetSlotValue(InputSlot3Id, generationMode);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(outputSlot) + " = " + GetFunctionCallBody(input1Value, input2Value, input3Value) + ";", true);
visitor.AddShaderChunk(precision + outputDimension + " " + GetVariableNameForSlot(OutputSlotId) + " = " + GetFunctionCallBody(input1Value, input2Value, input3Value) + ";", true);
}
protected virtual string GetFunctionCallBody(string inputValue1, string inputValue2, string inputValue3)

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


if (!generationMode.IsPreview())
return;
visitor.AddShaderChunk("float" + AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(slotValueType) + " " + owner.GetVariableNameForSlot(this) + ";", true);
visitor.AddShaderChunk("float" + AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(slotValueType) + " " + owner.GetVariableNameForSlot(id) + ";", true);
return owner.GetVariableNameForSlot(this);
return owner.GetVariableNameForSlot(id);
switch (concreteValueType)
{

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


get { return PreviewMode.Preview3D; }
}
public override string GetVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(int slotId)
{
return "o.Normal";
}

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


if (fromNode == null)
continue;
var fromSlot = fromNode.FindOutputSlot<MaterialSlot>(outputRef.slotId) as MaterialSlot;
if (fromSlot == null)
continue;
shaderBody.AddShaderChunk("o." + firstPassSlot.shaderOutputName + " = " + fromNode.GetVariableNameForSlot(fromSlot) + ";", true);
shaderBody.AddShaderChunk("o." + firstPassSlot.shaderOutputName + " = " + fromNode.GetVariableNameForSlot(outputRef.slotId) + ";", true);
}
// track the last index of nodes... they have already been processed :)

var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
if (fromNode == null)
continue;
var fromSlot = fromNode.FindOutputSlot<MaterialSlot>(outputRef.slotId) as MaterialSlot;
if (fromSlot == null)
continue;
shaderBody.AddShaderChunk("o." + slot.shaderOutputName + " = " + fromNode.GetVariableNameForSlot(fromSlot) + ";", true);
shaderBody.AddShaderChunk("o." + slot.shaderOutputName + " = " + fromNode.GetVariableNameForSlot(outputRef.slotId) + ";", true);
public override string GetVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(int slotId)
{
return GetVariableNameForNode();
}

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


public abstract PreviewProperty GetPreviewProperty();
public override string GetVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(int slotId)
{
return propertyName;
}

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


RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(MaterialSlot slot)
public override string GetVariableNameForSlot(int slotId)
{
return "IN.screenPos";
}

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


get { return true; }
}
public override string GetVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(int slotIds)
{
return "_SinTime";
}

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


protected const string kOutputSlotBName = "B";
protected const string kOutputSlotAName = "A";
protected const int kUVSlotId = 0;
protected const int kOutputSlotRGBAId = 1;
protected const int kOutputSlotRId =2;
protected const int kOutputSlotGId =3;
protected const int kOutputSlotBId = 4;
protected const int kOutputSlotAId = 5;
public const int UvSlotId = 0;
public const int OutputSlotRgbaId = 1;
public const int OutputSlotRId =2;
public const int OutputSlotGId =3;
public const int OutputSlotBId = 4;
public const int OutputSlotAId = 5;
[SerializeField]
private string m_TextureGuid;

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(kOutputSlotRGBAId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotRgbaId, kOutputSlotRGBAName, kOutputSlotRGBAName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotRId, kOutputSlotRName, kOutputSlotRName, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(kUVSlotId, kUVSlotName, kUVSlotName, SlotType.Input, SlotValueType.Vector2, Vector4.zero));
AddSlot(new MaterialSlot(UvSlotId, kUVSlotName, kUVSlotName, SlotType.Input, SlotValueType.Vector2, Vector4.zero));
get { return new[] {kOutputSlotRGBAId, kOutputSlotRId, kOutputSlotGId, kOutputSlotBId, kOutputSlotAId, kUVSlotId}; }
get { return new[] {OutputSlotRgbaId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId, UvSlotId}; }
var uvSlot = FindInputSlot<MaterialSlot>(kUVSlotId);
var uvSlot = FindInputSlot<MaterialSlot>(UvSlotId);
if (uvSlot == null)
return;

{
var edge = edges[0];
var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(edge.outputSlot.nodeGuid);
var slot = fromNode.FindOutputSlot<MaterialSlot>(edge.outputSlot.slotId);
uvName = ShaderGenerator.AdaptNodeOutput(fromNode, slot, ConcreteSlotValueType.Vector2, true);
uvName = ShaderGenerator.AdaptNodeOutput(fromNode, edge.outputSlot.slotId, ConcreteSlotValueType.Vector2, true);
}

visitor.AddShaderChunk("float4 " + GetVariableNameForNode() + " = " + body + ";", true);
}
public override string GetVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(int slotId)
switch (s.id)
switch (slotId)
case kOutputSlotRId:
case OutputSlotRId:
case kOutputSlotGId:
case OutputSlotGId:
case kOutputSlotBId:
case OutputSlotBId:
case kOutputSlotAId:
case OutputSlotAId:
slotOutput = ".a";
break;
default:

public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
var uvSlot = FindInputSlot<MaterialSlot>(kUVSlotId);
var uvSlot = FindInputSlot<MaterialSlot>(UvSlotId);
if (uvSlot == null)
return;

public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode)
{
var uvSlot = FindInputSlot<MaterialSlot>(kUVSlotId);
var uvSlot = FindInputSlot<MaterialSlot>(UvSlotId);
if (uvSlot == null)
return;

34
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/TimeNode.cs


private const string kOutputSlotNameZ = "Time.z";
private const string kOutputSlotNameW = "Time.w";
private const int kOutputSlotId = 0;
private const int kOutputSlotIdX = 1;
private const int kOutputSlotIdY = 2;
private const int kOutputSlotIdZ = 3;
private const int kOutputSlotIdW = 4;
public const int OutputSlotId = 0;
public const int OutputSlotIdX = 1;
public const int OutputSlotIdY = 2;
public const int OutputSlotIdZ = 3;
public const int OutputSlotIdW = 4;
public TimeNode()
{

public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(kOutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotIdX, kOutputSlotNameX, kOutputSlotNameX, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotIdY, kOutputSlotNameY, kOutputSlotNameY, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotIdZ, kOutputSlotNameZ, kOutputSlotNameZ, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(kOutputSlotIdW, kOutputSlotNameW, kOutputSlotNameW, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotIdX, kOutputSlotNameX, kOutputSlotNameX, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotIdY, kOutputSlotNameY, kOutputSlotNameY, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotIdZ, kOutputSlotNameZ, kOutputSlotNameZ, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
AddSlot(new MaterialSlot(OutputSlotIdW, kOutputSlotNameW, kOutputSlotNameW, SlotType.Output, SlotValueType.Vector1, Vector4.zero));
get { return new[] {kOutputSlotId, kOutputSlotIdX, kOutputSlotIdY, kOutputSlotIdZ, kOutputSlotId}; }
get { return new[] {OutputSlotId, OutputSlotIdX, OutputSlotIdY, OutputSlotIdZ, OutputSlotId}; }
public override string GetVariableNameForSlot(MaterialSlot s)
public override string GetVariableNameForSlot(int slotId)
switch (s.id)
switch (slotId)
case kOutputSlotIdX:
case OutputSlotIdX:
case kOutputSlotIdY:
case OutputSlotIdY:
case kOutputSlotIdZ:
case OutputSlotIdZ:
case kOutputSlotIdW:
case OutputSlotIdW:
return "_Time.w";
default:
return "_Time";

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


[Title("Input/UV Node")]
public class UVNode : AbstractMaterialNode, IGeneratesVertexToFragmentBlock, IGeneratesVertexShaderBlock, IGeneratesBodyCode
{
private const int kOutputSlotId = 0;
public const int OutputSlotId = 0;
private const string kOutputSlotName = "UV";
public override bool hasPreview { get { return true; } }

public override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(kOutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
AddSlot(new MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector4, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
public static void StaticGenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode)

public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputSlot = FindOutputSlot<MaterialSlot>(kOutputSlotId);
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(outputSlot) + " = " + uvValue + ";", true);
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(OutputSlotId) + " = " + uvValue + ";", true);
}
}
}

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


RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(MaterialSlot slot)
public override string GetVariableNameForSlot(int slotId)
{
return "IN.viewDir";
}

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


RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(MaterialSlot slot)
public override string GetVariableNameForSlot(int slotId)
{
return "IN.worldPos";
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphInputNode.cs


foreach (var slot in GetOutputSlots<MaterialSlot>())
{
var outDimension = ConvertConcreteSlotValueTypeToString(slot.concreteValueType);
visitor.AddShaderChunk("float" + outDimension + " " + GetVariableNameForSlot(slot) + ";", true);
visitor.AddShaderChunk("float" + outDimension + " " + GetVariableNameForSlot(slot.id) + ";", true);
}
}

properties.Add(
new PreviewProperty
{
m_Name = GetVariableNameForSlot(slot),
m_Name = GetVariableNameForSlot(slot.id),
m_PropType = PropertyType.Vector4,
m_Vector4 = slot.defaultValue
}

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


"float"
+ outDimension
+ " "
+ GetVariableNameForSlot(slot)
+ GetVariableNameForSlot(slot.id)
+ " = 0;", false);
}

foreach (var slot in GetInputSlots<MaterialSlot>())
{
var varName = subGraphInputNode.GetVariableNameForSlot(subGraphInputNode.FindOutputSlot<MaterialSlot>(slot.id));
var varValue = GetSlotValue(slot, GenerationMode.SurfaceShader);
var varName = subGraphInputNode.GetVariableNameForSlot(slot.id);
var varValue = GetSlotValue(slot.id, GenerationMode.SurfaceShader);
var outDimension = ConvertConcreteSlotValueTypeToString(slot.concreteValueType);
outputString.AddShaderChunk(

// Copy the outputs to the parent context name);
foreach (var slot in GetOutputSlots<MaterialSlot>())
{
var inputSlot = subGraphOutputNode.FindInputSlot<MaterialSlot>(slot.id);
var inputValue = subGraphOutputNode.GetSlotValue(inputSlot, GenerationMode.SurfaceShader);
var inputValue = subGraphOutputNode.GetSlotValue(slot.id, GenerationMode.SurfaceShader);
GetVariableNameForSlot(slot)
GetVariableNameForSlot(slot.id)
+ " = "
+ inputValue
+ ";", false);

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


}
private const string kErrorString = @"ERROR!";
public static string AdaptNodeOutput(AbstractMaterialNode node, MaterialSlot outputSlot, ConcreteSlotValueType convertToType, bool textureSampleUVHack = false)
public static string AdaptNodeOutput(AbstractMaterialNode node, int outputSlotId, ConcreteSlotValueType convertToType, bool textureSampleUVHack = false)
var outputSlot = node.FindOutputSlot<MaterialSlot>(outputSlotId);
var rawOutput = node.GetVariableNameForSlot(outputSlot);
var rawOutput = node.GetVariableNameForSlot(outputSlotId);
if (convertFromType == convertToType)
return rawOutput;

}
}
private static string AdaptNodeOutputForPreview(AbstractMaterialNode node, MaterialSlot outputSlot, ConcreteSlotValueType convertToType)
private static string AdaptNodeOutputForPreview(AbstractMaterialNode node, int outputSlotId, ConcreteSlotValueType convertToType)
if (outputSlot == null)
var outputSlot = node.FindOutputSlot<MaterialSlot>(outputSlotId);
if (outputSlot == null)
return AdaptNodeOutput(node, outputSlot, convertToType);
return AdaptNodeOutput(node, outputSlotId, convertToType);
var rawOutput = node.GetVariableNameForSlot(outputSlot);
var rawOutput = node.GetVariableNameForSlot(outputSlotId);
// otherwise we need to pad output for the preview!
switch (convertToType)

var shaderPropertyUsagesVisitor = new ShaderGenerator();
var vertexShaderBlock = new ShaderGenerator();
var shaderName = "Hidden/PreviewShader/" + node.GetVariableNameForSlot(node.GetOutputSlots<MaterialSlot>().First());
var shaderName = "Hidden/PreviewShader/" + node.GetVariableNameForSlot(node.GetOutputSlots<MaterialSlot>().First().id);
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
{

}
if (generationMode == GenerationMode.Preview2D)
shaderBodyVisitor.AddShaderChunk("return " + AdaptNodeOutputForPreview(node, node.GetOutputSlots<MaterialSlot>().First(), ConcreteSlotValueType.Vector4) + ";", true);
shaderBodyVisitor.AddShaderChunk("return " + AdaptNodeOutputForPreview(node, node.GetOutputSlots<MaterialSlot>().First().id, ConcreteSlotValueType.Vector4) + ";", true);
shaderBodyVisitor.AddShaderChunk("o.Emission = " + AdaptNodeOutputForPreview(node, node.GetOutputSlots<MaterialSlot>().First(), ConcreteSlotValueType.Vector3) + ";", true);
shaderBodyVisitor.AddShaderChunk("o.Emission = " + AdaptNodeOutputForPreview(node, node.GetOutputSlots<MaterialSlot>().First().id, ConcreteSlotValueType.Vector3) + ";", true);
template = template.Replace("${ShaderName}", shaderName);
template = template.Replace("${ShaderPropertiesHeader}", shaderPropertiesVisitor.GetShaderString(2));

正在加载...
取消
保存