public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements) { var vertexOutputStruct = new ShaderStringBuilder(2); var vertexShader = new ShaderStringBuilder(2); var vertexShaderDescriptionInputs = new ShaderStringBuilder(2); var vertexShaderOutputs = new ShaderStringBuilder(1); var pixelShader = new ShaderStringBuilder(2); var pixelShaderSurfaceInputs = new ShaderStringBuilder(2); var pixelShaderSurfaceRemap = new ShaderStringBuilder(2); ShaderGenerator.GenerateStandardTransforms( 0, 16, vertexOutputStruct, vertexShader, vertexShaderDescriptionInputs, vertexShaderOutputs, pixelShader, pixelShaderSurfaceInputs, shaderGraphRequirements, shaderGraphRequirements, ShaderGraphRequirements.none, ShaderGraphRequirements.none, CoordinateSpace.World); vertexShader.AppendLines(vertexShaderDescriptionInputs.ToString()); vertexShader.AppendLines(vertexShaderOutputs.ToString()); if (node != null) { var outputSlot = node.GetOutputSlots <MaterialSlot>().FirstOrDefault(); if (outputSlot != null) { var result = string.Format("surf.{0}", node.GetVariableNameForSlot(outputSlot.id)); pixelShaderSurfaceRemap.AppendLine("return {0};", AdaptNodeOutputForPreview(node, outputSlot.id, result)); } else { pixelShaderSurfaceRemap.AppendLine("return 0;"); } } else { pixelShaderSurfaceRemap.AppendLine("return surf.PreviewOutput;"); } var res = subShaderTemplate.Replace("${Interpolators}", vertexOutputStruct.ToString()); res = res.Replace("${VertexShader}", vertexShader.ToString()); res = res.Replace("${LocalPixelShader}", pixelShader.ToString()); res = res.Replace("${SurfaceInputs}", pixelShaderSurfaceInputs.ToString()); res = res.Replace("${SurfaceOutputRemap}", pixelShaderSurfaceRemap.ToString()); return(res); }
public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements) { var interpolators = new ShaderGenerator(); var vertexShader = new ShaderGenerator(); var pixelShader = new ShaderGenerator(); var surfaceInputs = new ShaderGenerator(); ShaderGenerator.GenerateStandardTransforms( 0, 16, interpolators, vertexShader, pixelShader, surfaceInputs, shaderGraphRequirements, ShaderGraphRequirements.none, CoordinateSpace.World); var outputs = new ShaderGenerator(); if (node != null) { var outputSlot = node.GetOutputSlots <MaterialSlot>().FirstOrDefault(); if (outputSlot != null) { var result = string.Format("surf.{0}", node.GetVariableNameForSlot(outputSlot.id)); outputs.AddShaderChunk(string.Format("return {0};", AdaptNodeOutputForPreview(node, outputSlot.id, result)), true); } else { outputs.AddShaderChunk("return 0;", true); } } else { outputs.AddShaderChunk("return surf.PreviewOutput;", false); } var res = subShaderTemplate.Replace("${Interpolators}", interpolators.GetShaderString(0)); res = res.Replace("${VertexShader}", vertexShader.GetShaderString(0)); res = res.Replace("${LocalPixelShader}", pixelShader.GetShaderString(0)); res = res.Replace("${SurfaceInputs}", surfaceInputs.GetShaderString(0)); res = res.Replace("${SurfaceOutputRemap}", outputs.GetShaderString(0)); return(res); }
public static string AdaptNodeOutputForPreview(AbstractMaterialNode node, int outputSlotId) { var rawOutput = node.GetVariableNameForSlot(outputSlotId); return(AdaptNodeOutputForPreview(node, outputSlotId, rawOutput)); }
public static string AdaptNodeOutput(AbstractMaterialNode node, int outputSlotId, ConcreteSlotValueType convertToType) { var outputSlot = node.FindOutputSlot <MaterialSlot>(outputSlotId); if (outputSlot == null) { return(kErrorString); } var convertFromType = outputSlot.concreteValueType; var rawOutput = node.GetVariableNameForSlot(outputSlotId); if (convertFromType == convertToType) { return(rawOutput); } switch (convertToType) { case ConcreteSlotValueType.Vector1: return(string.Format("({0}).x", rawOutput)); case ConcreteSlotValueType.Vector2: switch (convertFromType) { case ConcreteSlotValueType.Vector1: return(string.Format("({0}.xx)", rawOutput)); case ConcreteSlotValueType.Vector3: case ConcreteSlotValueType.Vector4: return(string.Format("({0}.xy)", rawOutput)); default: return(kErrorString); } case ConcreteSlotValueType.Vector3: switch (convertFromType) { case ConcreteSlotValueType.Vector1: return(string.Format("({0}.xxx)", rawOutput)); case ConcreteSlotValueType.Vector2: return(string.Format("({0}3({1}, 0.0))", node.precision, rawOutput)); case ConcreteSlotValueType.Vector4: return(string.Format("({0}.xyz)", rawOutput)); default: return(kErrorString); } case ConcreteSlotValueType.Vector4: switch (convertFromType) { case ConcreteSlotValueType.Vector1: return(string.Format("({0}.xxxx)", rawOutput)); case ConcreteSlotValueType.Vector2: return(string.Format("({0}4({1}, 0.0, 1.0))", node.precision, rawOutput)); case ConcreteSlotValueType.Vector3: return(string.Format("({0}4({1}, 1.0))", node.precision, rawOutput)); default: return(kErrorString); } case ConcreteSlotValueType.Matrix3: return(rawOutput); case ConcreteSlotValueType.Matrix2: return(rawOutput); default: return(kErrorString); } }
internal static void GenerateSurfaceDescription( List <INode> activeNodeList, AbstractMaterialNode masterNode, AbstractMaterialGraph graph, ShaderGenerator surfaceDescriptionFunction, FunctionRegistry functionRegistry, PropertyCollector shaderProperties, ShaderGraphRequirements requirements, GenerationMode mode, string functionName = "PopulateSurfaceData", string surfaceDescriptionName = "SurfaceDescription", FloatShaderProperty outputIdProperty = 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); graph.CollectShaderProperties(shaderProperties, mode); foreach (var activeNode in activeNodeList.OfType <AbstractMaterialNode>()) { if (activeNode is IGeneratesFunction) { functionRegistry.builder.currentNode = activeNode; (activeNode as IGeneratesFunction).GenerateNodeFunction(functionRegistry, 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) { surfaceDescriptionFunction.AddShaderChunk(String.Format("if ({0} == {1}) {{ surface.PreviewOutput = {2}; return surface; }}", outputIdProperty.referenceName, activeNode.tempId.index, ShaderGenerator.AdaptNodeOutputForPreview(activeNode, outputSlot.id, activeNode.GetVariableNameForSlot(outputSlot.id))), false); } } activeNode.CollectShaderProperties(shaderProperties, mode); } functionRegistry.builder.currentNode = null; 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};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), fromNode.GetVariableNameForSlot(outputRef.slotId)), true); } else { surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", NodeUtils.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};", NodeUtils.GetHLSLSafeName(slot.shaderOutputName), masterNode.GetVariableNameForSlot(slot.id)), true); } } } surfaceDescriptionFunction.AddShaderChunk("return surface;", false); surfaceDescriptionFunction.Deindent(); surfaceDescriptionFunction.AddShaderChunk("}", false); }