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); }
private static string GetShaderPassFromTemplate(string template, PBRMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions) { var builder = new ShaderStringBuilder(); builder.IncreaseIndent(); builder.IncreaseIndent(); var vertexInputs = new ShaderGenerator(); var surfaceVertexShader = new ShaderGenerator(); var surfaceDescriptionFunction = new ShaderGenerator(); var surfaceDescriptionStruct = new ShaderGenerator(); var functionRegistry = new FunctionRegistry(builder); var surfaceInputs = new ShaderGenerator(); var shaderProperties = new PropertyCollector(); surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false); surfaceInputs.Indent(); var activeNodeList = ListPool <INode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots); var requirements = ShaderGraphRequirements.FromNodes(activeNodeList); var modelRequiements = ShaderGraphRequirements.none; modelRequiements.requiresNormal |= NeededCoordinateSpace.World; modelRequiements.requiresTangent |= NeededCoordinateSpace.World; modelRequiements.requiresBitangent |= NeededCoordinateSpace.World; modelRequiements.requiresPosition |= NeededCoordinateSpace.World; modelRequiements.requiresViewDir |= NeededCoordinateSpace.World; modelRequiements.requiresMeshUVs.Add(UVChannel.UV1); GraphUtil.GenerateApplicationVertexInputs(requirements.Union(modelRequiements), vertexInputs); 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); } foreach (var channel in requirements.requiresMeshUVs.Distinct()) { surfaceInputs.AddShaderChunk(string.Format("half4 {0};", channel.GetUVName()), false); } surfaceInputs.Deindent(); surfaceInputs.AddShaderChunk("};", false); surfaceVertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false); surfaceVertexShader.Indent(); surfaceVertexShader.AddShaderChunk("return v;", false); surfaceVertexShader.Deindent(); surfaceVertexShader.AddShaderChunk("}", false); var slots = new List <MaterialSlot>(); foreach (var id in pass.PixelShaderSlots) { slots.Add(masterNode.FindSlot <MaterialSlot>(id)); } GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, true); var usedSlots = new List <MaterialSlot>(); foreach (var id in pass.PixelShaderSlots) { usedSlots.Add(masterNode.FindSlot <MaterialSlot>(id)); } GraphUtil.GenerateSurfaceDescription( activeNodeList, masterNode, masterNode.owner as AbstractMaterialGraph, surfaceDescriptionFunction, functionRegistry, shaderProperties, requirements, mode, "PopulateSurfaceData", "SurfaceDescription", null, usedSlots); var graph = new ShaderGenerator(); graph.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false); graph.AddShaderChunk(surfaceInputs.GetShaderString(2), false); graph.AddShaderChunk(builder.ToString(), false); graph.AddShaderChunk(vertexInputs.GetShaderString(2), false); graph.AddShaderChunk(surfaceDescriptionStruct.GetShaderString(2), false); graph.AddShaderChunk(surfaceVertexShader.GetShaderString(2), false); graph.AddShaderChunk(surfaceDescriptionFunction.GetShaderString(2), false); var blendingVisitor = new ShaderGenerator(); var cullingVisitor = new ShaderGenerator(); var zTestVisitor = new ShaderGenerator(); var zWriteVisitor = new ShaderGenerator(); materialOptions.GetBlend(blendingVisitor); materialOptions.GetCull(cullingVisitor); materialOptions.GetDepthTest(zTestVisitor); materialOptions.GetDepthWrite(zWriteVisitor); var interpolators = new ShaderGenerator(); var localVertexShader = new ShaderGenerator(); var localPixelShader = new ShaderGenerator(); var localSurfaceInputs = new ShaderGenerator(); var surfaceOutputRemap = new ShaderGenerator(); ShaderGenerator.GenerateStandardTransforms( 3, 10, interpolators, localVertexShader, localPixelShader, localSurfaceInputs, requirements, modelRequiements, CoordinateSpace.World); ShaderGenerator defines = new ShaderGenerator(); if (masterNode.IsSlotConnected(PBRMasterNode.NormalSlotId)) { defines.AddShaderChunk("#define _NORMALMAP 1", true); } if (masterNode.model == PBRMasterNode.Model.Specular) { defines.AddShaderChunk("#define _SPECULAR_SETUP 1", true); } if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId)) { defines.AddShaderChunk("#define _AlphaClip 1", true); } if (masterNode.surfaceType == SurfaceType.Transparent && masterNode.alphaMode == AlphaMode.Premultiply) { defines.AddShaderChunk("#define _ALPHAPREMULTIPLY_ON 1", true); } var templateLocation = ShaderGenerator.GetTemplatePath(template); foreach (var slot in usedSlots) { surfaceOutputRemap.AddShaderChunk(string.Format("{0} = surf.{0};", slot.shaderOutputName), true); } if (!File.Exists(templateLocation)) { return(string.Empty); } var subShaderTemplate = File.ReadAllText(templateLocation); var resultPass = subShaderTemplate.Replace("${Defines}", defines.GetShaderString(3)); resultPass = resultPass.Replace("${Graph}", graph.GetShaderString(3)); resultPass = resultPass.Replace("${Interpolators}", interpolators.GetShaderString(3)); resultPass = resultPass.Replace("${VertexShader}", localVertexShader.GetShaderString(3)); resultPass = resultPass.Replace("${LocalPixelShader}", localPixelShader.GetShaderString(3)); resultPass = resultPass.Replace("${SurfaceInputs}", localSurfaceInputs.GetShaderString(3)); resultPass = resultPass.Replace("${SurfaceOutputRemap}", surfaceOutputRemap.GetShaderString(3)); resultPass = resultPass.Replace("${Tags}", string.Empty); resultPass = resultPass.Replace("${Blending}", blendingVisitor.GetShaderString(2)); resultPass = resultPass.Replace("${Culling}", cullingVisitor.GetShaderString(2)); resultPass = resultPass.Replace("${ZTest}", zTestVisitor.GetShaderString(2)); resultPass = resultPass.Replace("${ZWrite}", zWriteVisitor.GetShaderString(2)); return(resultPass); }
public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements) { // Should never be called without a node Debug.Assert(node != null); 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()); var outputSlot = node.GetOutputSlots <MaterialSlot>().FirstOrDefault(); // Sub Graph Output uses first input slot if (node is SubGraphOutputNode) { outputSlot = node.GetInputSlots <MaterialSlot>().FirstOrDefault(); } if (outputSlot != null) { var result = $"surf.{NodeUtils.GetHLSLSafeName(outputSlot.shaderOutputName)}_{outputSlot.id}"; pixelShaderSurfaceRemap.AppendLine("return all(isfinite({0})) ? {1} : {2};", result, AdaptNodeOutputForPreview(node, outputSlot.id, result), nanOutput); } else { // No valid slots to display, so just show black. // It's up to each node to error or warn as appropriate. pixelShaderSurfaceRemap.AppendLine("return 0;"); } // ------------------------------------- // Extra pixel shader work var faceSign = new ShaderStringBuilder(); if (shaderGraphRequirements.requiresFaceSign) { faceSign.AppendLine(", half FaceSign : VFACE"); } var res = subShaderTemplate.Replace("${Interpolators}", vertexOutputStruct.ToString()); res = res.Replace("${VertexShader}", vertexShader.ToString()); res = res.Replace("${FaceSign}", faceSign.ToString()); res = res.Replace("${LocalPixelShader}", pixelShader.ToString()); res = res.Replace("${SurfaceInputs}", pixelShaderSurfaceInputs.ToString()); res = res.Replace("${SurfaceOutputRemap}", pixelShaderSurfaceRemap.ToString()); return(res); }