public string GetShader(GenerationMode mode, string outputName, out List<PropertyCollector.TextureInfo> configuredTextures, List<string> sourceAssetDependencyPaths = null) { var activeNodeList = ListPool<AbstractMaterialNode>.Get(); NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this); var shaderProperties = new PropertyCollector(); var abstractMaterialGraph = owner as GraphData; if (abstractMaterialGraph != null) abstractMaterialGraph.CollectShaderProperties(shaderProperties, mode); foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>()) activeNode.CollectShaderProperties(shaderProperties, mode); var finalShader = new ShaderStringBuilder(); finalShader.AppendLine(@"Shader ""{0}""", outputName); using (finalShader.BlockScope()) { finalShader.AppendLine("Properties"); using (finalShader.BlockScope()) { finalShader.AppendLine(shaderProperties.GetPropertiesBlock(0)); } foreach (var subShader in m_SubShaders) { if (mode != GenerationMode.Preview || subShader.IsPipelineCompatible(GraphicsSettings.renderPipelineAsset)) finalShader.AppendLines(subShader.GetSubshader(this, mode, sourceAssetDependencyPaths)); } finalShader.AppendLine(@"FallBack ""Hidden/InternalErrorShader"""); } configuredTextures = shaderProperties.GetConfiguredTexutres(); return finalShader.ToString(); }
void BuildShader() { var activeNodeList = Graphing.ListPool <AbstractMaterialNode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, m_OutputNode); var shaderProperties = new PropertyCollector(); var shaderKeywords = new KeywordCollector(); m_GraphData.CollectShaderProperties(shaderProperties, m_Mode); m_GraphData.CollectShaderKeywords(shaderKeywords, m_Mode); if (m_GraphData.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit) { m_GraphData.AddValidationError(m_OutputNode.guid, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); m_ConfiguredTextures = shaderProperties.GetConfiguredTexutres(); m_Builder.AppendLines(ShaderGraphImporter.k_ErrorShader); } GetTargetImplementations(); foreach (var activeNode in activeNodeList.OfType <AbstractMaterialNode>()) { activeNode.CollectShaderProperties(shaderProperties, m_Mode); } m_Builder.AppendLine(@"Shader ""{0}""", m_Name); using (m_Builder.BlockScope()) { GenerationUtils.GeneratePropertiesBlock(m_Builder, shaderProperties, shaderKeywords, m_Mode); for (int i = 0; i < m_TargetImplementations.Length; i++) { TargetSetupContext context = new TargetSetupContext(); context.SetMasterNode(m_OutputNode as IMasterNode); // Instead of setup target, we can also just do get context m_TargetImplementations[i].SetupTarget(ref context); GetAssetDependencyPaths(context); GenerateSubShader(i, context.descriptor); } // Either grab the pipeline default for the active node or the user override if (m_OutputNode is ICanChangeShaderGUI canChangeShaderGui) { string customEditor = GenerationUtils.FinalCustomEditorString(canChangeShaderGui); if (customEditor != null) { m_Builder.AppendLine("CustomEditor \"" + customEditor + "\""); } } m_Builder.AppendLine(@"FallBack ""Hidden/Shader Graph/FallbackError"""); } m_ConfiguredTextures = shaderProperties.GetConfiguredTexutres(); }
public string GetSubshader(IMasterNode inMasterNode, GenerationMode mode) { var templatePath = GetTemplatePath("HDUnlitPassForward.template"); if (!File.Exists(templatePath)) return string.Empty; string passTemplate = File.ReadAllText(templatePath); var masterNode = inMasterNode as UnlitMasterNode; var subShader = new ShaderStringBuilder(); subShader.AppendLine("SubShader"); using(subShader.BlockScope()) { subShader.AppendLine("Tags{ \"RenderPipeline\" = \"HDRenderPipeline\"}"); subShader.AppendLine("Tags{ \"RenderType\" = \"Opaque\" }"); subShader.AppendLines( GetShaderPassFromTemplate( passTemplate, masterNode, m_UnlitPassForwardDepthOnly, mode)); subShader.AppendLines( GetShaderPassFromTemplate( passTemplate, masterNode, m_UnlitPassForwardOnly, mode)); } return subShader.ToString(); }
public static void WorldToTangent(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { if (xform.version <= 1) { // prior to version 2, all transform were normalized, and all transforms were Normal transforms xform.normalize = true; xform.type = ConversionType.Normal; } using (sb.BlockScope()) { string tangentTransform = GenerateTangentTransform(sb, xform.from); switch (xform.type) { case ConversionType.Position: sb.AddLine(outputVariable, " = TransformWorldToTangentDir(", inputValue, " - IN.WorldSpacePosition, ", tangentTransform, ", false);"); break; case ConversionType.Direction: sb.AddLine(outputVariable, " = TransformWorldToTangentDir(", inputValue, ", ", tangentTransform, ", ", xform.NormalizeString(), ");"); break; case ConversionType.Normal: sb.AddLine(outputVariable, " = TransformWorldToTangent(", inputValue, ", ", tangentTransform, ", ", xform.NormalizeString(), ");"); break; } } }
public static void TangentToWorld(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { // prior to version 2 all transforms were Normal, and directional transforms were normalized if (xform.version <= 1) { if (xform.type != ConversionType.Position) { xform.normalize = true; } xform.type = ConversionType.Normal; } using (sb.BlockScope()) { string tangentTransform = GenerateTangentTransform(sb, CoordinateSpace.World); switch (xform.type) { case ConversionType.Position: sb.AddLine(outputVariable, " = TransformTangentToWorldDir(", inputValue, ", ", tangentTransform, ", false).xyz + IN.WorldSpacePosition;"); break; case ConversionType.Direction: sb.AddLine(outputVariable, " = TransformTangentToWorldDir(", inputValue, ", ", tangentTransform, ", ", xform.NormalizeString(), ").xyz;"); break; case ConversionType.Normal: sb.AddLine(outputVariable, " = TransformTangentToWorld(", inputValue, ", ", tangentTransform, ", ", xform.NormalizeString(), ");"); break; } } }
internal override string GetPropertyDeclarationString(string delimiter = ";") { ShaderStringBuilder s = new ShaderStringBuilder(); s.AppendLine("Gradient {0}_Definition()", referenceName); using (s.BlockScope()) { string[] colors = new string[8]; for (int i = 0; i < colors.Length; i++) { colors[i] = string.Format("g.colors[{0}] = {1}4(0, 0, 0, 0);", i, concretePrecision.ToShaderString()); } for (int i = 0; i < value.colorKeys.Length; i++) { colors[i] = string.Format("g.colors[{0}] = {1}4({2}, {3}, {4}, {5});" , i , concretePrecision.ToShaderString() , NodeUtils.FloatToShaderValue(value.colorKeys[i].color.r) , NodeUtils.FloatToShaderValue(value.colorKeys[i].color.g) , NodeUtils.FloatToShaderValue(value.colorKeys[i].color.b) , NodeUtils.FloatToShaderValue(value.colorKeys[i].time)); } string[] alphas = new string[8]; for (int i = 0; i < alphas.Length; i++) { alphas[i] = string.Format("g.alphas[{0}] = {1}2(0, 0);", i, concretePrecision.ToShaderString()); } for (int i = 0; i < value.alphaKeys.Length; i++) { alphas[i] = string.Format("g.alphas[{0}] = {1}2({2}, {3});" , i , concretePrecision.ToShaderString() , NodeUtils.FloatToShaderValue(value.alphaKeys[i].alpha) , NodeUtils.FloatToShaderValue(value.alphaKeys[i].time)); } s.AppendLine("Gradient g;"); s.AppendLine("g.type = {0};", (int)value.mode); s.AppendLine("g.colorsLength = {0};", value.colorKeys.Length); s.AppendLine("g.alphasLength = {0};", value.alphaKeys.Length); for (int i = 0; i < colors.Length; i++) { s.AppendLine(colors[i]); } for (int i = 0; i < alphas.Length; i++) { s.AppendLine(alphas[i]); } s.AppendLine("return g;", true); } s.AppendIndentation(); s.Append("#define {0} {0}_Definition()", referenceName); return(s.ToString()); }
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) { var sb = new ShaderStringBuilder(); sb.AppendLine("void {0}({1} Texture, {2} Sampler, {3} UV, {4} Offset, {5} Strength, out {6} Out)", GetFunctionName(), FindInputSlot <MaterialSlot>(TextureInputId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(SamplerInputId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(UVInputId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(OffsetInputId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(StrengthInputId).concreteValueType.ToString(precision), FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision)); using (sb.BlockScope()) { sb.AppendLine("Offset = pow(Offset, 3) * 0.1;"); sb.AppendLine("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision); sb.AppendLine("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision); sb.AppendLine("{0} normalSample = Texture.Sample(Sampler, UV).x;", precision); sb.AppendLine("{0} uSample = Texture.Sample(Sampler, offsetU).x;", precision); sb.AppendLine("{0} vSample = Texture.Sample(Sampler, offsetV).x;", precision); sb.AppendLine("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision); sb.AppendLine("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision); sb.AppendLine("Out = normalize(cross(va, vb));"); } visitor.AddShaderChunk(sb.ToString(), true); }
public void GetTags(ShaderStringBuilder builder) { builder.AppendLine("Tags"); using (builder.BlockScope()) { builder.AppendLine("\"RenderType\"=\"{0}\"", renderType); builder.AppendLine("\"Queue\"=\"{0}\"", renderQueue); } }
public override string GetPropertyDeclarationString(string delimiter = ";") { ShaderStringBuilder s = new ShaderStringBuilder(); s.AppendLine("Gradient {0}_Definition()", referenceName); using (s.BlockScope()) { string[] colors = new string[8]; for (int i = 0; i < colors.Length; i++) { colors[i] = string.Format("g.colors[{0}] = float4(0, 0, 0, 0);", i); } for (int i = 0; i < value.colorKeys.Length; i++) { colors[i] = string.Format("g.colors[{0}] = float4({1}, {2}, {3}, {4});" , i , value.colorKeys[i].color.r , value.colorKeys[i].color.g , value.colorKeys[i].color.b , value.colorKeys[i].time); } string[] alphas = new string[8]; for (int i = 0; i < alphas.Length; i++) { alphas[i] = string.Format("g.alphas[{0}] = float2(0, 0);", i); } for (int i = 0; i < value.alphaKeys.Length; i++) { alphas[i] = string.Format("g.alphas[{0}] = float2({1}, {2});" , i , value.alphaKeys[i].alpha , value.alphaKeys[i].time); } s.AppendLine("Gradient g;"); s.AppendLine("g.type = {0};", (int)value.mode); s.AppendLine("g.colorsLength = {0};", value.colorKeys.Length); s.AppendLine("g.alphasLength = {0};", value.alphaKeys.Length); for (int i = 0; i < colors.Length; i++) { s.AppendLine(colors[i]); } for (int i = 0; i < alphas.Length; i++) { s.AppendLine(alphas[i]); } s.AppendLine("return g;", true); } s.AppendLine("#define {0} {0}_Definition()", referenceName); return(s.ToString()); }
public static string ToShaderString(this StencilDescriptor descriptor) { ShaderStringBuilder builder = new ShaderStringBuilder(); builder.AppendLine("Stencil"); using (builder.BlockScope()) { string compBack = descriptor.CompBack != null && descriptor.CompBack.Length > 0 ? descriptor.CompBack : descriptor.Comp; string zFailBack = descriptor.ZFailBack != null && descriptor.ZFailBack.Length > 0 ? descriptor.ZFailBack : descriptor.ZFail; string failBack = descriptor.FailBack != null && descriptor.FailBack.Length > 0 ? descriptor.FailBack : descriptor.Fail; string passBack = descriptor.PassBack != null && descriptor.PassBack.Length > 0 ? descriptor.PassBack : descriptor.Pass; if (descriptor.WriteMask != null && descriptor.WriteMask.Length > 0) { builder.AppendLine($"WriteMask {descriptor.WriteMask}"); } if (descriptor.Ref != null && descriptor.Ref.Length > 0) { builder.AppendLine($"Ref {descriptor.Ref}"); } if (descriptor.Comp != null && descriptor.Comp.Length > 0) { builder.AppendLine($"CompFront {descriptor.Comp}"); } if (descriptor.ZFail != null && descriptor.ZFail.Length > 0) { builder.AppendLine($"ZFailFront {descriptor.ZFail}"); } if (descriptor.Fail != null && descriptor.Fail.Length > 0) { builder.AppendLine($"FailFront {descriptor.Fail}"); } if (descriptor.Pass != null && descriptor.Pass.Length > 0) { builder.AppendLine($"PassFront {descriptor.Pass}"); } if (compBack != null && compBack.Length > 0) { builder.AppendLine($"CompBack {compBack}"); } if (zFailBack != null && zFailBack.Length > 0) { builder.AppendLine($"ZFailBack {zFailBack}"); } if (failBack != null && failBack.Length > 0) { builder.AppendLine($"FailBack {failBack}"); } if (passBack != null && passBack.Length > 0) { builder.AppendLine($"PassBack {passBack}"); } } return(builder.ToCodeBlock()); }
public string GetShader(GenerationMode mode, string outputName, out List <PropertyCollector.TextureInfo> configuredTextures) { var activeNodeList = ListPool <INode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this); var shaderProperties = new PropertyCollector(); var abstractMaterialGraph = owner as AbstractMaterialGraph; if (abstractMaterialGraph != null) { abstractMaterialGraph.CollectShaderProperties(shaderProperties, mode); } foreach (var activeNode in activeNodeList.OfType <AbstractMaterialNode>()) { activeNode.CollectShaderProperties(shaderProperties, mode); } var finalShader = new ShaderStringBuilder(); finalShader.AppendLine(@"Shader ""{0}""", outputName); using (finalShader.BlockScope()) { finalShader.AppendLine("Properties"); using (finalShader.BlockScope()) { finalShader.AppendLine(shaderProperties.GetPropertiesBlock(0)); } foreach (var subShader in m_SubShaders) { finalShader.AppendLines(subShader.GetSubshader(this, mode)); } finalShader.AppendLine(@"FallBack ""Hidden/InternalErrorShader"""); } configuredTextures = shaderProperties.GetConfiguredTexutres(); return(finalShader.ToString()); }
public void GetTags(ShaderStringBuilder builder, string pipeline) { builder.AppendLine("Tags"); using (builder.BlockScope()) { builder.AppendLine("\"RenderPipeline\"=\"{0}\"", pipeline); builder.AppendLine("\"RenderType\"=\"{0}\"", renderType); string seperator = renderQueueOffset >= 0 ? "+" : ""; builder.AppendLine("\"Queue\"=\"{0}{1}{2}\"", renderQueue, seperator, renderQueueOffset); } }
private void GenCopyFunc(string funcName, string dstType, string srcType, ShaderStringBuilder builder, string makeDefine = "") { builder.AppendLine($"{dstType} {funcName}(inout {dstType} output, {srcType} input)"); using (builder.BlockScope()) { GenCopyBlock("output", "input", builder); builder.AppendLine("return output;"); } if (makeDefine != null && makeDefine != "") { builder.AppendLine($"#define {makeDefine}"); } }
public static void GenerateVertexDescriptionFunction( GraphData graph, ShaderStringBuilder builder, FunctionRegistry functionRegistry, PropertyCollector shaderProperties, KeywordCollector shaderKeywords, GenerationMode mode, AbstractMaterialNode rootNode, List <AbstractMaterialNode> nodes, List <int>[] keywordPermutationsPerNode, List <MaterialSlot> slots, string graphInputStructName = "VertexDescriptionInputs", string functionName = "PopulateVertexData", string graphOutputStructName = k_VertexDescriptionStructName) { if (graph == null) { return; } graph.CollectShaderProperties(shaderProperties, mode); builder.AppendLine("{0} {1}({2} IN)", graphOutputStructName, functionName, graphInputStructName); using (builder.BlockScope()) { builder.AppendLine("{0} description = ({0})0;", graphOutputStructName); for (int i = 0; i < nodes.Count; i++) { GenerateDescriptionForNode(nodes[i], keywordPermutationsPerNode[i], functionRegistry, builder, shaderProperties, shaderKeywords, graph, mode); } functionRegistry.builder.currentNode = null; builder.currentNode = null; if (slots.Count != 0) { foreach (var slot in slots) { var isSlotConnected = slot.owner.owner.GetEdges(slot.slotReference).Any(); var slotName = NodeUtils.GetHLSLSafeName(slot.shaderOutputName); var slotValue = isSlotConnected ? ((AbstractMaterialNode)slot.owner).GetSlotValue(slot.id, mode, slot.owner.concretePrecision) : slot.GetDefaultValue(mode, slot.owner.concretePrecision); builder.AppendLine("description.{0} = {1};", slotName, slotValue); } } builder.AppendLine("return description;"); } }
public static void GenerateVertexDescriptionFunction( AbstractMaterialGraph graph, ShaderStringBuilder builder, FunctionRegistry functionRegistry, PropertyCollector shaderProperties, GenerationMode mode, List <AbstractMaterialNode> nodes, List <MaterialSlot> slots, string graphInputStructName = "VertexDescriptionInputs") { if (graph == null) { return; } GraphContext graphContext = new GraphContext(graphInputStructName); graph.CollectShaderProperties(shaderProperties, mode); builder.AppendLine("{0} PopulateVertexData(VertexDescriptionInputs IN)", k_VertexDescriptionStructName); using (builder.BlockScope()) { ShaderGenerator sg = new ShaderGenerator(); builder.AppendLine("{0} description = ({0})0;", k_VertexDescriptionStructName); foreach (var node in nodes) { var generatesFunction = node as IGeneratesFunction; if (generatesFunction != null) { functionRegistry.builder.currentNode = node; generatesFunction.GenerateNodeFunction(functionRegistry, graphContext, mode); } var generatesBodyCode = node as IGeneratesBodyCode; if (generatesBodyCode != null) { generatesBodyCode.GenerateNodeCode(sg, mode); } node.CollectShaderProperties(shaderProperties, mode); } builder.AppendLines(sg.GetShaderString(0)); foreach (var slot in slots) { var isSlotConnected = slot.owner.owner.GetEdges(slot.slotReference).Any(); var slotName = NodeUtils.GetHLSLSafeName(slot.shaderOutputName); var slotValue = isSlotConnected ? ((AbstractMaterialNode)slot.owner).GetSlotValue(slot.id, mode) : slot.GetDefaultValue(mode); builder.AppendLine("description.{0} = {1};", slotName, slotValue); } builder.AppendLine("return description;"); } }
public static string ToShaderString(this StencilDescriptor descriptor) { ShaderStringBuilder builder = new ShaderStringBuilder(); builder.AppendLine("Stencil"); using (builder.BlockScope()) { builder.AppendLine($"WriteMask {descriptor.WriteMask}"); builder.AppendLine($"Ref {descriptor.Ref}"); builder.AppendLine($"Comp {descriptor.Comp}"); builder.AppendLine($"Pass {descriptor.Pass}"); } return(builder.ToCodeBlock()); }
public void GenerateNodeFunction(ShaderGenerator visitor, GraphContext graphContext, GenerationMode generationMode) { var sb = new ShaderStringBuilder(); sb.AppendLine("void {0}({1} In, {2} Flip, out {3} Out)", GetFunctionName(), FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType.ToString(precision), FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision)); using (sb.BlockScope()) { sb.AppendLine("Out = (Flip * -2 + 1) * In;"); } visitor.AddShaderChunk(sb.ToString(), true); }
public string GetShader(GenerationMode mode, string outputName, out List <PropertyCollector.TextureInfo> configuredTextures, List <string> sourceAssetDependencyPaths = null) { var activeNodeList = ListPool <AbstractMaterialNode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this); var shaderProperties = new PropertyCollector(); var shaderKeywords = new KeywordCollector(); if (owner != null) { owner.CollectShaderProperties(shaderProperties, mode); owner.CollectShaderKeywords(shaderKeywords, mode); } if (owner.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit) { owner.AddValidationError(tempId, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); configuredTextures = shaderProperties.GetConfiguredTexutres(); return(ShaderGraphImporter.k_ErrorShader); } foreach (var activeNode in activeNodeList.OfType <AbstractMaterialNode>()) { activeNode.CollectShaderProperties(shaderProperties, mode); } var finalShader = new ShaderStringBuilder(); finalShader.AppendLine(@"Shader ""{0}""", outputName); using (finalShader.BlockScope()) { GraphUtil.GeneratePropertiesBlock(finalShader, shaderProperties, shaderKeywords, mode); foreach (var subShader in m_SubShaders) { if (mode != GenerationMode.Preview || subShader.IsPipelineCompatible(GraphicsSettings.renderPipelineAsset)) { finalShader.AppendLines(subShader.GetSubshader(this, mode, sourceAssetDependencyPaths)); } } finalShader.AppendLine(@"FallBack ""Hidden/InternalErrorShader"""); } configuredTextures = shaderProperties.GetConfiguredTexutres(); return(finalShader.ToString()); }
public static void GenerateSurfaceDescriptionFunction( List <AbstractMaterialNode> nodes, List <int>[] keywordPermutationsPerNode, AbstractMaterialNode rootNode, GraphData graph, ShaderStringBuilder surfaceDescriptionFunction, FunctionRegistry functionRegistry, PropertyCollector shaderProperties, KeywordCollector shaderKeywords, GenerationMode mode, string functionName = "PopulateSurfaceData", string surfaceDescriptionName = "SurfaceDescription", Vector1ShaderProperty outputIdProperty = null, IEnumerable <MaterialSlot> slots = null, string graphInputStructName = "SurfaceDescriptionInputs") { if (graph == null) { return; } graph.CollectShaderProperties(shaderProperties, mode); surfaceDescriptionFunction.AppendLine(String.Format("{0} {1}(SurfaceDescriptionInputs IN)", surfaceDescriptionName, functionName), false); using (surfaceDescriptionFunction.BlockScope()) { surfaceDescriptionFunction.AppendLine("{0} surface = ({0})0;", surfaceDescriptionName); for (int i = 0; i < nodes.Count; i++) { GenerateDescriptionForNode(nodes[i], keywordPermutationsPerNode[i], functionRegistry, surfaceDescriptionFunction, shaderProperties, shaderKeywords, graph, mode); } functionRegistry.builder.currentNode = null; surfaceDescriptionFunction.currentNode = null; GenerateSurfaceDescriptionRemap(graph, rootNode, slots, surfaceDescriptionFunction, mode); surfaceDescriptionFunction.AppendLine("return surface;"); } }
void AppendVtParameters(ShaderStringBuilder sb, string uvExpr, string lodExpr, string dxExpr, string dyExpr, AddressMode address, FilterMode filter, LodCalculation lod, UvSpace space, QualityMode quality) { sb.AppendLine("VtInputParameters vtParams;"); sb.AppendLine("vtParams.uv = " + uvExpr + ";"); sb.AppendLine("vtParams.lodOrOffset = " + lodExpr + ";"); sb.AppendLine("vtParams.dx = " + dxExpr + ";"); sb.AppendLine("vtParams.dy = " + dyExpr + ";"); sb.AppendLine("vtParams.addressMode = " + address + ";"); sb.AppendLine("vtParams.filterMode = " + filter + ";"); sb.AppendLine("vtParams.levelMode = " + lod + ";"); sb.AppendLine("vtParams.uvMode = " + space + ";"); sb.AppendLine("vtParams.sampleQuality = " + quality + ";"); sb.AppendLine("#if defined(SHADER_STAGE_RAY_TRACING)"); sb.AppendLine("if (vtParams.levelMode == VtLevel_Automatic || vtParams.levelMode == VtLevel_Bias)"); using (sb.BlockScope()) { sb.AppendLine("vtParams.levelMode = VtLevel_Lod;"); sb.AppendLine("vtParams.lodOrOffset = 0.0f;"); } sb.AppendLine("#endif"); }
public static void GeneratePropertiesBlock(ShaderStringBuilder sb, PropertyCollector propertyCollector, KeywordCollector keywordCollector, GenerationMode mode) { sb.AppendLine("Properties"); using (sb.BlockScope()) { foreach (var prop in propertyCollector.properties.Where(x => x.generatePropertyBlock)) { sb.AppendLine(prop.GetPropertyBlockString()); } // Keywords use hardcoded state in preview // Do not add them to the Property Block if (mode == GenerationMode.Preview) { return; } foreach (var key in keywordCollector.keywords.Where(x => x.generatePropertyBlock)) { sb.AppendLine(key.GetPropertyBlockString()); } } }
public override string GetPropertyDeclarationString(string delimiter = ";") { if (m_OverrideMembers) { ShaderStringBuilder s = new ShaderStringBuilder(); s.AppendLine("Gradient Unity{0} ()", referenceName); using (s.BlockScope()) { s.AppendLine("Gradient g;"); s.AppendLine("g.type = {0}_Type;", m_OverrideSlotName); s.AppendLine("g.colorsLength = {0}_ColorsLength;", m_OverrideSlotName); s.AppendLine("g.alphasLength = {0}_AlphasLength;", m_OverrideSlotName); for (int i = 0; i < 8; i++) { s.AppendLine("g.colors[{0}] = {1}_ColorKey{0};", i, m_OverrideSlotName); } for (int i = 0; i < 8; i++) { s.AppendLine("g.alphas[{0}] = {1}_AlphaKey{0};", i, m_OverrideSlotName); } s.AppendLine("return g;", true); } return(s.ToString()); } else { ShaderStringBuilder s = new ShaderStringBuilder(); s.AppendLine("Gradient Unity{0} ()", referenceName); using (s.BlockScope()) { GradientUtils.GetGradientDeclaration(value, ref s); s.AppendLine("return g;", true); } return(s.ToString()); } }
// TODO: could get rid of this if we could run a codegen prepass (with proper keyword #ifdef) public static void GenerateVirtualTextureFeedback( List <AbstractMaterialNode> downstreamNodesIncludingRoot, List <int>[] keywordPermutationsPerNode, ShaderStringBuilder surfaceDescriptionFunction, KeywordCollector shaderKeywords) { // A note on how we handle vt feedback in combination with keywords: // We essentially generate a fully separate feedback path for each permutation of keywords // so per permutation we gather variables contribution to feedback and we generate // feedback gathering for each permutation individually. var feedbackVariablesPerPermutation = PooledList <PooledList <string> > .Get(); try { if (shaderKeywords.permutations.Count >= 1) { for (int i = 0; i < shaderKeywords.permutations.Count; i++) { feedbackVariablesPerPermutation.Add(PooledList <string> .Get()); } } else { // Create a dummy single permutation feedbackVariablesPerPermutation.Add(PooledList <string> .Get()); } int index = 0; //for keywordPermutationsPerNode foreach (var node in downstreamNodesIncludingRoot) { if (node is SampleVirtualTextureNode vtNode) { if (vtNode.noFeedback) { continue; } if (keywordPermutationsPerNode[index] == null) { Debug.Assert(shaderKeywords.permutations.Count == 0, $"Shader has {shaderKeywords.permutations.Count} permutations but keywordPermutationsPerNode of some nodes are null."); feedbackVariablesPerPermutation[0].Add(vtNode.GetFeedbackVariableName()); } else { foreach (int perm in keywordPermutationsPerNode[index]) { feedbackVariablesPerPermutation[perm].Add(vtNode.GetFeedbackVariableName()); } } } if (node is SubGraphNode sgNode) { if (sgNode.asset == null) { continue; } if (keywordPermutationsPerNode[index] == null) { Debug.Assert(shaderKeywords.permutations.Count == 0, $"Shader has {shaderKeywords.permutations.Count} permutations but keywordPermutationsPerNode of some nodes are null."); foreach (var feedbackSlot in sgNode.asset.vtFeedbackVariables) { feedbackVariablesPerPermutation[0].Add(node.GetVariableNameForNode() + "_" + feedbackSlot); } } else { foreach (var feedbackSlot in sgNode.asset.vtFeedbackVariables) { foreach (int perm in keywordPermutationsPerNode[index]) { feedbackVariablesPerPermutation[perm].Add(node.GetVariableNameForNode() + "_" + feedbackSlot); } } } } index++; } index = 0; foreach (var feedbackVariables in feedbackVariablesPerPermutation) { // If it's a dummy single always-on permutation don't put an ifdef around the code if (shaderKeywords.permutations.Count >= 1) { surfaceDescriptionFunction.AppendLine(KeywordUtil.GetKeywordPermutationConditional(index)); } using (surfaceDescriptionFunction.BlockScope()) { if (feedbackVariables.Count == 0) { string feedBackCode = "surface.VTPackedFeedback = float4(1.0f,1.0f,1.0f,1.0f);"; surfaceDescriptionFunction.AppendLine(feedBackCode); } else if (feedbackVariables.Count == 1) { string feedBackCode = "surface.VTPackedFeedback = GetPackedVTFeedback(" + feedbackVariables[0] + ");"; surfaceDescriptionFunction.AppendLine(feedBackCode); } else if (feedbackVariables.Count > 1) { surfaceDescriptionFunction.AppendLine("float4 VTFeedback_array[" + feedbackVariables.Count + "];"); int arrayIndex = 0; foreach (var variable in feedbackVariables) { surfaceDescriptionFunction.AppendLine("VTFeedback_array[" + arrayIndex + "] = " + variable + ";"); arrayIndex++; } // TODO: should read from NDCPosition instead... surfaceDescriptionFunction.AppendLine("uint pixelColumn = (IN.ScreenPosition.x / IN.ScreenPosition.w) * _ScreenParams.x;"); surfaceDescriptionFunction.AppendLine( "surface.VTPackedFeedback = GetPackedVTFeedback(VTFeedback_array[(pixelColumn + _FrameCount) % (uint)" + feedbackVariables.Count + "]);"); } } if (shaderKeywords.permutations.Count >= 1) { surfaceDescriptionFunction.AppendLine("#endif"); } index++; } } finally { foreach (var list in feedbackVariablesPerPermutation) { list.Dispose(); } feedbackVariablesPerPermutation.Dispose(); } }
private static void ViaWorld(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { // should never be calling this if one of the spaces is already world space (silly, and could lead to infinite recursions) if ((xform.from == CoordinateSpace.World) || (xform.to == CoordinateSpace.World)) { return; } // this breaks the transform into two parts: (from->world) and (world->to) var toWorld = new SpaceTransform() { from = xform.from, to = CoordinateSpace.World, type = xform.type, normalize = false, version = xform.version }; var fromWorld = new SpaceTransform() { from = CoordinateSpace.World, to = xform.to, type = xform.type, normalize = xform.normalize, version = xform.version }; // Apply Versioning Hacks to match old (incorrect) versions if (xform.version <= 1) { if (xform.type == ConversionType.Direction) { switch (xform.from) { case CoordinateSpace.AbsoluteWorld: if ((xform.to == CoordinateSpace.Object) || (xform.to == CoordinateSpace.View)) { // these transforms were wrong in v0, but correct in v1, so here we // pretend it is a later version to disable the v1 versioning in the AbsWorldToWorld transform if (xform.version == 1) { toWorld.version = 2; } } break; case CoordinateSpace.View: if ((xform.to == CoordinateSpace.Tangent) || (xform.to == CoordinateSpace.AbsoluteWorld)) { // these transforms erroneously used the position view-to-world transform toWorld.type = ConversionType.Position; } break; case CoordinateSpace.Tangent: if ((xform.to == CoordinateSpace.Object) || (xform.to == CoordinateSpace.View) || (xform.to == CoordinateSpace.AbsoluteWorld)) { // manually version to 2, to remove normalization (while keeping Normal type) toWorld.type = ConversionType.Normal; toWorld.version = 2; } break; } } } using (sb.BlockScope()) { sb.AddLine("// Converting ", xform.type.ToString(), " from ", xform.from.ToString(), " to ", xform.to.ToString(), " via world space"); sb.AddLine("float3 world;"); GenerateTransformCodeStatement(toWorld, inputValue, "world", sb); GenerateTransformCodeStatement(fromWorld, "world", outputVariable, sb); } }
public static void GenerateSurfaceDescriptionFunction( List <INode> activeNodeList, AbstractMaterialNode masterNode, AbstractMaterialGraph graph, ShaderStringBuilder surfaceDescriptionFunction, FunctionRegistry functionRegistry, PropertyCollector shaderProperties, ShaderGraphRequirements requirements, GenerationMode mode, string functionName = "PopulateSurfaceData", string surfaceDescriptionName = "SurfaceDescription", Vector1ShaderProperty outputIdProperty = null, IEnumerable <MaterialSlot> slots = null, string graphInputStructName = "SurfaceDescriptionInputs") { if (graph == null) { return; } GraphContext graphContext = new GraphContext(graphInputStructName); graph.CollectShaderProperties(shaderProperties, mode); surfaceDescriptionFunction.AppendLine(String.Format("{0} {1}(SurfaceDescriptionInputs IN)", surfaceDescriptionName, functionName), false); using (surfaceDescriptionFunction.BlockScope()) { ShaderGenerator sg = new ShaderGenerator(); surfaceDescriptionFunction.AppendLine("{0} surface = ({0})0;", surfaceDescriptionName); foreach (var activeNode in activeNodeList.OfType <AbstractMaterialNode>()) { if (activeNode is IGeneratesFunction) { functionRegistry.builder.currentNode = activeNode; (activeNode as IGeneratesFunction).GenerateNodeFunction(functionRegistry, graphContext, mode); } if (activeNode is IGeneratesBodyCode) { (activeNode as IGeneratesBodyCode).GenerateNodeCode(sg, mode); } if (masterNode == null && activeNode.hasPreview) { var outputSlot = activeNode.GetOutputSlots <MaterialSlot>().FirstOrDefault(); if (outputSlot != null) { sg.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); } } // In case of the subgraph output node, the preview is generated // from the first input to the node. if (activeNode is SubGraphOutputNode) { var inputSlot = activeNode.GetInputSlots <MaterialSlot>().FirstOrDefault(); if (inputSlot != null) { var foundEdges = graph.GetEdges(inputSlot.slotReference).ToArray(); string slotValue = foundEdges.Any() ? activeNode.GetSlotValue(inputSlot.id, mode) : inputSlot.GetDefaultValue(mode); sg.AddShaderChunk(String.Format("if ({0} == {1}) {{ surface.PreviewOutput = {2}; return surface; }}", outputIdProperty.referenceName, activeNode.tempId.index, slotValue), false); } } activeNode.CollectShaderProperties(shaderProperties, mode); } surfaceDescriptionFunction.AppendLines(sg.GetShaderString(0)); 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()) { surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), masterNode.GetSlotValue(input.id, mode)); } else { surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode)); } } } else if (masterNode.hasPreview) { foreach (var slot in masterNode.GetOutputSlots <MaterialSlot>()) { surfaceDescriptionFunction.AppendLine("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(slot.shaderOutputName), masterNode.GetSlotValue(slot.id, mode)); } } } surfaceDescriptionFunction.AppendLine("return surface;"); } }
public static GenerationResults GetShader(this AbstractMaterialGraph graph, AbstractMaterialNode node, GenerationMode mode, string name) { var results = new GenerationResults(); bool isUber = node == null; var vertexInputs = new ShaderGenerator(); var vertexShader = new ShaderGenerator(); var surfaceDescriptionFunction = new ShaderGenerator(); var surfaceDescriptionStruct = new ShaderGenerator(); var functionBuilder = new ShaderStringBuilder(); var functionRegistry = new FunctionRegistry(functionBuilder); 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 = ShaderGraphRequirements.FromNodes(activeNodeList); GenerateApplicationVertexInputs(requirements, 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); } results.previewMode = PreviewMode.Preview3D; if (!isUber) { foreach (var pNode in activeNodeList.OfType <AbstractMaterialNode>()) { if (pNode.previewMode == PreviewMode.Preview3D) { results.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(); results.outputIdProperty = new Vector1ShaderProperty { displayName = "OutputId", generatePropertyBlock = false, value = -1 }; if (isUber) { shaderProperties.AddShaderProperty(results.outputIdProperty); } GenerateSurfaceDescription( activeNodeList, node, graph, surfaceDescriptionFunction, functionRegistry, shaderProperties, requirements, mode, outputIdProperty: results.outputIdProperty); var finalBuilder = new ShaderStringBuilder(); finalBuilder.AppendLine(@"Shader ""{0}""", name); using (finalBuilder.BlockScope()) { finalBuilder.AppendLine("Properties"); using (finalBuilder.BlockScope()) { finalBuilder.AppendLines(shaderProperties.GetPropertiesBlock(0)); } finalBuilder.AppendLine(@"HLSLINCLUDE"); finalBuilder.AppendLine("#define USE_LEGACY_UNITY_MATRIX_VARIABLES"); finalBuilder.AppendLine(@"#include ""CoreRP/ShaderLibrary/Common.hlsl"""); finalBuilder.AppendLine(@"#include ""CoreRP/ShaderLibrary/Packing.hlsl"""); finalBuilder.AppendLine(@"#include ""CoreRP/ShaderLibrary/Color.hlsl"""); finalBuilder.AppendLine(@"#include ""CoreRP/ShaderLibrary/UnityInstancing.hlsl"""); finalBuilder.AppendLine(@"#include ""CoreRP/ShaderLibrary/EntityLighting.hlsl"""); finalBuilder.AppendLine(@"#include ""ShaderGraphLibrary/ShaderVariables.hlsl"""); finalBuilder.AppendLine(@"#include ""ShaderGraphLibrary/ShaderVariablesFunctions.hlsl"""); finalBuilder.AppendLine(@"#include ""ShaderGraphLibrary/Functions.hlsl"""); finalBuilder.AppendLines(shaderProperties.GetPropertiesDeclaration(0)); finalBuilder.AppendLines(surfaceInputs.GetShaderString(0)); finalBuilder.Concat(functionBuilder); finalBuilder.AppendLines(vertexInputs.GetShaderString(0)); finalBuilder.AppendLines(surfaceDescriptionStruct.GetShaderString(0)); finalBuilder.AppendLines(vertexShader.GetShaderString(0)); finalBuilder.AppendLines(surfaceDescriptionFunction.GetShaderString(0)); finalBuilder.AppendLine(@"ENDHLSL"); finalBuilder.AppendLines(ShaderGenerator.GetPreviewSubShader(node, requirements)); ListPool <INode> .Release(activeNodeList); } results.configuredTextures = shaderProperties.GetConfiguredTexutres(); ShaderSourceMap sourceMap; results.shader = finalBuilder.ToString(out sourceMap); results.sourceMap = sourceMap; return(results); }
public static GenerationResults GetShader(this GraphData graph, AbstractMaterialNode node, GenerationMode mode, string name) { // ----------------------------------------------------- // // SETUP // // ----------------------------------------------------- // // ------------------------------------- // String builders var finalShader = new ShaderStringBuilder(); var results = new GenerationResults(); var shaderProperties = new PropertyCollector(); var shaderKeywords = new KeywordCollector(); var shaderPropertyUniforms = new ShaderStringBuilder(); var shaderKeywordDeclarations = new ShaderStringBuilder(); var shaderKeywordPermutations = new ShaderStringBuilder(1); var functionBuilder = new ShaderStringBuilder(); var functionRegistry = new FunctionRegistry(functionBuilder); var vertexDescriptionFunction = new ShaderStringBuilder(0); var surfaceDescriptionInputStruct = new ShaderStringBuilder(0); var surfaceDescriptionStruct = new ShaderStringBuilder(0); var surfaceDescriptionFunction = new ShaderStringBuilder(0); var vertexInputs = new ShaderStringBuilder(0); graph.CollectShaderKeywords(shaderKeywords, mode); if (graph.GetKeywordPermutationCount() > ShaderGraphPreferences.variantLimit) { graph.AddValidationError(node.tempId, ShaderKeyword.kVariantLimitWarning, Rendering.ShaderCompilerMessageSeverity.Error); results.configuredTextures = shaderProperties.GetConfiguredTexutres(); results.shader = string.Empty; return(results); } // ------------------------------------- // Get Slot and Node lists var activeNodeList = ListPool <AbstractMaterialNode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node); var slots = new List <MaterialSlot>(); if (node is IMasterNode || node is SubGraphOutputNode) { slots.AddRange(node.GetInputSlots <MaterialSlot>()); } else { var outputSlots = node.GetOutputSlots <MaterialSlot>().ToList(); if (outputSlots.Count > 0) { slots.Add(outputSlots[0]); } } // ------------------------------------- // Get Requirements var requirements = ShaderGraphRequirements.FromNodes(activeNodeList, ShaderStageCapability.Fragment); // ----------------------------------------------------- // // KEYWORDS // // ----------------------------------------------------- // // ------------------------------------- // Get keyword permutations graph.CollectShaderKeywords(shaderKeywords, mode); // Track permutation indicies for all nodes and requirements List <int>[] keywordPermutationsPerNode = new List <int> [activeNodeList.Count]; // ------------------------------------- // Evaluate all permutations for (int i = 0; i < shaderKeywords.permutations.Count; i++) { // Get active nodes for this permutation var localNodes = ListPool <AbstractMaterialNode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(localNodes, node, keywordPermutation: shaderKeywords.permutations[i]); // Track each pixel node in this permutation foreach (AbstractMaterialNode pixelNode in localNodes) { int nodeIndex = activeNodeList.IndexOf(pixelNode); if (keywordPermutationsPerNode[nodeIndex] == null) { keywordPermutationsPerNode[nodeIndex] = new List <int>(); } keywordPermutationsPerNode[nodeIndex].Add(i); } // Get active requirements for this permutation var localSurfaceRequirements = ShaderGraphRequirements.FromNodes(localNodes, ShaderStageCapability.Fragment, false); var localPixelRequirements = ShaderGraphRequirements.FromNodes(localNodes, ShaderStageCapability.Fragment); } // ----------------------------------------------------- // // START VERTEX DESCRIPTION // // ----------------------------------------------------- // // ------------------------------------- // Generate Vertex Description function vertexDescriptionFunction.AppendLine("GraphVertexInput PopulateVertexData(GraphVertexInput v)"); using (vertexDescriptionFunction.BlockScope()) { vertexDescriptionFunction.AppendLine("return v;"); } // ----------------------------------------------------- // // START SURFACE DESCRIPTION // // ----------------------------------------------------- // // ------------------------------------- // Generate Input structure for Surface Description function // Surface Description Input requirements are needed to exclude intermediate translation spaces GenerateSurfaceInputStruct(surfaceDescriptionInputStruct, requirements, "SurfaceDescriptionInputs"); results.previewMode = PreviewMode.Preview2D; foreach (var pNode in activeNodeList) { if (pNode.previewMode == PreviewMode.Preview3D) { results.previewMode = PreviewMode.Preview3D; break; } } // ------------------------------------- // Generate Output structure for Surface Description function GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, slots, useIdsInNames: !(node is IMasterNode)); // ------------------------------------- // Generate Surface Description function GenerateSurfaceDescriptionFunction( activeNodeList, keywordPermutationsPerNode, node, graph, surfaceDescriptionFunction, functionRegistry, shaderProperties, shaderKeywords, mode, outputIdProperty: results.outputIdProperty); // ----------------------------------------------------- // // GENERATE VERTEX > PIXEL PIPELINE // // ----------------------------------------------------- // // ------------------------------------- // Keyword declarations shaderKeywords.GetKeywordsDeclaration(shaderKeywordDeclarations, mode); // ------------------------------------- // Property uniforms shaderProperties.GetPropertiesDeclaration(shaderPropertyUniforms, mode, graph.concretePrecision); // ------------------------------------- // Generate Input structure for Vertex shader GenerateApplicationVertexInputs(requirements, vertexInputs); // ----------------------------------------------------- // // FINALIZE // // ----------------------------------------------------- // // ------------------------------------- // Build final shader finalShader.AppendLine(@"Shader ""{0}""", name); using (finalShader.BlockScope()) { SubShaderGenerator.GeneratePropertiesBlock(finalShader, shaderProperties, shaderKeywords, mode); finalShader.AppendNewLine(); finalShader.AppendLine(@"HLSLINCLUDE"); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"""); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"""); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"""); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"""); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl"""); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"""); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariables.hlsl"""); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl"""); finalShader.AppendLine(@"#include ""Assets/Scripts/URP/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl"""); finalShader.AppendLines(shaderKeywordDeclarations.ToString()); finalShader.AppendLine(@"#define SHADERGRAPH_PREVIEW 1"); finalShader.AppendNewLine(); finalShader.AppendLines(shaderKeywordPermutations.ToString()); finalShader.AppendLines(shaderPropertyUniforms.ToString()); finalShader.AppendNewLine(); finalShader.AppendLines(surfaceDescriptionInputStruct.ToString()); finalShader.AppendNewLine(); finalShader.Concat(functionBuilder); finalShader.AppendNewLine(); finalShader.AppendLines(surfaceDescriptionStruct.ToString()); finalShader.AppendNewLine(); finalShader.AppendLines(surfaceDescriptionFunction.ToString()); finalShader.AppendNewLine(); finalShader.AppendLines(vertexInputs.ToString()); finalShader.AppendNewLine(); finalShader.AppendLines(vertexDescriptionFunction.ToString()); finalShader.AppendNewLine(); finalShader.AppendLine(@"ENDHLSL"); finalShader.AppendLines(ShaderGenerator.GetPreviewSubShader(node, requirements)); ListPool <AbstractMaterialNode> .Release(activeNodeList); } // ------------------------------------- // Finalize results.configuredTextures = shaderProperties.GetConfiguredTexutres(); ShaderSourceMap sourceMap; results.shader = finalShader.ToString(out sourceMap); results.sourceMap = sourceMap; return(results); }