Peter Bay Bastian
7 年前
当前提交
83c052cb
共有 15 个文件被更改,包括 470 次插入 和 446 次删除
-
481MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/ColorShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/CubemapShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/FloatShaderProperty.cs
-
2MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/IShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/SamplerStateShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/TextureShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector2ShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector3ShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/Vector4ShaderProperty.cs
-
6MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightPBRSubShader.cs
-
8MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/LightweightPipeline/LightWeightUnlitSubShader.cs
-
366MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/GraphUtil.cs
-
3MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/GraphUtil.cs.meta
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEditor.Graphing; |
|||
using UnityEditor.Graphing.Util; |
|||
|
|||
namespace UnityEditor.ShaderGraph |
|||
{ |
|||
static class GraphUtil |
|||
{ |
|||
internal static ShaderGraphRequirements GetRequirements(List<INode> nodes) |
|||
{ |
|||
NeededCoordinateSpace requiresNormal = nodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal()); |
|||
NeededCoordinateSpace requiresBitangent = nodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresBitangent()); |
|||
NeededCoordinateSpace requiresTangent = nodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent()); |
|||
NeededCoordinateSpace requiresViewDir = nodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresViewDirection()); |
|||
NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition()); |
|||
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition()); |
|||
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor()); |
|||
|
|||
var meshUV = new List<UVChannel>(); |
|||
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex) |
|||
{ |
|||
var channel = (UVChannel)uvIndex; |
|||
if (nodes.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel))) |
|||
meshUV.Add(channel); |
|||
} |
|||
|
|||
// if anything needs tangentspace we have make
|
|||
// sure to have our othonormal basis!
|
|||
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition |
|||
| requiresTangent | requiresViewDir | requiresPosition |
|||
| requiresNormal; |
|||
|
|||
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0; |
|||
if (needsTangentSpace) |
|||
{ |
|||
requiresBitangent |= NeededCoordinateSpace.Object; |
|||
requiresNormal |= NeededCoordinateSpace.Object; |
|||
requiresTangent |= NeededCoordinateSpace.Object; |
|||
} |
|||
|
|||
var reqs = new ShaderGraphRequirements() |
|||
{ |
|||
requiresNormal = requiresNormal, |
|||
requiresBitangent = requiresBitangent, |
|||
requiresTangent = requiresTangent, |
|||
requiresViewDir = requiresViewDir, |
|||
requiresPosition = requiresPosition, |
|||
requiresScreenPosition = requiresScreenPosition, |
|||
requiresVertexColor = requiresVertexColor, |
|||
requiresMeshUVs = meshUV |
|||
}; |
|||
|
|||
return reqs; |
|||
} |
|||
|
|||
internal static void GenerateApplicationVertexInputs(ShaderGraphRequirements graphRequiements, ShaderGenerator vertexInputs, int vertexInputStartIndex, int maxVertexInputs) |
|||
{ |
|||
int vertexInputIndex = vertexInputStartIndex; |
|||
|
|||
vertexInputs.AddShaderChunk("struct GraphVertexInput", false); |
|||
vertexInputs.AddShaderChunk("{", false); |
|||
vertexInputs.Indent(); |
|||
vertexInputs.AddShaderChunk("float4 vertex : POSITION;", false); |
|||
vertexInputs.AddShaderChunk("float3 normal : NORMAL;", false); |
|||
vertexInputs.AddShaderChunk("float4 tangent : TANGENT;", false); |
|||
|
|||
if (graphRequiements.requiresVertexColor) |
|||
{ |
|||
vertexInputs.AddShaderChunk("float4 color : COLOR;", false); |
|||
} |
|||
|
|||
foreach (var channel in graphRequiements.requiresMeshUVs.Distinct()) |
|||
{ |
|||
vertexInputs.AddShaderChunk(String.Format("float4 texcoord{0} : TEXCOORD{1};", ((int)channel).ToString(), vertexInputIndex.ToString()), false); |
|||
vertexInputIndex++; |
|||
} |
|||
|
|||
vertexInputs.AddShaderChunk("UNITY_VERTEX_INPUT_INSTANCE_ID", false); |
|||
vertexInputs.Deindent(); |
|||
vertexInputs.AddShaderChunk("};", false); |
|||
} |
|||
|
|||
static void Visit(List<INode> outputList, Dictionary<Guid, INode> unmarkedNodes, INode node) |
|||
{ |
|||
if (!unmarkedNodes.ContainsKey(node.guid)) |
|||
return; |
|||
foreach (var slot in node.GetInputSlots<ISlot>()) |
|||
{ |
|||
foreach (var edge in node.owner.GetEdges(slot.slotReference)) |
|||
{ |
|||
var inputNode = node.owner.GetNodeFromGuid(edge.outputSlot.nodeGuid); |
|||
Visit(outputList, unmarkedNodes, inputNode); |
|||
} |
|||
} |
|||
unmarkedNodes.Remove(node.guid); |
|||
outputList.Add(node); |
|||
} |
|||
|
|||
public static string GetShader(this AbstractMaterialGraph graph, AbstractMaterialNode node, GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures, out PreviewMode previewMode, out FloatShaderProperty outputIdProperty, Dictionary<Guid, int> ids = null) |
|||
{ |
|||
bool isUber = node == null; |
|||
|
|||
var vertexInputs = new ShaderGenerator(); |
|||
var vertexShader = new ShaderGenerator(); |
|||
var surfaceDescriptionFunction = new ShaderGenerator(); |
|||
var surfaceDescriptionStruct = new ShaderGenerator(); |
|||
var shaderFunctionVisitor = new ShaderGenerator(); |
|||
var surfaceInputs = new ShaderGenerator(); |
|||
|
|||
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false); |
|||
surfaceInputs.Indent(); |
|||
|
|||
var activeNodeList = ListPool<INode>.Get(); |
|||
if (isUber) |
|||
{ |
|||
var unmarkedNodes = graph.GetNodes<INode>().Where(x => !(x is IMasterNode)).ToDictionary(x => x.guid); |
|||
while (unmarkedNodes.Any()) |
|||
{ |
|||
var unmarkedNode = unmarkedNodes.FirstOrDefault(); |
|||
Visit(activeNodeList, unmarkedNodes, unmarkedNode.Value); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node); |
|||
} |
|||
|
|||
var requirements = GraphUtil.GetRequirements(activeNodeList); |
|||
GraphUtil.GenerateApplicationVertexInputs(requirements, vertexInputs, 0, 8); |
|||
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresNormal, InterpolatorType.Normal, surfaceInputs); |
|||
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresTangent, InterpolatorType.Tangent, surfaceInputs); |
|||
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresBitangent, InterpolatorType.BiTangent, surfaceInputs); |
|||
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresViewDir, InterpolatorType.ViewDirection, surfaceInputs); |
|||
ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(requirements.requiresPosition, InterpolatorType.Position, surfaceInputs); |
|||
|
|||
if (requirements.requiresVertexColor) |
|||
surfaceInputs.AddShaderChunk(String.Format("float4 {0};", ShaderGeneratorNames.VertexColor), false); |
|||
|
|||
if (requirements.requiresScreenPosition) |
|||
surfaceInputs.AddShaderChunk(String.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false); |
|||
|
|||
previewMode = PreviewMode.Preview3D; |
|||
if (!isUber) |
|||
{ |
|||
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); |
|||
|
|||
var slots = new List<MaterialSlot>(); |
|||
foreach (var activeNode in isUber ? activeNodeList.Where(n => ((AbstractMaterialNode)n).hasPreview) : ((INode)node).ToEnumerable()) |
|||
{ |
|||
if (activeNode is IMasterNode) |
|||
slots.AddRange(activeNode.GetInputSlots<MaterialSlot>()); |
|||
else |
|||
slots.AddRange(activeNode.GetOutputSlots<MaterialSlot>()); |
|||
} |
|||
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, !isUber); |
|||
|
|||
var shaderProperties = new PropertyCollector(); |
|||
outputIdProperty = new FloatShaderProperty |
|||
{ |
|||
displayName = "OutputId", |
|||
generatePropertyBlock = false, |
|||
value = -1 |
|||
}; |
|||
if (isUber) |
|||
shaderProperties.AddShaderProperty(outputIdProperty); |
|||
|
|||
GenerateSurfaceDescription( |
|||
activeNodeList, |
|||
node, |
|||
graph, |
|||
surfaceDescriptionFunction, |
|||
shaderFunctionVisitor, |
|||
shaderProperties, |
|||
requirements, |
|||
mode, |
|||
outputIdProperty: outputIdProperty, |
|||
ids: ids); |
|||
|
|||
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(vertexInputs.GetShaderString(2), 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); |
|||
|
|||
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(node, requirements), false); |
|||
|
|||
ListPool<INode>.Release(activeNodeList); |
|||
|
|||
finalShader.Deindent(); |
|||
finalShader.AddShaderChunk("}", false); |
|||
configuredTextures = shaderProperties.GetConfiguredTexutres(); |
|||
return finalShader.GetShaderString(0); |
|||
} |
|||
|
|||
internal static void GenerateSurfaceDescriptionStruct(ShaderGenerator surfaceDescriptionStruct, List<MaterialSlot> slots, bool isMaster) |
|||
{ |
|||
surfaceDescriptionStruct.AddShaderChunk("struct SurfaceDescription{", false); |
|||
surfaceDescriptionStruct.Indent(); |
|||
if (isMaster) |
|||
{ |
|||
foreach (var slot in slots) |
|||
surfaceDescriptionStruct.AddShaderChunk(String.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), AbstractMaterialNode.GetHLSLSafeName(slot.shaderOutputName)), false); |
|||
surfaceDescriptionStruct.Deindent(); |
|||
} |
|||
else |
|||
{ |
|||
surfaceDescriptionStruct.AddShaderChunk("float4 PreviewOutput;", false); |
|||
} |
|||
surfaceDescriptionStruct.Deindent(); |
|||
surfaceDescriptionStruct.AddShaderChunk("};", false); |
|||
} |
|||
|
|||
internal static void GenerateSurfaceDescription( |
|||
List<INode> activeNodeList, |
|||
AbstractMaterialNode masterNode, |
|||
AbstractMaterialGraph graph, |
|||
ShaderGenerator surfaceDescriptionFunction, |
|||
ShaderGenerator shaderFunctionVisitor, |
|||
PropertyCollector shaderProperties, |
|||
ShaderGraphRequirements requirements, |
|||
GenerationMode mode, |
|||
string functionName = "PopulateSurfaceData", |
|||
string surfaceDescriptionName = "SurfaceDescription", |
|||
FloatShaderProperty outputIdProperty = null, |
|||
Dictionary<Guid, int> ids = null, |
|||
IEnumerable<MaterialSlot> slots = null) |
|||
{ |
|||
if (graph == null) |
|||
return; |
|||
|
|||
surfaceDescriptionFunction.AddShaderChunk(String.Format("{0} {1}(SurfaceInputs IN) {{", surfaceDescriptionName, functionName), false); |
|||
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); |
|||
|
|||
var currentId = -1; |
|||
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>()) |
|||
{ |
|||
if (activeNode is IGeneratesFunction) |
|||
(activeNode as IGeneratesFunction).GenerateNodeFunction(shaderFunctionVisitor, mode); |
|||
if (activeNode is IGeneratesBodyCode) |
|||
(activeNode as IGeneratesBodyCode).GenerateNodeCode(surfaceDescriptionFunction, mode); |
|||
if (masterNode == null && activeNode.hasPreview) |
|||
{ |
|||
var outputSlot = activeNode.GetOutputSlots<MaterialSlot>().FirstOrDefault(); |
|||
if (outputSlot != null) |
|||
{ |
|||
currentId++; |
|||
ids[activeNode.guid] = currentId; |
|||
surfaceDescriptionFunction.AddShaderChunk(String.Format("if ({0} == {1}) {{ surface.PreviewOutput = {2}; return surface; }}", outputIdProperty.referenceName, currentId, ShaderGenerator.AdaptNodeOutputForPreview(activeNode, outputSlot.id, activeNode.GetVariableNameForSlot(outputSlot.id))), false); |
|||
} |
|||
} |
|||
|
|||
activeNode.CollectShaderProperties(shaderProperties, mode); |
|||
} |
|||
|
|||
if (masterNode != null) |
|||
{ |
|||
if (masterNode is IMasterNode) |
|||
{ |
|||
var usedSlots = slots ?? masterNode.GetInputSlots<MaterialSlot>(); |
|||
foreach (var input in usedSlots) |
|||
{ |
|||
var foundEdges = graph.GetEdges(input.slotReference).ToArray(); |
|||
if (foundEdges.Any()) |
|||
{ |
|||
var outputRef = foundEdges[0].outputSlot; |
|||
var fromNode = graph.GetNodeFromGuid<AbstractMaterialNode>(outputRef.nodeGuid); |
|||
surfaceDescriptionFunction.AddShaderChunk(String.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(input.shaderOutputName), fromNode.GetVariableNameForSlot(outputRef.slotId)), true); |
|||
} |
|||
else |
|||
{ |
|||
surfaceDescriptionFunction.AddShaderChunk(String.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode)), true); |
|||
} |
|||
} |
|||
} |
|||
else if (masterNode.hasPreview) |
|||
{ |
|||
foreach (var slot in masterNode.GetOutputSlots<MaterialSlot>()) |
|||
surfaceDescriptionFunction.AddShaderChunk(String.Format("surface.{0} = {1};", AbstractMaterialNode.GetHLSLSafeName(slot.shaderOutputName), masterNode.GetVariableNameForSlot(slot.id)), true); |
|||
} |
|||
} |
|||
|
|||
surfaceDescriptionFunction.AddShaderChunk("return surface;", false); |
|||
surfaceDescriptionFunction.Deindent(); |
|||
surfaceDescriptionFunction.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
public static string GetPreviewShader(this AbstractMaterialGraph graph, AbstractMaterialNode node, out PreviewMode previewMode) |
|||
{ |
|||
List<PropertyCollector.TextureInfo> configuredTextures; |
|||
FloatShaderProperty outputIdProperty; |
|||
return graph.GetShader(node, GenerationMode.Preview, string.Format("hidden/preview/{0}", node.GetVariableNameForNode()), out configuredTextures, out previewMode, out outputIdProperty); |
|||
} |
|||
|
|||
public static string GetUberPreviewShader(this AbstractMaterialGraph graph, Dictionary<Guid, int> ids, out FloatShaderProperty outputIdProperty) |
|||
{ |
|||
List<PropertyCollector.TextureInfo> configuredTextures; |
|||
PreviewMode previewMode; |
|||
return graph.GetShader(null, GenerationMode.Preview, "hidden/preview", out configuredTextures, out previewMode, out outputIdProperty, ids); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 130a64d32c054c5fb51b1e5e13f93fc2 |
|||
timeCreated: 1513590591 |
撰写
预览
正在加载...
取消
保存
Reference in new issue