浏览代码

Move output selection in uber shader to an earlier place, to benefit from less register usage and early exit

/main
Peter Bay Bastian 7 年前
当前提交
b5df720c
共有 3 个文件被更改,包括 64 次插入59 次删除
  1. 105
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Graphs/AbstractMaterialGraph.cs
  2. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/LayeredShaderGraph.cs
  3. 16
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Util/ShaderGenerator.cs

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


return GetShader(null, GenerationMode.Preview, "hidden/preview", out configuredTextures, out previewMode, out outputIdProperty, ids);
}
protected static void GenerateSurfaceDescriptionStruct(ShaderGenerator surfaceDescriptionStruct, List<MaterialSlot> slots)
protected static void GenerateSurfaceDescriptionStruct(ShaderGenerator surfaceDescriptionStruct, List<MaterialSlot> slots, bool isMaster)
foreach (var slot in slots)
if (isMaster)
if (slot.isInputSlot)
surfaceDescriptionStruct.AddShaderChunk(string.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), slot.shaderOutputName), false);
else
surfaceDescriptionStruct.AddShaderChunk(string.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), ((AbstractMaterialNode) slot.owner).GetVariableNameForSlot(slot.id)), false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
foreach (var slot in slots)
{
if (slot.isInputSlot)
surfaceDescriptionStruct.AddShaderChunk(string.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), slot.shaderOutputName), false);
else
surfaceDescriptionStruct.AddShaderChunk(string.Format("{0} {1};", AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, slot.concreteValueType), ((AbstractMaterialNode) slot.owner).GetVariableNameForSlot(slot.id)), false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
surfaceDescriptionStruct.AddShaderChunk("void ScaleSurfaceDescription(inout SurfaceDescription surface, float scale){", false);
surfaceDescriptionStruct.Indent();
foreach (var slot in slots)
{
if (slot.isInputSlot)
surfaceDescriptionStruct.AddShaderChunk(string.Format("surface.{0} = scale * surface.{0};", slot.shaderOutputName), false);
else
surfaceDescriptionStruct.AddShaderChunk(string.Format("surface.{0} = scale * surface.{0};", ((AbstractMaterialNode) slot.owner).GetVariableNameForSlot(slot.id)), false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
surfaceDescriptionStruct.AddShaderChunk("void ScaleSurfaceDescription(inout SurfaceDescription surface, float scale){", false);
surfaceDescriptionStruct.Indent();
foreach (var slot in slots)
{
if (slot.isInputSlot)
surfaceDescriptionStruct.AddShaderChunk(string.Format("surface.{0} = scale * surface.{0};", slot.shaderOutputName), false);
else
surfaceDescriptionStruct.AddShaderChunk(string.Format("surface.{0} = scale * surface.{0};", ((AbstractMaterialNode) slot.owner).GetVariableNameForSlot(slot.id)), false);
surfaceDescriptionStruct.AddShaderChunk("void AddSurfaceDescription(inout SurfaceDescription base, in SurfaceDescription add){", false);
surfaceDescriptionStruct.Indent();
foreach (var slot in slots)
{
if (slot.isInputSlot)
surfaceDescriptionStruct.AddShaderChunk(string.Format("base.{0} = base.{0} + add.{0};", slot.shaderOutputName), false);
else
surfaceDescriptionStruct.AddShaderChunk(string.Format("base.{0} = base.{0} + add.{0};", ((AbstractMaterialNode) slot.owner).GetVariableNameForSlot(slot.id)), false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);
surfaceDescriptionStruct.AddShaderChunk("void AddSurfaceDescription(inout SurfaceDescription base, in SurfaceDescription add){", false);
surfaceDescriptionStruct.Indent();
foreach (var slot in slots)
else
if (slot.isInputSlot)
surfaceDescriptionStruct.AddShaderChunk(string.Format("base.{0} = base.{0} + add.{0};", slot.shaderOutputName), false);
else
surfaceDescriptionStruct.AddShaderChunk(string.Format("base.{0} = base.{0} + add.{0};", ((AbstractMaterialNode) slot.owner).GetVariableNameForSlot(slot.id)), false);
surfaceDescriptionStruct.AddShaderChunk("float4 PreviewOutput;", false);
}
surfaceDescriptionStruct.Deindent();
surfaceDescriptionStruct.AddShaderChunk("};", false);

ShaderGraphRequirements requirements,
GenerationMode mode,
string functionName = "PopulateSurfaceData",
string surfaceDescriptionName = "SurfaceDescription")
string surfaceDescriptionName = "SurfaceDescription",
FloatShaderProperty outputIdProperty = null,
Dictionary<Guid, int> ids = null)
{
if (graph == null)
return;

surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} surface = ({0})0;", surfaceDescriptionName), false);
foreach (CoordinateSpace space in Enum.GetValues(typeof(CoordinateSpace)))
{

graph.CollectShaderProperties(shaderProperties, mode);
var currentId = -1;
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (activeNode is IGeneratesFunction)

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);
}
}
surfaceDescriptionFunction.AddShaderChunk(string.Format("{0} surface = ({0})0;", surfaceDescriptionName), false);
var surfaceDescriptionNodes = masterNode == null ? activeNodeList.OfType<AbstractMaterialNode>() : masterNode.ToEnumerable();
foreach (var node in surfaceDescriptionNodes)
if (masterNode != null)
if (node is IMasterNode)
if (masterNode is IMasterNode)
foreach (var input in node.GetInputSlots<MaterialSlot>())
foreach (var input in masterNode.GetInputSlots<MaterialSlot>())
{
var foundEdges = graph.GetEdges(input.slotReference).ToArray();
if (foundEdges.Any())

}
}
}
else
else if (masterNode.hasPreview)
if (node.hasPreview)
{
foreach (var slot in node.GetOutputSlots<MaterialSlot>())
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {0};", node.GetVariableNameForSlot(slot.id)), true);
}
foreach (var slot in masterNode.GetOutputSlots<MaterialSlot>())
surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {0};", masterNode.GetVariableNameForSlot(slot.id)), true);
surfaceDescriptionFunction.AddShaderChunk("return surface;", false);
surfaceDescriptionFunction.Deindent();

else
slots.AddRange(activeNode.GetOutputSlots<MaterialSlot>());
}
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots);
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, !isUber);
var shaderProperties = new PropertyCollector();
outputIdProperty = new FloatShaderProperty

shaderFunctionVisitor,
shaderProperties,
requirements,
mode);
mode,
outputIdProperty: outputIdProperty,
ids: ids);
var finalShader = new ShaderGenerator();
finalShader.AddShaderChunk(string.Format(@"Shader ""{0}""", name), false);

}
else
{
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(activeNodeList, node, requirements, outputIdProperty, ids), false);
finalShader.AddShaderChunk(ShaderGenerator.GetPreviewSubShader(node, requirements), false);
}
ListPool<INode>.Release(activeNodeList);

2
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/SubGraph/LayeredShaderGraph.cs


}
var masterNode = baseGraph.masterNode;
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, ((AbstractMaterialNode) masterNode).GetInputSlots<MaterialSlot>().ToList());
GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, ((AbstractMaterialNode) masterNode).GetInputSlots<MaterialSlot>().ToList(), true);
foreach (var layer in layerMap)
{

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


ConvertBetweenSpace(from.ToVariableName(type), from, CoordinateSpace.Tangent, inputType, from)), false);
}
public static string GetPreviewSubShader(List<INode> activeNodeList, AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements, FloatShaderProperty outputIdProperty, Dictionary<Guid, int> ids)
public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements)
{
var interpolators = new ShaderGenerator();
var vertexShader = new ShaderGenerator();

CoordinateSpace.World);
var outputs = new ShaderGenerator();
var currentId = -1;
if (node != null)
{
var outputSlot = node.GetOutputSlots<MaterialSlot>().FirstOrDefault();

}
else
{
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
{
var outputSlot = activeNode.GetOutputSlots<MaterialSlot>().FirstOrDefault();
if (activeNode.hasPreview && outputSlot != null)
{
currentId++;
ids[activeNode.guid] = currentId;
var result = string.Format("surf.{0}", activeNode.GetVariableNameForSlot(outputSlot.id));
outputs.AddShaderChunk(string.Format("if ({0} == {1}) return {2}; else ", outputIdProperty.referenceName, currentId, AdaptNodeOutputForPreview(activeNode, outputSlot.id, result)), false);
}
}
outputs.AddShaderChunk("return 0;", false);
outputs.AddShaderChunk("return surf.PreviewOutput;", false);
}
var res = subShaderTemplate.Replace("${Interpolators}", interpolators.GetShaderString(0));

正在加载...
取消
保存