浏览代码

First pass working layered graph :)

/main
Tim Cooper 7 年前
当前提交
4e26b4fc
共有 10 个文件被更改,包括 153 次插入67 次删除
  1. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs
  2. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/ShaderLayerview.cs
  3. 54
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs
  4. 34
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractShaderProperty.cs
  5. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/IShaderGraph.cs
  6. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/MaterialGraphChange.cs
  7. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/LayerWeightsOutputNode.cs
  8. 72
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/LayeredShaderGraph.cs
  9. 37
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/SerializableGuid.cs
  10. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/SerializableGuid.cs.meta

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/GraphInspectorView.cs


var layerRemoved = change as LayerRemoved;
if (layerRemoved != null)
{
var view = m_LayerItems.OfType<ShaderLayerView>().FirstOrDefault(v => v.layer.layer == layerRemoved.id);
var view = m_LayerItems.OfType<ShaderLayerView>().FirstOrDefault(v => v.layer.guid == layerRemoved.id);
if (view != null)
m_LayerItems.Remove(view);
}

8
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/ShaderLayerview.cs


{
public class ShaderLayerView : VisualElement
{
public LayeredShaderGraph graph { get; private set; }
public LayeredShaderGraph.Layer layer { get; private set; }
public LayeredShaderGraph graph { get; }
public LayeredShaderGraph.Layer layer { get; }
public ShaderLayerView(LayeredShaderGraph graph, LayeredShaderGraph.Layer layer)
{

void OnClickRemove()
{
graph.RemoveLayer(layer.layer);
graph.RemoveLayer(layer.guid);
NotifyNodes();
}

var newShader = EditorGUILayout.ObjectField("Shader", layer.shader, typeof(Shader), false) as Shader;
if (newShader != layer.shader)
{
if (graph.SetLayer(layer.layer, newShader))
if (graph.SetLayer(layer.guid, newShader))
NotifyNodes();
}
}

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


return GetShader(node, GenerationMode.Preview, string.Format("hidden/preview/{0}", node.GetVariableNameForNode()), out configuredTextures, out previewMode);
}
protected void GenerateSurfaceDescriptionStruct(ShaderGenerator surfaceDescriptionStruct, AbstractMaterialNode node, bool isMasterNode)
protected static void GenerateSurfaceDescriptionStruct(ShaderGenerator surfaceDescriptionStruct, AbstractMaterialNode node, bool isMasterNode)
{
surfaceDescriptionStruct.AddShaderChunk("struct SurfaceDescription{", false);
surfaceDescriptionStruct.Indent();

surfaceDescriptionStruct.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + slot.shaderOutputName + ";", false);
surfaceDescriptionStruct.AddShaderChunk(string.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), slot.shaderOutputName), false);
}
else
{
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
surfaceDescriptionStruct.AddShaderChunk(string.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), node.GetVariableNameForSlot(slot.id)), false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
surfaceDescriptionStruct.AddShaderChunk("void ScaleSurfaceDescription(inout SurfaceDescription surface, float scale){", false);
surfaceDescriptionStruct.Indent();
if (isMasterNode)
{
foreach (var slot in node.GetInputSlots<MaterialSlot>())
surfaceDescriptionStruct.AddShaderChunk( string.Format("surface.{0} = scale * surface.{0};", slot.shaderOutputName), false);
surfaceDescriptionStruct.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + node.GetVariableNameForSlot(slot.id) + ";", false);
surfaceDescriptionStruct.AddShaderChunk(string.Format("surface.{0} = scale * surface.{0};", node.GetVariableNameForSlot(slot.id)), false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
surfaceDescriptionStruct.AddShaderChunk("void AddSurfaceDescription(inout SurfaceDescription base, in SurfaceDescription add){", false);
surfaceDescriptionStruct.Indent();
if (isMasterNode)
{
foreach (var slot in node.GetInputSlots<MaterialSlot>())
{
var str = string.Format("base.{0} = base.{0} + add.{0};", slot.shaderOutputName);
surfaceDescriptionStruct.AddShaderChunk(str, false);
}
}
else
{
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
{
var str = string.Format("base.{0} = base.{0} + add.{0};", node.GetVariableNameForSlot(slot.id));
surfaceDescriptionStruct.AddShaderChunk(str, false);
}
protected void GenerateSurfaceDescription(
protected static void GenerateSurfaceDescription(
AbstractMaterialNode node,
ShaderGenerator surfaceDescriptionFunction,
ShaderGenerator shaderFunctionVisitor,

string functionName = "PopulateSurfaceData",
string surfaceDescriptionName = "SurfaceDescription")
{
var graph = node.owner as AbstractMaterialGraph;
if (graph == null)
return;
surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} {1}(SurfaceInputs IN) {{", surfaceDescriptionName, functionName), false);
surfaceDescriptionFunction.Indent();

foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceDescriptionFunction.AddShaderChunk(string.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
CollectShaderProperties(shaderProperties, mode);
graph.CollectShaderProperties(shaderProperties, mode);
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);

{
foreach (var input in node.GetInputSlots<MaterialSlot>())
{
var foundEdges = GetEdges(input.slotReference).ToArray();
var foundEdges = graph.GetEdges(input.slotReference).ToArray();
var fromNode = GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
var fromNode = graph.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid);
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", input.shaderOutputName, fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
}
else

34
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractShaderProperty.cs


namespace UnityEngine.MaterialGraph
{
[Serializable]
public abstract class AbstractShaderProperty<T> : ISerializationCallbackReceiver, IShaderProperty
public abstract class AbstractShaderProperty<T> : IShaderProperty
[SerializeField]
private string m_Description;
[NonSerialized]
private Guid m_Guid;
private string m_GuidSerialized;
private bool m_GeneratePropertyBlock = true;
private bool m_GeneratePropertyBlock = true;
protected AbstractShaderProperty()
{
m_Guid = Guid.NewGuid();
}
private SerializableGuid m_Guid = new SerializableGuid();
public T value
{

get
{
if (string.IsNullOrEmpty(m_Name))
return m_Guid.ToString();
return guid.ToString();
return m_Name;
}
set { m_Name = value; }

public Guid guid
{
get { return m_Guid; }
get { return m_Guid.guid; }
}
public bool generatePropertyBlock

}
public abstract PreviewProperty GetPreviewMaterialProperty();
public virtual void OnBeforeSerialize()
{
m_GuidSerialized = m_Guid.ToString();
}
public virtual void OnAfterDeserialize()
{
if (!string.IsNullOrEmpty(m_GuidSerialized))
m_Guid = new Guid(m_GuidSerialized);
else
m_Guid = Guid.NewGuid();
}
}
}

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


{
string GetShader(string name, GenerationMode mode, out List<PropertyCollector.TextureInfo> configuredTextures);
}
}
}

4
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/MaterialGraphChange.cs


public class LayerRemoved : GraphChange
{
public LayerRemoved(int id)
public LayerRemoved(Guid id)
public int id { get; private set; }
public Guid id { get; private set; }
}
}

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


var goodSlots = new List<int>();
foreach (var layer in layeredGraph.layers)
{
AddSlot(new MaterialSlot(layer.layer, "" + layer.layer, "" + layer.layer, SlotType.Input, SlotValueType.Vector1, new Vector4(0, 0, 0, 0)));
goodSlots.Add(layer.layer);
AddSlot(new MaterialSlot(layer.guid.GetHashCode(), LayeredShaderGraph.LayerToFunctionName(layer.guid), LayeredShaderGraph.LayerToFunctionName(layer.guid), SlotType.Input, SlotValueType.Vector1, new Vector4(0, 0, 0, 0)));
goodSlots.Add(layer.guid.GetHashCode());
}
RemoveSlotsNameNotMatching(goodSlots);

72
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/LayeredShaderGraph.cs


public class Layer
{
[SerializeField]
private int m_Layer;
private SerializableGuid m_Guid = new SerializableGuid();
{
m_Layer = Guid.NewGuid().GetHashCode();
}
{}
public int layer
public Guid guid
get { return m_Layer; }
get { return m_Guid.guid; }
}
public Shader shader

outputNode.onModified(outputNode, ModificationScope.Graph);
}
public bool SetLayer(int layerId, Shader newShader)
public bool SetLayer(Guid layerId, Shader newShader)
{
try
{

if (graph == null)
return false;
var layer = layers.FirstOrDefault(x => x.layer == layerId);
var layer = layers.FirstOrDefault(x => x.guid == layerId);
if (layer == null)
return false;

return false;
}
public void RemoveLayer(int id)
public void RemoveLayer(Guid id)
var num = m_Layers.RemoveAll(x => x.layer == id);
var num = m_Layers.RemoveAll(x => x.guid == id);
if (num > 0)
{

base.OnAfterDeserialize();
}
public static string LayerToFunctionName(Guid id)
{
return string.Format("Layer_{0}", GuidEncoder.Encode(id));
}
var layerMap = new Dictionary<int,MaterialGraph>();
var layerMap = new Dictionary<Guid, MaterialGraph>();
foreach (var layer in layers)
{

if (graph == null)
continue;
layerMap[layer.layer] = graph;
layerMap[layer.guid] = graph;
}
if (layerMap.Count == 0)

var shaderProperties = new PropertyCollector();
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, layerMap[0].masterNode as AbstractMaterialNode, true);
var baseGraph = layerMap.Values.FirstOrDefault();
if (baseGraph == null)
{
configuredTextures = new List<PropertyCollector.TextureInfo>();
return string.Empty;
}
var masterNode = baseGraph.masterNode;
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, masterNode as AbstractMaterialNode, true);
foreach (var layer in layerMap)
{

requirements,
mode,
true,
"Layer_" + Mathf.Abs(layer.Key));
LayerToFunctionName(layer.Key));
surfaceDescriptionStruct.AddShaderChunk("struct WeightsSurfaceDescription{", false);
surfaceDescriptionStruct.Indent();

"PopulateWeightsGraph",
"WeightsSurfaceDescription");
string functionName = "PopulateSurfaceData";
string surfaceDescriptionName = "SurfaceDescription";
layerShaders.AddShaderChunk(string.Format("{0} {1}(SurfaceInputs IN) {{", surfaceDescriptionName, functionName), false);
layerShaders.Indent();
layerShaders.AddShaderChunk("WeightsSurfaceDescription weights = PopulateWeightsGraph(IN);", false);
layerShaders.AddShaderChunk("SurfaceDescription result = (SurfaceDescription)0;", false);
layerShaders.AddShaderChunk(
string.Format(
"{0} {1} = {2}({3});",
surfaceDescriptionName,
LayerToFunctionName(layer.Key) + "_surface",
LayerToFunctionName(layer.Key),
"IN"), false);
layerShaders.AddShaderChunk(
string.Format("ScaleSurfaceDescription({0}_surface, weights.{0});", LayerToFunctionName(layer.Key)), false);
layerShaders.AddShaderChunk(string.Format("AddSurfaceDescription(result, {0}_surface);", LayerToFunctionName(layer.Key)), false);
layerShaders.AddShaderChunk("return result;", false);
layerShaders.Deindent();
layerShaders.AddShaderChunk("}", false);
var finalShader = new ShaderGenerator();
finalShader.AddShaderChunk(string.Format(@"Shader ""{0}""", name), false);

finalShader.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
finalShader.AddShaderChunk(vertexShader.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);
finalShader.AddShaderChunk(layerShaders.GetShaderString(2), false);
/* var masterNode = node as IMasterNode;
if (masterNode != null)
{
var subShaders = masterNode.GetSubshader(requirements, null);

else
{
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(node, requirements), false);
}*/
finalShader.Deindent();
finalShader.AddShaderChunk("}", false);

37
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/SerializableGuid.cs


using System;
namespace UnityEngine.MaterialGraph
{
[Serializable]
public class SerializableGuid : ISerializationCallbackReceiver
{
public SerializableGuid()
{
m_Guid = Guid.NewGuid();
}
[NonSerialized]
private Guid m_Guid;
[SerializeField]
private string m_GuidSerialized;
public Guid guid
{
get { return m_Guid; }
}
public virtual void OnBeforeSerialize()
{
m_GuidSerialized = m_Guid.ToString();
}
public virtual void OnAfterDeserialize()
{
if (!string.IsNullOrEmpty(m_GuidSerialized))
m_Guid = new Guid(m_GuidSerialized);
else
m_Guid = Guid.NewGuid();
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/SerializableGuid.cs.meta


fileFormatVersion: 2
guid: fb9a23efd2bc46e9a5e34bf5ff0c9768
timeCreated: 1507479217
正在加载...
取消
保存