浏览代码

Merge pull request #145 from Unity-Technologies/FixingSubGraphs

Fixing sub graphs (+ fix 2D/3D preview bug)
/main
GitHub 7 年前
当前提交
455b4075
共有 45 个文件被更改,包括 482 次插入538 次删除
  1. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs
  2. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractShaderProperty.cs
  3. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/BitangentMaterialSlot.cs
  4. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorShaderProperty.cs
  5. 9
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapShaderProperty.cs
  6. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/FloatShaderProperty.cs
  7. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IShaderProperty.cs
  8. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs
  9. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/NormalMaterialSlot.cs
  10. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/PositionMaterialSlot.cs
  11. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs
  12. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ScreenPositionMaterialSlot.cs
  13. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TangentMaterialSlot.cs
  14. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureShaderProperty.cs
  15. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/UVMaterialSlot.cs
  16. 6
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2ShaderProperty.cs
  17. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3ShaderProperty.cs
  18. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/VectorShaderProperty.cs
  19. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/VertexColorMaterialSlot.cs
  20. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ViewDirectionMaterialSlot.cs
  21. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/HDPipeline/HDUnlitSubShader.cs
  22. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/NeededCoordinateSpace.cs
  23. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightPBRSubShader.cs
  24. 5
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightUnlitSubShader.cs
  25. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/AbstractMaterialNode.cs
  26. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalUnpackNode.cs
  27. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/BitangentVectorNode.cs
  28. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/NormalVectorNode.cs
  29. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/PositionNode.cs
  30. 10
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ScreenPositionNode.cs
  31. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/TangentVectorNode.cs
  32. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/UVNode.cs
  33. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/VertexColorNode.cs
  34. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ViewDirectionNode.cs
  35. 341
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Utility/SubGraphNode.cs
  36. 103
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/SubGraph.cs
  37. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/SubGraphOutputNode.cs
  38. 34
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/GraphUtil.cs
  39. 16
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/ShaderGenerator.cs
  40. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs
  41. 27
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs
  42. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraph.cs.meta
  43. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraphNode.cs.meta
  44. 65
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraph.cs
  45. 250
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraphNode.cs

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs


using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor.Compilation;
using UnityEditor.Graphing.Util;
namespace UnityEditor.ShaderGraph
{

public IEnumerable<Guid> removedProperties
{
get { return m_RemovedProperties; }
}
[SerializeField]
SerializableGuid m_GUID = new SerializableGuid();
public Guid guid
{
get { return m_GUID.guid; }
}
#endregion

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractShaderProperty.cs


public abstract Vector4 defaultValue { get; }
public abstract string GetPropertyBlockString();
public abstract string GetPropertyDeclarationString();
public abstract string GetPropertyDeclarationString(string delimiter = ";");
public virtual string GetInlinePropertyDeclarationString()
public virtual string GetPropertyAsArgumentString()
return GetPropertyDeclarationString();
return GetPropertyDeclarationString(string.Empty);
}
public abstract PreviewProperty GetPreviewMaterialProperty();

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/BitangentMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.BiTangent);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.BiTangent));
}
public NeededCoordinateSpace RequiresBitangent()

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorShaderProperty.cs


return result.ToString();
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return "float4 " + referenceName + ";";
return string.Format("float4 {0}{1}", referenceName, delimiter);
}
public override PreviewProperty GetPreviewMaterialProperty()

9
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapShaderProperty.cs


result.Append("\", CUBE) = \"\" {}");
return result.ToString();
}
public override string GetPropertyDeclarationString(string delimiter = ";")
{
return string.Format("TEXTURECUBE({0}){1} SAMPLER(sampler{0}){1}", referenceName, delimiter);
}
public override string GetPropertyDeclarationString()
public override string GetPropertyAsArgumentString()
return string.Format("TEXTURECUBE({0});\nSAMPLER(sampler{0});", referenceName);
return string.Format("TEXTURECUBE_ARGS({0}, sampler{0})", referenceName);
}
public override PreviewProperty GetPreviewMaterialProperty()

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/FloatShaderProperty.cs


return result.ToString();
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return "float " + referenceName + ";";
return string.Format("float {0}{1}", referenceName, delimiter);
}
public override PreviewProperty GetPreviewMaterialProperty()

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IShaderProperty.cs


string overrideReferenceName { get; set; }
string GetPropertyBlockString();
string GetPropertyDeclarationString();
string GetInlinePropertyDeclarationString();
string GetPropertyDeclarationString(string delimiter = ";");
string GetPropertyAsArgumentString();
PreviewProperty GetPreviewMaterialProperty();
INode ToConcreteNode();
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/MaterialSlot.cs


return inputType == SlotValueType.Cubemap;
case SlotValueType.Dynamic:
case SlotValueType.Vector4:
return inputType == SlotValueType.Vector4
|| inputType == SlotValueType.Vector3
|| inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
return inputType == SlotValueType.Vector3
|| inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
return inputType == SlotValueType.Vector2
|| inputType == SlotValueType.Vector1
|| inputType == SlotValueType.Dynamic;
case SlotValueType.Vector1:
return inputType == SlotValueType.Vector4
|| inputType == SlotValueType.Vector3

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/NormalMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.Normal);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Normal));
}
public NeededCoordinateSpace RequiresNormal()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/PositionMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.Position);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Position));
}
public NeededCoordinateSpace RequiresPosition()

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs


return string.Empty;
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return string.Format(@"SAMPLER2D({0});", referenceName);
return string.Format(@"SAMPLER2D({0}){1}", referenceName, delimiter);
}
public override PreviewProperty GetPreviewMaterialProperty()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ScreenPositionMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return ShaderGeneratorNames.ScreenPosition;
return string.Format("IN.{0}", ShaderGeneratorNames.ScreenPosition);
}
public bool RequiresScreenPosition()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TangentMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.Tangent);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Tangent));
}
public NeededCoordinateSpace RequiresTangent()

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureShaderProperty.cs


return result.ToString();
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return string.Format("TEXTURE2D({0});\nSAMPLER(sampler{0});", referenceName);
return string.Format("TEXTURE2D({0}){1} SAMPLER(sampler{0}){1}", referenceName, delimiter);
public override string GetInlinePropertyDeclarationString()
public override string GetPropertyAsArgumentString()
return string.Format("TEXTURE2D({0});", referenceName);
return string.Format("TEXTURE2D_ARGS({0}, sampler{0})", referenceName);
}
public override PreviewProperty GetPreviewMaterialProperty()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/UVMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return string.Format("{0}.xy", channel.GetUVName());
return string.Format("IN.{0}.xy", channel.GetUVName());
}
public bool RequiresMeshUV(UVChannel channel)

6
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2ShaderProperty.cs


{
get { return new Vector4(value.x, value.y, 0, 0); }
}
public override string GetInlinePropertyDeclarationString()
{
return "float2 " + referenceName + ";";
}
public override PreviewProperty GetPreviewMaterialProperty()
{

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3ShaderProperty.cs


{
get { return new Vector4(value.x, value.y, value.z, 0); }
}
public override string GetInlinePropertyDeclarationString()
{
return "float3 " + referenceName + ";";
}
public override PreviewProperty GetPreviewMaterialProperty()
{
return new PreviewProperty(PropertyType.Vector3)

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/VectorShaderProperty.cs


return result.ToString();
}
public override string GetPropertyDeclarationString()
public override string GetPropertyDeclarationString(string delimiter = ";")
return "float4 " + referenceName + ";";
return string.Format("float4 {0}{1}", referenceName, delimiter);
}
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/VertexColorMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return ShaderGeneratorNames.VertexColor;
return string.Format("IN.{0}", ShaderGeneratorNames.VertexColor);
}
public bool RequiresScreenPosition()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ViewDirectionMaterialSlot.cs


public override string GetDefaultValue(GenerationMode generationMode)
{
return space.ToVariableName(InterpolatorType.ViewDirection);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.ViewDirection));
}
public NeededCoordinateSpace RequiresViewDirection()

17
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/HDPipeline/HDUnlitSubShader.cs


var surfaceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
var functionRegistry = new FunctionRegistry(builder);

var requirements = ShaderGraphRequirements.FromNodes(activeNodeList);
/*
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, InterpolatorType.Position, surfaceInputs);*/
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, InterpolatorType.Position, surfaceInputs);
ShaderGenerator defines = new ShaderGenerator();
defines.AddShaderChunk(string.Format("#define SHADERPASS {0}", pass.ShaderPassName), true);

/*if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);*/
if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);
defines.AddShaderChunk("#define ATTRIBUTES_NEED_TEXCOORD" + (int)channel, true);
defines.AddShaderChunk("#define VARYINGS_NEED_TEXCOORD" + (int)channel, true);
defines.AddShaderChunk(string.Format("#define ATTRIBUTES_NEED_TEXCOORD{0}", (int)channel), true);
defines.AddShaderChunk(string.Format("#define VARYINGS_NEED_TEXCOORD{0}", (int)channel), true);
}
surfaceInputs.Deindent();

usedSlots);
var graph = new ShaderGenerator();
graph.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(builder.ToString(), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);
var tagsVisitor = new ShaderGenerator();

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Interfaces/NeededCoordinateSpace.cs


Tangent = 1 << 3
}
public enum CoordinateSpace : int
public enum CoordinateSpace
{
Object,
View,

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightPBRSubShader.cs


usedSlots);
var graph = new ShaderGenerator();
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceVertexShader.GetShaderString(2), false);
graph.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);

5
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightUnlitSubShader.cs


usedSlots);
var graph = new ShaderGenerator();
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
graph.AddShaderChunk(surfaceVertexShader.GetShaderString(2), false);
graph.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/AbstractMaterialNode.cs


{
get { return true; }
}
public virtual bool allowedInRemapGraph
{
get { return true; }
}
public virtual bool allowedInMainGraph
{
get { return true; }

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Normal/NormalUnpackNode.cs


using System.Reflection;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/BitangentVectorNode.cs


public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.BiTangent);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.BiTangent));
}
public NeededCoordinateSpace RequiresBitangent()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/NormalVectorNode.cs


public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.Normal);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Normal));
}
public NeededCoordinateSpace RequiresNormal()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/PositionNode.cs


public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.Position);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Position));
}
public NeededCoordinateSpace RequiresPosition()

10
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ScreenPositionNode.cs


switch (m_ScreenSpaceType)
{
case ScreenSpaceType.Raw:
visitor.AddShaderChunk(string.Format("{0}4 {1} = {2};", precision, GetVariableNameForSlot(kOutputSlotId),
visitor.AddShaderChunk(string.Format("{0}4 {1} = In.{2};", precision, GetVariableNameForSlot(kOutputSlotId),
"float4((" + ShaderGeneratorNames.ScreenPosition + ".xy / " + ShaderGeneratorNames.ScreenPosition + ".w) * 2 - 1, 0, 0)"), true);
string.Format("float4((In.{0}.xy / In.{0}.w) * 2 - 1, 0, 0)", ShaderGeneratorNames.ScreenPosition)), true);
"float4((" + ShaderGeneratorNames.ScreenPosition + ".xy / " + ShaderGeneratorNames.ScreenPosition + ".w) * 2 - 1, 0, 0)"), true);
string.Format("float4((In.{0}.xy / In.{0}.w) * 2 - 1, 0, 0)", ShaderGeneratorNames.ScreenPosition)), true);
"float4(" + ShaderGeneratorNames.ScreenPosition + ".x * _ScreenParams.x / _ScreenParams.y, " + ShaderGeneratorNames.ScreenPosition + ".y, 0, 0)"), true);
string.Format("float4(In.{0}.x * _ScreenParams.x / _ScreenParams.y, In.{0}.y, 0, 0)", ShaderGeneratorNames.ScreenPosition)), true);
"float4(" + ShaderGeneratorNames.ScreenPosition + ".xy / " + ShaderGeneratorNames.ScreenPosition + ".w, 0, 0)"), true);
string.Format("float4(In.{0}.xy / In.{0}.w, 0, 0)", ShaderGeneratorNames.ScreenPosition)), true);
break;
}
}

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/TangentVectorNode.cs


public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.Tangent);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Tangent));
}
public NeededCoordinateSpace RequiresTangent()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/UVNode.cs


public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
visitor.AddShaderChunk(precision + "4 " + GetVariableNameForSlot(OutputSlotId) + " = " + m_OutputChannel.GetUVName() + ";", true);
visitor.AddShaderChunk(string.Format("{0}4 {1} = IN.{2};", precision, GetVariableNameForSlot(OutputSlotId), m_OutputChannel.GetUVName()), true);
}
public bool RequiresMeshUV(UVChannel channel)

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/VertexColorNode.cs


public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.VertexColor;
return string.Format("IN.{0}", ShaderGeneratorNames.VertexColor);
}
public bool RequiresVertexColor()

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Input/Geometry/ViewDirectionNode.cs


public override string GetVariableNameForSlot(int slotId)
{
return space.ToVariableName(InterpolatorType.ViewDirection);
return string.Format("IN.{0}", space.ToVariableName(InterpolatorType.ViewDirection));
}
public NeededCoordinateSpace RequiresViewDirection()

341
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Utility/SubGraphNode.cs


using System;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEditor.Graphs;
public class SubGraphNode : AbstractSubGraphNode
public class SubGraphNode : AbstractMaterialNode
, IGeneratesFunction
, IMayRequireNormal
, IMayRequireTangent
, IMayRequireBitangent
, IMayRequireMeshUV
, IMayRequireScreenPosition
, IMayRequireViewDirection
, IMayRequirePosition
, IMayRequireVertexColor
, IMayRequireTime
{
[SerializeField]
private string m_SerializedSubGraph = string.Empty;

public MaterialSubGraphAsset subGraph;
}
protected override AbstractSubGraph referencedGraph
protected SubGraph referencedGraph
{
get
{

public MaterialSubGraphAsset subGraphAsset {get; set; }
#endif
public override INode outputNode
public INode outputNode
{
get
{

}
}
public override bool hasPreview
{
get { return referencedGraph != null; }
}
public override PreviewMode previewMode
{
get
{
if (referencedGraph == null)
return PreviewMode.Preview2D;
return PreviewMode.Preview3D;
}
}
public void GenerateNodeCode(ShaderGenerator shaderBodyVisitor, GenerationMode generationMode)
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
var outputString = new ShaderGenerator();
outputString.AddShaderChunk("// Subgraph for node " + GetVariableNameForNode(), false);
foreach (var outSlot in referencedGraph.graphOutputs)
visitor.AddShaderChunk(string.Format("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, outSlot.concreteValueType), GetVariableNameForSlot(outSlot.id)), true);
// Step 1...
// find out which output slots are actually used
//var validOutputSlots = NodeUtils.GetSlotsThatOutputToNodeRecurse(this, (graph as BaseMaterialGraph).masterNode);
s_TempSlots.Clear();
GetOutputSlots(s_TempSlots);
foreach (var slot in s_TempSlots)
var arguments = new List<string>();
foreach (var prop in referencedGraph.graphInputs)
var outDimension = NodeUtils.ConvertConcreteSlotValueTypeToString(precision, slot.concreteValueType);
outputString.AddShaderChunk(string.Format("{0} {1} = 0;", outDimension, GetVariableNameForSlot(slot.id)), false);
var inSlotId = prop.guid.GetHashCode();
if (prop is TextureShaderProperty)
arguments.Add(string.Format("TEXTURE2D_PARAM({0}, sampler{0})", GetSlotValue(inSlotId, generationMode)));
else if (prop is CubemapShaderProperty)
arguments.Add(string.Format("TEXTURECUBE_PARAM({0}, sampler{0})", GetSlotValue(inSlotId, generationMode)));
else
arguments.Add(GetSlotValue(inSlotId, generationMode));
// Step 2...
// Go into the subgraph
outputString.AddShaderChunk("{", false);
outputString.Indent();
// pass surface inputs through
arguments.Add("IN");
foreach (var outSlot in referencedGraph.graphOutputs)
arguments.Add(GetVariableNameForSlot(outSlot.id));
// Step 3...
// For each input that is used and connects through we want to generate code.
// First we assign the input variables to the subgraph
// 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 dSubGraph = SerializationHelper.Deserialize<SubGraph>(sSubGraph, null);
visitor.AddShaderChunk(
string.Format("{0}({1});"
, SubGraphFunctionName()
, arguments.Aggregate((current, next) => string.Format("{0}, {1}", current, next)))
, false);
}
var subGraphInputs = dSubGraph.properties;
public void OnEnable()
{
UpdateSlots();
}
var propertyGen = new PropertyCollector();
dSubGraph.CollectShaderProperties(propertyGen, GenerationMode.ForReals);
public virtual void UpdateSlots()
{
var validNames = new List<int>();
if (referencedGraph == null)
{
RemoveSlotsNameNotMatching(validNames);
return;
}
foreach (var prop in subGraphInputs)
var props = referencedGraph.properties;
foreach (var prop in props)
var inSlotId = prop.guid.GetHashCode();
var inSlot = FindInputSlot<MaterialSlot>(inSlotId);
var propType = prop.propertyType;
SlotValueType slotType;
var edges = owner.GetEdges(inSlot.slotReference).ToArray();
switch (propType)
{
case PropertyType.Color:
slotType = SlotValueType.Vector4;
break;
case PropertyType.Texture:
slotType = SlotValueType.Texture2D;
break;
case PropertyType.Cubemap:
slotType = SlotValueType.Cubemap;
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();
}
string varValue = inSlot.GetDefaultValue(generationMode);
if (edges.Any())
var id = prop.guid.GetHashCode();
MaterialSlot slot = MaterialSlot.CreateMaterialSlot(slotType, id, prop.displayName, prop.referenceName, SlotType.Input, prop.defaultValue);
// copy default for texture for niceness
if (slotType == SlotValueType.Texture2D && propType == PropertyType.Texture)
var fromSocketRef = edges[0].outputSlot;
var fromNode = owner.GetNodeFromGuid<AbstractMaterialNode>(fromSocketRef.nodeGuid);
if (fromNode != null)
{
var slot = fromNode.FindOutputSlot<MaterialSlot>(fromSocketRef.slotId);
if (slot != null)
prop.overrideReferenceName = fromNode.GetSlotValue(slot.id, generationMode);
}
var tSlot = slot as Texture2DInputMaterialSlot;
var tProp = prop as TextureShaderProperty;
if (tSlot != null && tProp != null)
tSlot.texture = tProp.value.texture;
else if (inSlot is Texture2DInputMaterialSlot)
// copy default for cubemap for niceness
else if (slotType == SlotValueType.Cubemap && propType == PropertyType.Cubemap)
prop.overrideReferenceName = ((Texture2DInputMaterialSlot)inSlot).GetDefaultValue(generationMode);
var tSlot = slot as CubemapInputMaterialSlot;
var tProp = prop as CubemapShaderProperty;
if (tSlot != null && tProp != null)
tSlot.cubemap = tProp.value.cubemap;
else
AddSlot(slot);
validNames.Add(id);
}
var subGraphOutputNode = outputNode;
if (outputNode != null)
{
foreach (var slot in NodeExtensions.GetInputSlots<MaterialSlot>(subGraphOutputNode))
var varName = prop.referenceName;
outputString.AddShaderChunk(NodeUtils.ConvertConcreteSlotValueTypeToString(precision, inSlot.concreteValueType)
+ " "
+ varName
+ " = "
+ varValue
+ ";", false);
AddSlot(MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(), slot.shaderOutputName, SlotType.Output, Vector4.zero));
validNames.Add(slot.id);
// Step 4...
// Using the inputs we can now generate the shader body :)
var bodyGenerator = new ShaderGenerator();
dSubGraph.GenerateNodeCode(bodyGenerator, GenerationMode.ForReals);
var subGraphOutputNode = dSubGraph.outputNode;
outputString.AddShaderChunk(bodyGenerator.GetShaderString(0), false);
RemoveSlotsNameNotMatching(validNames);
}
// Step 5...
// Copy the outputs to the parent context name);
s_TempSlots.Clear();
GetOutputSlots(s_TempSlots);
foreach (var slot in s_TempSlots)
public override void ValidateNode()
{
if (referencedGraph != null)
var inputValue = subGraphOutputNode.GetSlotValue(slot.id, GenerationMode.ForReals);
referencedGraph.OnEnable();
referencedGraph.ValidateGraph();
outputString.AddShaderChunk(
GetVariableNameForSlot(slot.id)
+ " = "
+ inputValue
+ ";", false);
if (referencedGraph.GetNodes<INode>().Any(x => x.hasError))
hasError = true;
outputString.Deindent();
outputString.AddShaderChunk("}", false);
outputString.AddShaderChunk("// Subgraph ends", false);
base.ValidateNode();
}
public override void CollectShaderProperties(PropertyCollector visitor, GenerationMode generationMode)
{
base.CollectShaderProperties(visitor, generationMode);
if (referencedGraph == null)
return;
shaderBodyVisitor.AddShaderChunk(outputString.GetShaderString(0), true);
referencedGraph.CollectShaderProperties(visitor, GenerationMode.ForReals);
public void OnEnable()
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
UpdateSlots();
base.CollectPreviewMaterialProperties(properties);
if (referencedGraph == null)
return;
properties.AddRange(referencedGraph.GetPreviewProperties());
}
private string SubGraphFunctionName()
{
var functionName = subGraphAsset != null ? NodeUtils.GetHLSLSafeName(subGraphAsset.name) : "ERROR";
return string.Format("{0}_{1}", functionName, GuidEncoder.Encode(referencedGraph.guid));
}
public virtual void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
if (subGraphAsset == null || referencedGraph == null)
return;
referencedGraph.GenerateNodeFunction(registry, GenerationMode.ForReals);
referencedGraph.GenerateSubGraphFunction(SubGraphFunctionName(), registry, ShaderGraphRequirements.FromNodes(new List<INode> {this}), GenerationMode.ForReals);
}
public NeededCoordinateSpace RequiresNormal()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresNormal();
return mask;
});
}
public bool RequiresMeshUV(UVChannel channel)
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel));
}
public bool RequiresScreenPosition()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
}
public NeededCoordinateSpace RequiresViewDirection()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresViewDirection();
return mask;
});
}
public NeededCoordinateSpace RequiresPosition()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresPosition();
return mask;
});
}
public NeededCoordinateSpace RequiresTangent()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresTangent();
return mask;
});
}
public bool RequiresTime()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireTime>().Any(x => x.RequiresTime());
}
public NeededCoordinateSpace RequiresBitangent()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresBitangent();
return mask;
});
}
public bool RequiresVertexColor()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
}
}
}

103
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/SubGraph.cs


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

base.AddNode(node);
}
public override IEnumerable<AbstractMaterialNode> activeNodes
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(FunctionRegistry registry, GenerationMode generationMode)
{
foreach (var node in activeNodes)
{
if (node is IGeneratesFunction)
(node as IGeneratesFunction).GenerateNodeFunction(registry, generationMode);
}
}
public IEnumerable<IShaderProperty> graphInputs
{
get { return properties.OrderBy(x => x.guid); }
}
public IEnumerable<MaterialSlot> graphOutputs
{
get
{
return outputNode != null ? outputNode.graphOutputs : new List<MaterialSlot>();
}
}
public void GenerateSubGraphFunction(string functionName, FunctionRegistry registry, ShaderGraphRequirements reqs, GenerationMode generationMode)
{
registry.ProvideFunction(functionName, s =>
{
s.AppendLine("// Subgraph function");
// Generate arguments... first INPUTS
var arguments = new List<string>();
foreach (var prop in graphInputs)
arguments.Add(string.Format("{0}", prop.GetPropertyAsArgumentString()));
// now pass surface inputs
arguments.Add("SurfaceInputs IN");
// Now generate outputs
foreach (var slot in graphOutputs)
arguments.Add(string.Format("out {0} {1}", slot.concreteValueType.ToString(outputNode.precision), slot.shaderOutputName));
// Create the function protoype from the arguments
s.AppendLine("void {0}({1})"
, functionName
, arguments.Aggregate((current, next) => string.Format("{0}, {1}", current, next)));
// now generate the function
using (s.BlockScope())
{
// Just grab the body from the active nodes
var bodyGenerator = new ShaderGenerator();
GenerateNodeCode(bodyGenerator, GenerationMode.ForReals);
if (outputNode != null)
outputNode.RemapOutputs(bodyGenerator, GenerationMode.ForReals);
s.Append(bodyGenerator.GetShaderString(1));
}
});
}
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;
}
public IEnumerable<AbstractMaterialNode> activeNodes
{
get
{

17
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/SubGraphOutputNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor.ShaderGraph.Drawing.Controls;

RemoveSlot(index);
}
public override bool allowedInRemapGraph { get { return false; } }
public void RemapOutputs(ShaderGenerator visitor, GenerationMode generationMode)
{
foreach (var slot in graphOutputs)
visitor.AddShaderChunk(string.Format("{0} = {1};", slot.shaderOutputName, GetSlotValue(slot.id, generationMode)), true);
}
public IEnumerable<MaterialSlot> graphOutputs
{
get
{
return NodeExtensions.GetInputSlots<MaterialSlot>(this).OrderBy(x=>x.id);
}
}
}
}

34
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/GraphUtil.cs


finalBuilder.AppendLine(@"#include ""ShaderGraphLibrary/ShaderVariables.hlsl""");
finalBuilder.AppendLine(@"#include ""ShaderGraphLibrary/ShaderVariablesFunctions.hlsl""");
finalBuilder.AppendLines(shaderProperties.GetPropertiesDeclaration(0));
finalBuilder.AppendLines(surfaceInputs.GetShaderString(0));
finalBuilder.AppendLines(surfaceInputs.GetShaderString(0));
finalBuilder.AppendLines(shaderProperties.GetPropertiesDeclaration(0));
finalBuilder.AppendLines(vertexShader.GetShaderString(0));
finalBuilder.AppendLines(surfaceDescriptionFunction.GetShaderString(0));
finalBuilder.AppendLine(@"ENDHLSL");

surfaceDescriptionFunction.Indent();
surfaceDescriptionFunction.AddShaderChunk(String.Format("{0} surface = ({0})0;", surfaceDescriptionName), false);
foreach (CoordinateSpace space in Enum.GetValues(typeof(CoordinateSpace)))
{
var neededCoordinateSpace = space.ToNeededCoordinateSpace();
if ((requirements.requiresNormal & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(String.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Normal)), false);
if ((requirements.requiresTangent & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(String.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Tangent)), false);
if ((requirements.requiresBitangent & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(String.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.BiTangent)), false);
if ((requirements.requiresViewDir & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(String.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.ViewDirection)), false);
if ((requirements.requiresPosition & neededCoordinateSpace) > 0)
surfaceDescriptionFunction.AddShaderChunk(String.Format("float3 {0} = IN.{0};", space.ToVariableName(InterpolatorType.Position)), false);
}
if (requirements.requiresScreenPosition)
surfaceDescriptionFunction.AddShaderChunk(String.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
if (requirements.requiresVertexColor)
surfaceDescriptionFunction.AddShaderChunk(String.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceDescriptionFunction.AddShaderChunk(String.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
graph.CollectShaderProperties(shaderProperties, mode);
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())

{
var outputRef = foundEdges[0].outputSlot;
var fromNode = graph.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
surfaceDescriptionFunction.AddShaderChunk(String.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
surfaceDescriptionFunction.AddShaderChunk(String.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode)), true);
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode)), true);
}
}
}

surfaceDescriptionFunction.AddShaderChunk(String.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(slot.shaderOutputName), masterNode.GetVariableNameForSlot(slot.id)), true);
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(slot.shaderOutputName), masterNode.GetVariableNameForSlot(slot.id)), true);
}
}

16
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/ShaderGenerator.cs


switch (convertFromType)
{
case ConcreteSlotValueType.Vector1:
return string.Format("({0}{1})", rawOutput, ".xx");
return string.Format("({0}.xx)", rawOutput);
case ConcreteSlotValueType.Vector3:
case ConcreteSlotValueType.Vector4:
return string.Format("({0}.xy)", rawOutput);

switch (convertFromType)
{
case ConcreteSlotValueType.Vector1:
return string.Format("({0}{1})", rawOutput, ".xxx");
return string.Format("({0}.xxx)", rawOutput);
case ConcreteSlotValueType.Vector2:
return string.Format("({0}3({1}.x, {1}.y, 0.0))", node.precision, rawOutput);
case ConcreteSlotValueType.Vector4:
return string.Format("({0}.xyz)", rawOutput);
default:

switch (convertFromType)
{
case ConcreteSlotValueType.Vector1:
return string.Format("({0}{1})", rawOutput, ".xxxx");
return string.Format("({0}.xxxx)", rawOutput);
case ConcreteSlotValueType.Vector2:
return string.Format("({0}4({1}.x, {1}.y, 0.0, 1.0))", node.precision, rawOutput);
case ConcreteSlotValueType.Vector3:
return string.Format("({0}4({1}.x, {1}.y, {1}.z, 1.0))", node.precision, rawOutput);
default:
return kErrorString;
}

var convertFromType = slot.concreteValueType;
// preview is always dimension 4, and we always ignore alpha
// preview is always dimension 4
switch (convertFromType)
{
case ConcreteSlotValueType.Vector1:

{
interpolators.AddShaderChunk(string.Format("half4 {0} : TEXCOORD{1};", channel.GetUVName(), interpolatorIndex == 0 ? "" : interpolatorIndex.ToString()), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.texcoord{1};", channel.GetUVName(), (int)channel), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", channel.GetUVName()), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", channel.GetUVName()), false);
interpolatorIndex++;
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/MaterialGraphEditWindow.cs


graphObject.graph.ValidateGraph();
}
void UpdateAbstractSubgraphOnDisk<T>(string path) where T : AbstractSubGraph
void UpdateAbstractSubgraphOnDisk<T>(string path) where T : SubGraph
{
var graph = graphObject.graph as T;
if (graph == null)

{
if (graphObject != null && graphObject.graph != null)
{
var subNodes = graphObject.graph.GetNodes<AbstractSubGraphNode>();
var subNodes = graphObject.graph.GetNodes<SubGraphNode>();
foreach (var node in subNodes)
node.UpdateSlots();
}

27
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/PreviewManager.cs


m_DirtyPreviews.UnionWith(m_TimeDependentPreviews);
PropagateNodeSet(m_DirtyPreviews);
m_NodesWith3DPreview.Clear();
foreach (var index in m_DirtyPreviews)
{
var node = (AbstractMaterialNode)m_Graph.GetNodeFromTempId(m_Identifiers[index]);
if (node.previewMode == PreviewMode.Preview3D)
m_NodesWith3DPreview.Add(node.tempId.index);
}
PropagateNodeSet(m_NodesWith3DPreview);
foreach (var index in m_DirtyPreviews)
{
var renderData = m_RenderDatas[index];
renderData.previewMode = m_NodesWith3DPreview.Contains(renderData.shaderData.node.tempId.index) ? PreviewMode.Preview3D : PreviewMode.Preview2D;
}
// Find nodes we need properties from
m_PropertyNodes.Clear();
m_PropertyNodes.UnionWith(m_DirtyPreviews);

if (m_DirtyShaders.Any())
{
PropagateNodeSet(m_DirtyShaders);
m_NodesWith3DPreview.Clear();
foreach (var index in m_DirtyShaders)
{
var node = (AbstractMaterialNode)m_Graph.GetNodeFromTempId(m_Identifiers[index]);
if (node.previewMode == PreviewMode.Preview3D)
m_NodesWith3DPreview.Add(node.tempId.index);
}
PropagateNodeSet(m_NodesWith3DPreview);
foreach (var index in m_DirtyShaders)
{
var renderData = m_RenderDatas[index];
renderData.previewMode = m_NodesWith3DPreview.Contains(renderData.shaderData.node.tempId.index) ? PreviewMode.Preview3D : PreviewMode.Preview2D;
}
var masterNodes = new List<MasterNode>();
var uberNodes = new List<INode>();

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraph.cs.meta


fileFormatVersion: 2
guid: f2b67435729448498da7e7b90f052ebd
timeCreated: 1506844687

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraphNode.cs.meta


fileFormatVersion: 2
guid: bc4cf774a7a6480ba543eb6069cd1c50
timeCreated: 1506847426

65
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraph.cs


using System;
using System.Collections.Generic;
using System.Linq;
namespace UnityEditor.ShaderGraph
{
[Serializable]
public class AbstractSubGraph : AbstractMaterialGraph
, IGeneratesBodyCode
, IGeneratesFunction
{
public virtual IEnumerable<AbstractMaterialNode> activeNodes { get { return Enumerable.Empty<AbstractMaterialNode>(); } }
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(FunctionRegistry registry, GenerationMode generationMode)
{
foreach (var node in activeNodes)
{
if (node is IGeneratesFunction)
(node as IGeneratesFunction).GenerateNodeFunction(registry, 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;
}
}
}

250
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/AbstractSubGraphNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{
public abstract class AbstractSubGraphNode : AbstractMaterialNode
, IGeneratesFunction
, IMayRequireNormal
, IMayRequireTangent
, IMayRequireBitangent
, IMayRequireMeshUV
, IMayRequireScreenPosition
, IMayRequireViewDirection
, IMayRequirePosition
, IMayRequireVertexColor
, IMayRequireTime
{
protected abstract AbstractSubGraph referencedGraph { get; }
public override bool hasPreview
{
get { return referencedGraph != null; }
}
public override PreviewMode previewMode
{
get
{
if (referencedGraph == null)
return PreviewMode.Preview2D;
return PreviewMode.Preview3D;
}
}
public virtual INode outputNode
{
get { return null; }
}
public virtual void UpdateSlots()
{
var validNames = new List<int>();
if (referencedGraph == null)
{
RemoveSlotsNameNotMatching(validNames);
return;
}
var props = referencedGraph.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.Cubemap:
slotType = SlotValueType.Cubemap;
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();
MaterialSlot slot = MaterialSlot.CreateMaterialSlot(slotType, id, prop.displayName, prop.referenceName, SlotType.Input, prop.defaultValue);
// copy default for texture for niceness
if (slotType == SlotValueType.Texture2D && propType == PropertyType.Texture)
{
var tSlot = slot as Texture2DInputMaterialSlot;
var tProp = prop as TextureShaderProperty;
if (tSlot != null && tProp != null)
tSlot.texture = tProp.value.texture;
}
// copy default for cubemap for niceness
else if (slotType == SlotValueType.Cubemap && propType == PropertyType.Cubemap)
{
var tSlot = slot as CubemapInputMaterialSlot;
var tProp = prop as CubemapShaderProperty;
if (tSlot != null && tProp != null)
tSlot.cubemap = tProp.value.cubemap;
}
AddSlot(slot);
validNames.Add(id);
}
var subGraphOutputNode = outputNode;
if (outputNode != null)
{
foreach (var slot in subGraphOutputNode.GetInputSlots<MaterialSlot>())
{
AddSlot(MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(), slot.shaderOutputName, SlotType.Output, Vector4.zero));
validNames.Add(slot.id);
}
}
RemoveSlotsNameNotMatching(validNames);
}
public override void CollectShaderProperties(PropertyCollector visitor, GenerationMode generationMode)
{
base.CollectShaderProperties(visitor, generationMode);
if (referencedGraph == null)
return;
referencedGraph.CollectShaderProperties(visitor, GenerationMode.ForReals);
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
if (referencedGraph == null)
return;
properties.AddRange(referencedGraph.GetPreviewProperties());
}
public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
{
if (referencedGraph == null)
return;
referencedGraph.GenerateNodeFunction(registry, GenerationMode.ForReals);
}
public NeededCoordinateSpace RequiresNormal()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresNormal();
return mask;
});
}
public bool RequiresMeshUV(UVChannel channel)
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel));
}
public bool RequiresScreenPosition()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
}
public NeededCoordinateSpace RequiresViewDirection()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresViewDirection();
return mask;
});
}
public NeededCoordinateSpace RequiresPosition()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresPosition();
return mask;
});
}
public NeededCoordinateSpace RequiresTangent()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresTangent();
return mask;
});
}
public bool RequiresTime()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireTime>().Any(x => x.RequiresTime());
}
public NeededCoordinateSpace RequiresBitangent()
{
if (referencedGraph == null)
return NeededCoordinateSpace.None;
return referencedGraph.activeNodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresBitangent();
return mask;
});
}
public bool RequiresVertexColor()
{
if (referencedGraph == null)
return false;
return referencedGraph.activeNodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
}
}
}
正在加载...
取消
保存