浏览代码

refactoring material graph to allow for layered materials.

/main
Tim Cooper 7 年前
当前提交
7809cfe9
共有 4 个文件被更改,包括 339 次插入87 次删除
  1. 195
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs
  2. 182
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/LayeredShaderGraph.cs
  3. 46
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/ShaderLayerview.cs
  4. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/ShaderLayerview.cs.meta

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


base.OnAfterDeserialize();
}
static ShaderGraphRequirements GetRequierments(AbstractMaterialNode nodeForRequirements)
protected static ShaderGraphRequirements GetRequierments(AbstractMaterialNode nodeForRequirements)
if (nodeForRequirements == null)
return ShaderGraphRequirements.none;
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, nodeForRequirements);

return reqs;
}
static void GenerateSpaceTranslationSurfaceInputs(
protected static void GenerateSpaceTranslationSurfaceInputs(
NeededCoordinateSpace neededSpaces,
ShaderGenerator surfaceInputs,
string objectSpaceName,

return GetShader(node, GenerationMode.Preview, string.Format("hidden/preview/{0}", node.GetVariableNameForNode()), out configuredTextures, out previewMode);
}
public string GetShader(AbstractMaterialNode node, GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures, out PreviewMode previewMode)
protected void GenerateSurfaceDescriptionStruct(ShaderGenerator surfaceDescriptionStruct, AbstractMaterialNode node, bool isMasterNode)
if (node == null)
throw new ArgumentNullException("node");
var vertexShader = new ShaderGenerator();
var surfaceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
var graphVertexInput = @"
struct GraphVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord0 : TEXCOORD0;
float4 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};";
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();
var requirements = GetRequierments(node);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresViewDir, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, surfaceInputs,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition);
if (requirements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.VertexColor), false);
if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
previewMode = PreviewMode.Preview2D;
foreach (var pNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (pNode.previewMode == PreviewMode.Preview3D)
{
previewMode = PreviewMode.Preview3D;
break;
}
}
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("half4 {0};", channel.GetUVName()), false);
surfaceInputs.Deindent();
surfaceInputs.AddShaderChunk("};", false);
vertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false);
vertexShader.Indent();
vertexShader.AddShaderChunk("return v;", false);
vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
if (node is IMasterNode)
if (isMasterNode)
{
foreach (var slot in node.GetInputSlots<MaterialSlot>())
surfaceDescriptionStruct.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + slot.shaderOutputName + ";", false);

}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
}
surfaceDescriptionFunction.AddShaderChunk("SurfaceDescription PopulateSurfaceData(SurfaceInputs IN) {", false);
protected void GenerateSurfaceDescription(
AbstractMaterialNode node,
ShaderGenerator surfaceDescriptionFunction,
ShaderGenerator shaderFunctionVisitor,
PropertyCollector shaderProperties,
ShaderGraphRequirements requirements,
GenerationMode mode,
bool isMasterNode,
string functionName = "PopulateSurfaceData",
string surfaceDescriptionName = "SurfaceDescription")
{
surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} {1}(SurfaceInputs IN) {{", surfaceDescriptionName, functionName), false);
surfaceDescriptionFunction.Indent();
if ((requirements.requiresNormal & NeededCoordinateSpace.Object) > 0)

foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceDescriptionFunction.AddShaderChunk(string.Format("half4 {0} = IN.{0};", channel.GetUVName()), false);
var shaderProperties = new PropertyCollector();
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (activeNode is IGeneratesFunction)

activeNode.CollectShaderProperties(shaderProperties, mode);
}
surfaceDescriptionFunction.AddShaderChunk("SurfaceDescription surface = (SurfaceDescription)0;", false);
if (node is IMasterNode)
surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} surface = ({0})0;", surfaceDescriptionName), false);
if (isMasterNode)
{
foreach (var input in node.GetInputSlots<MaterialSlot>())
{

surfaceDescriptionFunction.Deindent();
surfaceDescriptionFunction.AddShaderChunk("}", false);
ListPool<INode>.Release(activeNodeList);
}
public string GetShader(AbstractMaterialNode node, GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures, out PreviewMode previewMode)
{
if (node == null)
throw new ArgumentNullException("node");
var vertexShader = new ShaderGenerator();
var surfaceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
var graphVertexInput = @"
struct GraphVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord0 : TEXCOORD0;
float4 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};";
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();
var requirements = GetRequierments(node);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresViewDir, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, surfaceInputs,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition);
if (requirements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.VertexColor), false);
if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
previewMode = PreviewMode.Preview2D;
foreach (var pNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (pNode.previewMode == PreviewMode.Preview3D)
{
previewMode = PreviewMode.Preview3D;
break;
}
}
ListPool<INode>.Release(activeNodeList);
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("half4 {0};", channel.GetUVName()), false);
surfaceInputs.Deindent();
surfaceInputs.AddShaderChunk("};", false);
vertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false);
vertexShader.Indent();
vertexShader.AddShaderChunk("return v;", false);
vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, node, node is IMasterNode);
var shaderProperties = new PropertyCollector();
GenerateSurfaceDescription(
node,
surfaceDescriptionFunction,
shaderFunctionVisitor,
shaderProperties,
requirements,
mode,
node is IMasterNode);
var finalShader = new ShaderGenerator();
finalShader.AddShaderChunk(string.Format(@"Shader ""{0}""", name), false);

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


public override void OnAfterDeserialize()
{
base.OnAfterDeserialize();
base.OnAfterDeserialize();
configuredTextures = new List<PropertyCollector.TextureInfo>();
return string.Empty;
//PreviewMode pmode;
//return GetShader(masterNode as AbstractMaterialNode, mode, name, out configuredTextures, out pmode);
if (outputNode == null)
throw new InvalidOperationException();
var layerMap = new Dictionary<int,MaterialGraph>();
foreach (var layer in layers)
{
var path = AssetDatabase.GetAssetPath(layer.shader);
if (!path.EndsWith("shaderGraph", StringComparison.InvariantCultureIgnoreCase))
continue;
var textGraph = File.ReadAllText(path, Encoding.UTF8);
var graph = JsonUtility.FromJson<MaterialGraph>(textGraph);
if (graph == null)
continue;
layerMap[layer.layer] = graph;
}
if (layerMap.Count == 0)
{
configuredTextures = new List<PropertyCollector.TextureInfo>();
return string.Empty;
}
var vertexShader = new ShaderGenerator();
var layerShaders = new ShaderGenerator();
var surfaceDescriptionFunction = new ShaderGenerator();
var surfaceDescriptionStruct = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var surfaceInputs = new ShaderGenerator();
var graphVertexInput = @"
struct GraphVertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord0 : TEXCOORD0;
float4 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};";
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();
var requirements = ShaderGraphRequirements.none;
foreach (var layer in layerMap)
requirements = requirements.Union(GetRequierments(layer.Value.masterNode as AbstractMaterialNode));
requirements = requirements.Union(GetRequierments(outputNode));
GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresViewDir, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection);
GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, surfaceInputs,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition);
if (requirements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.VertexColor), false);
if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);
foreach (var channel in requirements.requiresMeshUVs.Distinct())
surfaceInputs.AddShaderChunk(string.Format("half4 {0};", channel.GetUVName()), false);
surfaceInputs.Deindent();
surfaceInputs.AddShaderChunk("};", false);
vertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false);
vertexShader.Indent();
vertexShader.AddShaderChunk("return v;", false);
vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
var shaderProperties = new PropertyCollector();
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, layerMap[0].masterNode as AbstractMaterialNode, true);
foreach (var layer in layerMap)
{
GenerateSurfaceDescription(
layer.Value.masterNode as AbstractMaterialNode,
surfaceDescriptionFunction,
shaderFunctionVisitor,
shaderProperties,
requirements,
mode,
true,
"Layer_" + Mathf.Abs(layer.Key));
}
surfaceDescriptionStruct.AddShaderChunk("struct WeightsSurfaceDescription{", false);
surfaceDescriptionStruct.Indent();
foreach (var slot in outputNode.GetInputSlots<MaterialSlot>())
surfaceDescriptionStruct.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType) + " " + slot.shaderOutputName + ";", false);
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
GenerateSurfaceDescription(
outputNode,
surfaceDescriptionFunction,
shaderFunctionVisitor,
shaderProperties,
requirements,
mode,
true,
"PopulateWeightsGraph",
"WeightsSurfaceDescription");
foreach (var layer in layerMap)
{
}
var finalShader = new ShaderGenerator();
finalShader.AddShaderChunk(string.Format(@"Shader ""{0}""", name), false);
finalShader.AddShaderChunk("{", false);
finalShader.Indent();
finalShader.AddShaderChunk("Properties", false);
finalShader.AddShaderChunk("{", false);
finalShader.Indent();
finalShader.AddShaderChunk(shaderProperties.GetPropertiesBlock(2), false);
finalShader.Deindent();
finalShader.AddShaderChunk("}", false);
finalShader.AddShaderChunk("CGINCLUDE", false);
finalShader.AddShaderChunk("#include \"UnityCG.cginc\"", false);
finalShader.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
finalShader.AddShaderChunk(graphVertexInput, false);
finalShader.AddShaderChunk(surfaceInputs.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false);
finalShader.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
finalShader.AddShaderChunk(vertexShader.GetShaderString(2), false);
finalShader.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false);
finalShader.AddShaderChunk("ENDCG", false);
/* var masterNode = node as IMasterNode;
if (masterNode != null)
{
var subShaders = masterNode.GetSubshader(requirements, null);
foreach (var ss in subShaders)
finalShader.AddShaderChunk(ss, false);
}
else
{
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(node, requirements), false);
}*/
finalShader.Deindent();
finalShader.AddShaderChunk("}", false);
configuredTextures = shaderProperties.GetConfiguredTexutres();
return finalShader.GetShaderString(0);
}
}

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


using UnityEngine;
using UnityEngine.Experimental.UIElements;
using UnityEngine.Graphing;
using UnityEngine.MaterialGraph;
namespace UnityEditor.MaterialGraph.Drawing.Inspector
{
public class ShaderLayerView : VisualElement
{
public LayeredShaderGraph graph { get; private set; }
public LayeredShaderGraph.Layer layer { get; private set; }
public ShaderLayerView(LayeredShaderGraph graph, LayeredShaderGraph.Layer layer)
{
this.graph = graph;
this.layer = layer;
Add(new IMGUIContainer(ValueField) { name = "value" });
Add(new Button(OnClickRemove) { name = "remove", text = "Remove" });
}
void OnClickRemove()
{
graph.RemoveLayer(layer.layer);
NotifyNodes();
}
void ValueField()
{
EditorGUI.BeginChangeCheck();
var newShader = EditorGUILayout.ObjectField("Shader", layer.shader, typeof(Shader), false) as Shader;
if (newShader != layer.shader)
{
if (graph.SetLayer(layer.layer, newShader))
NotifyNodes();
}
}
void NotifyNodes()
{
foreach (var node in graph.GetNodes<PropertyNode>())
node.onModified(node, ModificationScope.Graph);
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Inspector/ShaderLayerview.cs.meta


fileFormatVersion: 2
guid: e1839e94c8024ee6a36ff3aa05cef37b
timeCreated: 1507451136
正在加载...
取消
保存