public void Generate() { this.m_GenerationMode = GenerationMode.GenerateOnly; this.Generate(GenerationMode.GenerateOnly, null); }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // HDLitSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("bac1a9627cfec924fa2ea9c65af8eeca")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as HDLitMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", false); subShader.AddShaderChunk("{", false); subShader.Indent(); { //Handle data migration here as we need to have a renderingPass already set with accurate data at this point. if (masterNode.renderingPass == HDRenderQueue.RenderQueueType.Unknown) { switch (masterNode.surfaceType) { case SurfaceType.Opaque: masterNode.renderingPass = HDRenderQueue.RenderQueueType.Opaque; break; case SurfaceType.Transparent: #pragma warning disable CS0618 // Type or member is obsolete if (masterNode.m_DrawBeforeRefraction) { masterNode.m_DrawBeforeRefraction = false; #pragma warning restore CS0618 // Type or member is obsolete masterNode.renderingPass = HDRenderQueue.RenderQueueType.PreRefraction; } else { masterNode.renderingPass = HDRenderQueue.RenderQueueType.Transparent; } break; default: throw new System.ArgumentException("Unknown SurfaceType"); } } HDMaterialTags materialTags = HDSubShaderUtilities.BuildMaterialTags(masterNode.renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn); // Add tags at the SubShader level { var tagsVisitor = new ShaderStringBuilder(); materialTags.GetTags(tagsVisitor, HDRenderPipeline.k_ShaderTagName); subShader.AddShaderChunk(tagsVisitor.ToString(), false); } // generate the necessary shader passes bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; bool distortionActive = transparent && masterNode.distortion.isOn; bool transparentBackfaceActive = transparent && masterNode.backThenFrontRendering.isOn; bool transparentDepthPrepassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPrepass.isOn; bool transparentDepthPostpassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPostpass.isOn; GenerateShaderPassLit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); if (opaque) { GenerateShaderPassLit(masterNode, m_PassDepthOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassGBuffer, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); } if (distortionActive) { GenerateShaderPassLit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths); } if (transparentBackfaceActive) { GenerateShaderPassLit(masterNode, m_PassTransparentBackface, mode, subShader, sourceAssetDependencyPaths); } // Assign define here based on opaque or transparent to save some variant m_PassForward.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent; GenerateShaderPassLit(masterNode, m_PassForward, mode, subShader, sourceAssetDependencyPaths); if (transparentDepthPrepassActive) { GenerateShaderPassLit(masterNode, m_PassTransparentDepthPrepass, mode, subShader, sourceAssetDependencyPaths); } if (transparentDepthPostpassActive) { GenerateShaderPassLit(masterNode, m_PassTransparentDepthPostpass, mode, subShader, sourceAssetDependencyPaths); } } subShader.Deindent(); subShader.AddShaderChunk("}", false); #if ENABLE_RAYTRACING if (mode == GenerationMode.ForReals) { subShader.AddShaderChunk("SubShader", false); subShader.AddShaderChunk("{", false); subShader.Indent(); { GenerateShaderPassLit(masterNode, m_PassRaytracingReflection, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassRaytracingVisibility, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassRaytracingForward, mode, subShader, sourceAssetDependencyPaths); } subShader.Deindent(); subShader.AddShaderChunk("}", false); } #endif subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HDLitGUI"""); return(subShader.GetShaderString(0)); }
private static bool GenerateShaderPassHair(HairMasterNode masterNode, Pass pass, GenerationMode mode, ShaderGenerator result, List <string> sourceAssetDependencyPaths) { if (mode == GenerationMode.ForReals || pass.UseInPreview) { SurfaceMaterialOptions materialOptions = HDSubShaderUtilities.BuildMaterialOptions(masterNode.surfaceType, masterNode.alphaMode, masterNode.doubleSidedMode != DoubleSidedMode.Disabled, false); pass.OnGeneratePass(masterNode); // apply master node options to active fields HashSet <string> activeFields = GetActiveFieldsFromMasterNode(masterNode, pass); // use standard shader pass generation bool vertexActive = masterNode.IsSlotConnected(HairMasterNode.PositionSlotId); return(HDSubShaderUtilities.GenerateShaderPass(masterNode, pass, mode, materialOptions, activeFields, result, sourceAssetDependencyPaths, vertexActive)); } else { return(false); } }
static string GetExtraPassesFromTemplate(string template, UnlitMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions) { // ----------------------------------------------------- // // SETUP // // ----------------------------------------------------- // // ------------------------------------- // String builders var dummyBuilder = new ShaderStringBuilder(0); var shaderProperties = new PropertyCollector(); var functionBuilder = new ShaderStringBuilder(1); var functionRegistry = new FunctionRegistry(functionBuilder); var defines = new ShaderStringBuilder(2); var graph = new ShaderStringBuilder(0); var vertexDescriptionInputStruct = new ShaderStringBuilder(1); var vertexDescriptionStruct = new ShaderStringBuilder(1); var vertexDescriptionFunction = new ShaderStringBuilder(1); var vertexInputStruct = new ShaderStringBuilder(1); var vertexShader = new ShaderStringBuilder(2); var vertexDescriptionInputs = new ShaderStringBuilder(2); // ------------------------------------- // Get Slot and Node lists per stage var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot <MaterialSlot>).ToList(); var vertexNodes = ListPool <AbstractMaterialNode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots); // ------------------------------------- // Get requirements var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false); var modelRequiements = ShaderGraphRequirements.none; modelRequiements.requiresNormal |= m_VertexCoordinateSpace; modelRequiements.requiresPosition |= m_VertexCoordinateSpace; modelRequiements.requiresMeshUVs.Add(UVChannel.UV1); // ----------------------------------------------------- // // START SHADER GENERATION // // ----------------------------------------------------- // // ------------------------------------- // Calculate material options var cullingBuilder = new ShaderStringBuilder(1); materialOptions.GetCull(cullingBuilder); // ------------------------------------- // Generate defines if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId)) { defines.AppendLine("#define _AlphaClip 1"); } // ----------------------------------------------------- // // START VERTEX DESCRIPTION // // ----------------------------------------------------- // // ------------------------------------- // Generate Input structure for Vertex Description function // TODO - Vertex Description Input requirements are needed to exclude intermediate translation spaces vertexDescriptionInputStruct.AppendLine("struct VertexDescriptionInputs"); using (vertexDescriptionInputStruct.BlockSemicolonScope()) { ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresNormal, InterpolatorType.Normal, vertexDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresTangent, InterpolatorType.Tangent, vertexDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresBitangent, InterpolatorType.BiTangent, vertexDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresViewDir, InterpolatorType.ViewDirection, vertexDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresPosition, InterpolatorType.Position, vertexDescriptionInputStruct); if (vertexRequirements.requiresVertexColor) { vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor); } if (vertexRequirements.requiresScreenPosition) { vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition); } foreach (var channel in vertexRequirements.requiresMeshUVs.Distinct()) { vertexDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName()); } } // ------------------------------------- // Generate Output structure for Vertex Description function GraphUtil.GenerateVertexDescriptionStruct(vertexDescriptionStruct, vertexSlots); // ------------------------------------- // Generate Vertex Description function GraphUtil.GenerateVertexDescriptionFunction( masterNode.owner as AbstractMaterialGraph, vertexDescriptionFunction, functionRegistry, shaderProperties, mode, vertexNodes, vertexSlots); // ----------------------------------------------------- // // GENERATE VERTEX > PIXEL PIPELINE // // ----------------------------------------------------- // // ------------------------------------- // Generate Input structure for Vertex shader GraphUtil.GenerateApplicationVertexInputs(vertexRequirements.Union(modelRequiements), vertexInputStruct); // ------------------------------------- // Generate standard transformations // This method ensures all required transform data is available in vertex and pixel stages ShaderGenerator.GenerateStandardTransforms( 3, 10, dummyBuilder, vertexShader, vertexDescriptionInputs, dummyBuilder, dummyBuilder, dummyBuilder, ShaderGraphRequirements.none, ShaderGraphRequirements.none, modelRequiements, vertexRequirements, CoordinateSpace.World); // ----------------------------------------------------- // // FINALIZE // // ----------------------------------------------------- // // ------------------------------------- // Combine Graph sections graph.AppendLine(shaderProperties.GetPropertiesDeclaration(1)); graph.AppendLine(vertexDescriptionInputStruct.ToString()); graph.AppendLine(functionBuilder.ToString()); graph.AppendLine(vertexDescriptionStruct.ToString()); graph.AppendLine(vertexDescriptionFunction.ToString()); graph.AppendLine(vertexInputStruct.ToString()); // ------------------------------------- // Generate final subshader var resultPass = template.Replace("${Culling}", cullingBuilder.ToString()); resultPass = resultPass.Replace("${Defines}", defines.ToString()); resultPass = resultPass.Replace("${Graph}", graph.ToString()); resultPass = resultPass.Replace("${VertexShader}", vertexShader.ToString()); resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexDescriptionInputs.ToString()); return(resultPass); }
private static bool GenerateShaderPassEye(EyeMasterNode masterNode, Pass pass, GenerationMode mode, ShaderGenerator result, List <string> sourceAssetDependencyPaths) { if (mode == GenerationMode.ForReals || pass.UseInPreview) { pass.OnGeneratePass(masterNode); // apply master node options to active fields var activeFields = GetActiveFieldsFromMasterNode(masterNode, pass); // use standard shader pass generation bool vertexActive = false; if (masterNode.IsSlotConnected(EyeMasterNode.PositionSlotId) || masterNode.IsSlotConnected(EyeMasterNode.VertexNormalSlotID) || masterNode.IsSlotConnected(EyeMasterNode.VertexTangentSlotID)) { vertexActive = true; } return(HDSubShaderUtilities.GenerateShaderPass(masterNode, pass, mode, activeFields, result, sourceAssetDependencyPaths, vertexActive)); } else { return(false); } }
public void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode) { registry.ProvideFunction(GetFunctionName(), s => { s.AppendLine("void {0} ({1} UV, {2} Width, {3} Height, {4} Tile, {5}2 Invert, out {6} Out)", GetFunctionName(), FindInputSlot <MaterialSlot>(UVSlotId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(WidthSlotId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(HeightSlotId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(TileSlotId).concreteValueType.ToString(precision), precision, FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision)); using (s.BlockScope()) { s.AppendLine("Tile = fmod(Tile, Width*Height);"); s.AppendLine("{0}2 tileCount = {0}2(1.0, 1.0) / {0}2(Width, Height);", precision); s.AppendLine("{0} tileY = abs(Invert.y * Height - (floor(Tile * tileCount.x) + Invert.y * 1));", precision); s.AppendLine("{0} tileX = abs(Invert.x * Width - ((Tile - Width * floor(Tile * tileCount.x)) + Invert.x * 1));", precision); s.AppendLine("Out = (UV + {0}2(tileX, tileY)) * tileCount;", precision); } }); }
private static bool GenerateShaderPassLit(AbstractMaterialNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List <string> sourceAssetDependencyPaths) { // apply master node options to active fields HashSet <string> activeFields = GetActiveFieldsFromMasterNode(masterNode, pass); // use standard shader pass generation bool vertexActive = masterNode.IsSlotConnected(PBRMasterNode.PositionSlotId); return(HDSubShaderUtilities.GenerateShaderPass(masterNode, pass, mode, materialOptions, activeFields, result, sourceAssetDependencyPaths, vertexActive)); }
public void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode) { if (generationMode == GenerationMode.Preview) { registry.ProvideFunction(GetFunctionName(), s => { s.AppendLine("Gradient {0} ()", GetFunctionName()); using (s.BlockScope()) { s.AppendLine("Gradient g;"); s.AppendLine("g.type = _{0}_Type;", GetVariableNameForNode()); s.AppendLine("g.colorsLength = _{0}_ColorsLength;", GetVariableNameForNode()); s.AppendLine("g.alphasLength = _{0}_AlphasLength;", GetVariableNameForNode()); for (int i = 0; i < 8; i++) { s.AppendLine("g.colors[{0}] = _{1}_ColorKey{0};", i, GetVariableNameForNode()); } for (int i = 0; i < 8; i++) { s.AppendLine("g.alphas[{0}] = _{1}_AlphaKey{0};", i, GetVariableNameForNode()); } s.AppendLine("return g;", true); } }); } else { registry.ProvideFunction(GetFunctionName(), s => { s.AppendLine("Gradient {0} ()", GetFunctionName()); using (s.BlockScope()) { GradientUtils.GetGradientDeclaration(m_Gradient, ref s); s.AppendLine("return g;", true); } }); } }
private static bool GenerateShaderPassLit(HDLitMasterNode masterNode, Pass pass, GenerationMode mode, ShaderGenerator result, List <string> sourceAssetDependencyPaths) { if (mode == GenerationMode.ForReals || pass.UseInPreview) { pass.OnGeneratePass(masterNode); // apply master node options to active fields HashSet <string> activeFields = GetActiveFieldsFromMasterNode(masterNode, pass); pass.ExtraInstancingOptions = GetInstancingOptionsFromMasterNode(masterNode); // use standard shader pass generation bool vertexActive = masterNode.IsSlotConnected(HDLitMasterNode.PositionSlotId); return(HDSubShaderUtilities.GenerateShaderPass(masterNode, pass, mode, activeFields, result, sourceAssetDependencyPaths, vertexActive)); } else { return(false); } }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // HDUnlitSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("1c44ec077faa54145a89357de68e5d26")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as HDUnlitMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { // Add tags at the SubShader level int queue = HDRenderQueue.ChangeType(masterNode.renderingPass, masterNode.sortPriority, masterNode.alphaTest.isOn); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName, HDRenderTypeTags.HDUnlitShader, queue); // For preview only we generate the passes that are enabled bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; bool distortionActive = transparent && masterNode.distortion.isOn; GenerateShaderPassUnlit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassUnlit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); if (distortionActive) { GenerateShaderPassUnlit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths); } GenerateShaderPassUnlit(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths); } subShader.Deindent(); subShader.AddShaderChunk("}", false); if (mode == GenerationMode.ForReals) { subShader.AddShaderChunk("SubShader", false); subShader.AddShaderChunk("{", false); subShader.Indent(); HDSubShaderUtilities.AddTags(subShader, HDRenderPipeline.k_ShaderTagName); { GenerateShaderPassUnlit(masterNode, m_PassRaytracingIndirect, mode, subShader, sourceAssetDependencyPaths, instancingFlag: false); GenerateShaderPassUnlit(masterNode, m_PassRaytracingVisibility, mode, subShader, sourceAssetDependencyPaths, instancingFlag: false); GenerateShaderPassUnlit(masterNode, m_PassRaytracingForward, mode, subShader, sourceAssetDependencyPaths, instancingFlag: false); GenerateShaderPassUnlit(masterNode, m_PassRaytracingGBuffer, mode, subShader, sourceAssetDependencyPaths, instancingFlag: false); GenerateShaderPassUnlit(masterNode, m_PassPathTracing, mode, subShader, sourceAssetDependencyPaths, instancingFlag: false); } subShader.Deindent(); subShader.AddShaderChunk("}", false); } if (!masterNode.OverrideEnabled) { subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Rendering.HighDefinition.HDUnlitGUI"""); } return(subShader.GetShaderString(0)); }
public string GetSubshader(IMasterNode masterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // LightWeightPBRSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("ca91dbeb78daa054c9bbe15fef76361c")); } var templatePath = GetTemplatePath("lightweightPBRForwardPass.template"); var extraPassesTemplatePath = GetTemplatePath("lightweightPBRExtraPasses.template"); var lightweight2DPath = GetTemplatePath("lightweight2DPBRPass.template"); if (!File.Exists(templatePath) || !File.Exists(extraPassesTemplatePath)) { return(string.Empty); } if (sourceAssetDependencyPaths != null) { sourceAssetDependencyPaths.Add(templatePath); sourceAssetDependencyPaths.Add(extraPassesTemplatePath); sourceAssetDependencyPaths.Add(lightweight2DPath); var relativePath = "Packages/com.unity.render-pipelines.lightweight/"; var fullPath = Path.GetFullPath(relativePath); var shaderFiles = Directory.GetFiles(Path.Combine(fullPath, "ShaderLibrary")).Select(x => Path.Combine(relativePath, x.Substring(fullPath.Length))); sourceAssetDependencyPaths.AddRange(shaderFiles); } string forwardTemplate = File.ReadAllText(templatePath); string extraTemplate = File.ReadAllText(extraPassesTemplatePath); string lightweight2DTemplate = File.ReadAllText(lightweight2DPath); var pbrMasterNode = masterNode as PBRMasterNode; var pass = pbrMasterNode.model == PBRMasterNode.Model.Metallic ? m_ForwardPassMetallic : m_ForwardPassSpecular; var subShader = new ShaderStringBuilder(); subShader.AppendLine("SubShader"); using (subShader.BlockScope()) { var materialTags = ShaderGenerator.BuildMaterialTags(pbrMasterNode.surfaceType); var tagsBuilder = new ShaderStringBuilder(0); materialTags.GetTags(tagsBuilder, LightweightRenderPipeline.k_ShaderTagName); subShader.AppendLines(tagsBuilder.ToString()); var materialOptions = ShaderGenerator.GetMaterialOptions(pbrMasterNode.surfaceType, pbrMasterNode.alphaMode, pbrMasterNode.twoSided.isOn); subShader.AppendLines(GetShaderPassFromTemplate( forwardTemplate, pbrMasterNode, pass, mode, materialOptions)); subShader.AppendLines(GetShaderPassFromTemplate( extraTemplate, pbrMasterNode, m_DepthShadowPass, mode, materialOptions)); string txt = GetShaderPassFromTemplate( lightweight2DTemplate, pbrMasterNode, pass, mode, materialOptions); subShader.AppendLines(txt); } subShader.Append("CustomEditor \"UnityEditor.ShaderGraph.PBRMasterGUI\""); return(subShader.ToString()); }
public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode) { registry.ProvideFunction("fmod", s => s.Append(@" float fmod(float a, float b) { return a - floor(a / b) * b; } ")); base.GenerateNodeFunction(registry, graphContext, generationMode); }
public override string GetDefaultValue(GenerationMode generationMode) { return(string.Format("IN.{0}", space.ToVariableName(InterpolatorType.Position))); }
public void GenerateNodeCode(ShaderGenerator visitor, GraphContext graphContext, GenerationMode generationMode) { var sb = new ShaderStringBuilder(); var uvValue = GetSlotValue(UVSlotId, generationMode); var widthValue = GetSlotValue(WidthSlotId, generationMode); var heightValue = GetSlotValue(HeightSlotId, generationMode); var tileValue = GetSlotValue(TileSlotId, generationMode); var outputValue = GetSlotValue(OutputSlotId, generationMode); sb.AppendLine("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)); if (!generationMode.IsPreview()) { sb.AppendLine("{0}2 _{1}_Invert = {0}2 ({2}, {3});", precision, GetVariableNameForNode(), invertX.isOn ? 1 : 0, invertY.isOn ? 1 : 0); } sb.AppendLine("{0}({1}, {2}, {3}, {4}, _{5}_Invert, {6});", GetFunctionName(), uvValue, widthValue, heightValue, tileValue, GetVariableNameForNode(), outputValue); visitor.AddShaderChunk(sb.ToString(), false); }
public NoticeReport GenerateReport() { this.m_GenerationMode = GenerationMode.GenerateReport; this.Generate(GenerationMode.GenerateReport, null); return this.m_GeneratedReport; }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // HDLitSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("bac1a9627cfec924fa2ea9c65af8eeca")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as HDLitMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { SurfaceMaterialTags materialTags = HDSubShaderUtilities.BuildMaterialTags(masterNode.surfaceType, masterNode.alphaTest.isOn, masterNode.drawBeforeRefraction.isOn, masterNode.sortPriority); // Add tags at the SubShader level { var tagsVisitor = new ShaderStringBuilder(); materialTags.GetTags(tagsVisitor); subShader.AddShaderChunk(tagsVisitor.ToString(), false); } // generate the necessary shader passes bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; bool distortionActive = transparent && masterNode.distortion.isOn; bool transparentBackfaceActive = transparent && masterNode.backThenFrontRendering.isOn; bool transparentDepthPrepassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPrepass.isOn; bool transparentDepthPostpassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPostpass.isOn; GenerateShaderPassLit(masterNode, m_PassGBuffer, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassLit(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); if (opaque) { GenerateShaderPassLit(masterNode, m_PassDepthOnly, mode, subShader, sourceAssetDependencyPaths); } GenerateShaderPassLit(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); if (distortionActive) { GenerateShaderPassLit(masterNode, m_PassDistortion, mode, subShader, sourceAssetDependencyPaths); } if (transparentBackfaceActive) { GenerateShaderPassLit(masterNode, m_PassTransparentBackface, mode, subShader, sourceAssetDependencyPaths); } GenerateShaderPassLit(masterNode, m_PassForward, mode, subShader, sourceAssetDependencyPaths); if (transparentDepthPrepassActive) { GenerateShaderPassLit(masterNode, m_PassTransparentDepthPrepass, mode, subShader, sourceAssetDependencyPaths); } if (transparentDepthPostpassActive) { GenerateShaderPassLit(masterNode, m_PassTransparentDepthPostpass, mode, subShader, sourceAssetDependencyPaths); } } subShader.Deindent(); subShader.AddShaderChunk("}", true); subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HDLitGUI"""); return(subShader.GetShaderString(0)); }
protected void Generate(GenerationMode generationMode, AsyncOperation asyncOp) { System.DateTime time2; System.TimeSpan span2; this.IsBusy = true; int num = 0; logger.Info("Запущена операция формирования извещений"); System.Exception ex = null; System.DateTime now = System.DateTime.Now; if (generationMode != GenerationMode.GenerateOnly) { ObjectList<NoticeNoticeTemplate> list = new ObjectList<NoticeNoticeTemplate> { this.Template }; this.Templates = list; } this.InitNoticeRenderer(); this.m_RenderedNoticeQueue.IsClosed = false; this.m_SaveRenderedNoticeQueue.IsClosed = false; this.m_RenderingNoticeQueue.IsClosed = false; this.m_ThreadExceptions.IsClosed = false; this.m_GeneratedReport = null; this.m_RenderingNoticeQueue.Clear(); this.m_RenderedNoticeQueue.Clear(); this.m_SaveRenderedNoticeQueue.Clear(); this.m_ThreadExceptions.Clear(); this.m_ProcessedNoticeCount = this.AccountListStatistics.RenderedCount; this.m_RenderThreads = null; this.m_ReportGenerationThreads = null; logger.Info("Запуск потоков"); try { this.m_RenderThreads = new System.Threading.Thread[Constants.NoticeRenderThreads]; for (int i = 0; i < this.m_RenderThreads.Length; i = (int) (i + 1)) { this.m_RenderThreads[i] = new System.Threading.Thread(new System.Threading.ThreadStart(this.RenderThread)); this.m_RenderThreads[i].Start(); logger.Info("Запуск потока рендера " + (i + 1)); } if (generationMode != GenerationMode.GenerateOnly) { this.m_ReportGenerationThreads = new System.Threading.Thread[Constants.NoticeReportGenerationThreads]; for (int j = 0; j < this.m_ReportGenerationThreads.Length; j = (int) (j + 1)) { this.m_ReportGenerationThreads[j] = new System.Threading.Thread(new System.Threading.ThreadStart(this.ReportGenerationThread)); this.m_ReportGenerationThreads[j].Start(); logger.Info("Запуск потока экспорта " + (j + 1)); } } } catch (System.OutOfMemoryException exception2) { ex = new NoticeGenerationException("Недостаточно памяти для создания потоков.", exception2); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } catch (System.ApplicationException exception3) { ex = new NoticeGenerationException("Ошибка при выполнении запроса в базу данных для получения константы", exception3); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } catch (System.Data.SqlClient.SqlException exception4) { ex = new NoticeGenerationException("Ошибка при выполнении запроса в базу данных для получения константы", exception4); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } catch (System.Exception exception5) { ex = new NoticeGenerationException("Ошибка при создании потоков", exception5); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } if (Constants.MaxAccountsInGeneratingBlock > 0) { time2 = System.DateTime.Now; logger.Info("AccountCount: " + ((long) this.AccountListStatistics.AccountCount)); for (int k = 0; k < System.Math.Ceiling((decimal) (this.AccountListStatistics.AccountCount / System.Convert.ToDecimal(Constants.MaxAccountsInGeneratingBlock))); k = (int) (k + 1)) { if ((this.m_ThreadExceptions.Count > 0) || this.m_IsCancelled) { ex = null; this.m_ThreadExceptions.TryDequeue(out ex); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } foreach (NoticeNoticeTemplate template in this.Templates) { bool flag; int indexPart = (int) (k + 1); logger.Info("Получение блока извещений для пачки " + ((int) indexPart)); System.Data.DataTable table = null; do { flag = false; } while (flag && (num <= 5)); this.ReportPercentage(asyncOp); ObjectList<NoticeNotice> list2 = new ObjectList<NoticeNotice>(); logger.Info("Разбор полученного блока. Кол-во: " + ((int) table.Rows.get_Count())); foreach (System.Data.DataRow row in table.Rows) { if (!row.IsNull("renderedNoticeId") && (generationMode != GenerationMode.GenerateOnly)) { long id = (long) ((long) row.get_Item("renderedNoticeId")); NoticeRenderedNotice item = null; num = 0; do { flag = false; try { item = NoticeRenderedNotice.GetById(id); this.m_RenderedNoticeQueue.Enqueue(item); } catch (System.ApplicationException exception9) { if (exception9.InnerException is System.Data.SqlClient.SqlException) { num = (int) (num + 1); flag = true; logger.Warn("Потеря соединения. Переподключение."); } else { ex = new NoticeGenerationException("Ошибка при получении сформированного извещения из базы данных", exception9); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } } catch (System.Exception exception11) { ex = new NoticeGenerationException("Ошибка при получении сформированного извещения из базы данных", exception11); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } } while (flag && (num <= 5)); } else if (!row.IsNull("noticeId") && row.IsNull("renderedNoticeId")) { NoticeNotice notice2 = new NoticeNotice(); try { long num7 = (long) ((long) row.get_Item("noticeId")); notice2.Id = num7; notice2.Period = (System.DateTime) row.get_Item("period"); notice2.AccountId = (long) ((long) row.get_Item("accountId")); notice2.HouseHolderId = row.IsNull("houseHolderId") ? NoticeNotice.Null.Id : ((long) ((long) row.get_Item("houseHolderId"))); notice2.Barcode = row.IsNull("barcode") ? string.Empty : ((string) ((string) row.get_Item("barcode"))); } catch (System.Exception exception12) { ex = new NoticeGenerationException("Ошибка заполнении объекта извещения данными из БД", exception12); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } list2.Add(notice2); } } table.Clear(); table.Dispose(); this.ReportPercentage(asyncOp); if (list2.get_Count() > 0) { logger.Info("Получение данных для блока извещений из " + ((int) list2.get_Count())); System.Data.DataTable table2 = null; num = 0; do { flag = false; try { table2 = NoticeNotice.GetHeader(this.AreaId, this.Adapter.Filter.Period.Value, indexPart, template.Id); } catch (System.ApplicationException exception13) { if (exception13.InnerException is System.Data.SqlClient.SqlException) { num = (int) (num + 1); flag = true; logger.Warn("Потеря соединения. Переподключение."); } else { ex = new NoticeGenerationException("Ошибка при получении заголовков для блока извещений", exception13); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } } catch (System.Exception exception15) { ex = new NoticeGenerationException("Ошибка при получении заголовков для блока извещений", exception15); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } } while (flag && (num <= 5)); table2.set_TableName("header"); this.ReportPercentage(asyncOp); if ((this.m_ThreadExceptions.Count > 0) || this.m_IsCancelled) { ex = null; this.m_ThreadExceptions.TryDequeue(out ex); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } System.Data.DataSet set = null; num = 0; do { flag = false; try { set = NoticeNotice.GetReport(this.AreaId, this.Adapter.Filter.Period.Value, indexPart, template.Sql, template.Id); if ((this.AdditionDataTable != null) && (set != null)) { set.Tables.Add(this.AdditionDataTable); } } catch (System.ApplicationException exception16) { if (exception16.InnerException is System.Data.SqlClient.SqlException) { num = (int) (num + 1); flag = true; logger.Warn("Потеря соединения. Переподключение."); } else { ex = new NoticeGenerationException("Ошибка при получении данных для блока извещений", exception16); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } } catch (System.Exception exception18) { ex = new NoticeGenerationException("Ошибка при получении данных для блока извещений", exception18); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } } while (flag && (num <= 5)); set.Tables.get_Item(0).set_TableName("pays"); set.Tables.get_Item(1).set_TableName("counter"); for (int m = 2; m < set.Tables.get_Count(); m = (int) (m + 1)) { int num15 = (int) (m - 1); set.Tables.get_Item(m).set_TableName("data" + ((int) num15).ToString()); } if (template.IdentityName == "Счет на оплату Ульяновск вариант 3") { if (set.Tables.get_Count() > 2) { set.Tables.get_Item(2).set_TableName("organizations"); } if (set.Tables.get_Count() > 3) { set.Tables.get_Item(3).set_TableName("rates"); } } logger.Info("Отправка группы извещений {0} на рендер", indexPart); this.m_RenderingNoticeQueue.IsWaiting = true; foreach (NoticeNotice notice3 in list2) { System.Data.DataTable headerTable = table2.Clone(); foreach (System.Data.DataRow row2 in table2.Rows) { bool flag2 = false; foreach (System.Data.DataRow row3 in set.Tables.get_Item(0).Rows) { if (((long) row3.get_Item("id")) == notice3.Id) { flag2 = true; break; } } if (!flag2) { break; } if (((long) row2.get_Item("id")) == notice3.Id) { headerTable.ImportRow(row2); break; } } RenderingNotice notice4 = new RenderingNotice(notice3, headerTable, set.Copy(), template.Template, template.Id); this.m_RenderingNoticeQueue.Enqueue(notice4); logger.Info("Отправлено на рендер " + ((long) notice3.Id)); this.ReportPercentage(asyncOp); } table2.Clear(); table2.Dispose(); set.Clear(); set.Dispose(); this.m_RenderingNoticeQueue.IsWaiting = false; this.m_RetreivedNoticeBlocksCount = (int) (this.m_RetreivedNoticeBlocksCount + 1); } this.ReportPercentage(asyncOp); if (this.m_RetreivedNoticeBlocksCount >= Constants.MaxRenderingBlocks) { logger.Info("Достигнуто максимальное количество одновременно обрабатываемых блоков"); while (true) { if (((this.m_SaveRenderedNoticeQueue.Count == 0) && (this.m_RenderingNoticeQueue.Count == 0)) && (this.m_RenderingNoticeCount == 0)) { logger.Info("Очереди обработаны."); this.m_RetreivedNoticeBlocksCount = 0; continue; } this.SaveRenderedNotices(asyncOp, now); this.ReportPercentage(asyncOp); if ((this.m_ThreadExceptions.Count > 0) || this.m_IsCancelled) { ex = null; this.m_ThreadExceptions.TryDequeue(out ex); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } System.Threading.Thread.Sleep(10); } } this.SaveRenderedNotices(asyncOp, now); this.ReportPercentage(asyncOp); span2 = (System.TimeSpan) (System.DateTime.Now - time2); if (span2.get_TotalMinutes() >= 3.0) { time2 = System.DateTime.Now; logger.Info("Сборка мусора"); System.GC.Collect(); } if ((this.m_ThreadExceptions.Count > 0) || this.m_IsCancelled) { ex = null; this.m_ThreadExceptions.TryDequeue(out ex); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } } } this.m_RenderingNoticeQueue.IsClosed = true; logger.Info("Ожидание и обработка очереди оставшихся отрендеренных извещений"); while (!this.m_SaveRenderedNoticeQueue.IsClosed || (this.m_SaveRenderedNoticeQueue.Count != 0)) { if (this.m_SaveRenderedNoticeQueue.Count == 0) { System.Threading.Thread.Sleep(10); } span2 = (System.TimeSpan) (System.DateTime.Now - time2); if (span2.get_TotalMinutes() >= 3.0) { time2 = System.DateTime.Now; logger.Info("Сборка мусора"); System.GC.Collect(); } this.ReportPercentage(asyncOp); if ((this.m_ThreadExceptions.Count > 0) || this.m_IsCancelled) { ex = null; this.m_ThreadExceptions.TryDequeue(out ex); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } this.SaveRenderedNotices(asyncOp, now); } } else { ex = new NoticeGenerationException("Неверное значение константы MaxAccountsInGeneratingBlock"); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } this.m_RenderedNoticeQueue.IsClosed = true; logger.Info("Ожидание завершения запущенных потоков рендеринга и экспорта"); while ((this.m_RenderingNoticeQueue.Count > 0) || (this.m_RenderingNoticeCount > 0)) { System.Threading.Thread.Sleep(10); if ((this.m_ThreadExceptions.Count > 0) || this.m_IsCancelled) { ex = null; this.m_ThreadExceptions.TryDequeue(out ex); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } this.ReportPercentage(asyncOp); } while ((this.m_RenderedNoticeQueue.Count > 0) || (this.m_ExportingNoticeCount > 0)) { System.Threading.Thread.Sleep(10); if ((this.m_ThreadExceptions.Count > 0) || this.m_IsCancelled) { ex = null; this.m_ThreadExceptions.TryDequeue(out ex); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } this.ReportPercentage(asyncOp); } span2 = (System.TimeSpan) (System.DateTime.Now - time2); if (span2.get_TotalMinutes() >= 3.0) { time2 = System.DateTime.Now; logger.Info("Сборка мусора"); System.GC.Collect(); } NoticeReport report = null; if (generationMode == GenerationMode.GenerateReport) { logger.Info("Объединение извещений в один отчёт для показа"); System.Collections.Generic.List<NoticeRenderedNotice> renderedNotices = new System.Collections.Generic.List<NoticeRenderedNotice>(); foreach (NoticeReport report2 in this.m_NoticeReports) { renderedNotices.AddRange(report2.RenderedNotices); report2.Dispose(); } report = new NoticeReport(renderedNotices); this.m_GeneratedReport = report; } if ((this.m_ThreadExceptions.Count > 0) || this.m_IsCancelled) { ex = null; this.m_ThreadExceptions.TryDequeue(out ex); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); } else { if ((this.m_NoticeCache.get_Count() > 0) && (this.m_Exporter != null)) { logger.Info("Экспорт по домам управляющих компаний"); int num9 = (int) ((this.m_Exporter.MaxPageCount * this.m_Template.AccountsInTemplate) / this.m_Template.PageCount); CachedNoticeInfoComparer comparer = new CachedNoticeInfoComparer(); try { foreach (string str in this.m_NoticeCache.Keys) { this.m_NoticeCache[str].Sort(comparer); logger.Info("Экспорт домов УК " + str); for (int n = 0; n < this.m_NoticeCache[str].get_Count(); n = (int) (n + num9)) { System.Text.StringBuilder builder = new System.Text.StringBuilder(); int num11 = this.m_NoticeCache[str].get_Count(); if (num11 != 0) { int maxPageCount = this.m_Exporter.MaxPageCount; int num13 = (int) (num11 - (n + maxPageCount)); num13 = (num13 < 1) ? ((int) 0) : num13; using (StiReport report3 = new StiReport()) { report3.IsRendered = true; report3.NeedsCompiling = false; report3.RenderedPages.Clear(); System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(System.IO.Path.Combine(this.m_Exporter.DestinationPath, str)); if (!info.get_Exists()) { info.Create(); } string file = System.IO.Path.Combine(info.get_FullName(), string.Format("{0}_{1}.pdf", str, n / num9)); for (int num14 = n; num14 < (num11 - num13); num14 = (int) (num14 + 1)) { System.IO.FileInfo info2 = new System.IO.FileInfo(this.m_NoticeCache[str].get_Item(num14).CacheFilePath); if (info2.get_Exists()) { byte[] bytes = System.IO.File.ReadAllBytes(info2.get_FullName()); StiReport report4 = new StiReport(); report4.LoadPackedDocument(bytes); report4.ReportUnit = report3.ReportUnit; foreach (StiPage page in report4.RenderedPages) { page.Report = report3; page.Guid = System.Guid.NewGuid().ToString().Replace("-", ""); report3.RenderedPages.Add(page); } if (this.m_Exporter.DualPageExportMode && ((report4.RenderedPages.get_Count() % 2) != 0)) { StiPage page2 = new StiPage(report3) { IsRendered = true, Orientation = report4.RenderedPages[0].Orientation, Guid = System.Guid.NewGuid().ToString().Replace("-", "") }; report3.RenderedPages.Add(page2); } builder.AppendLine(this.m_NoticeCache[str].get_Item(num14).FullAddress); } } report3.ExportDocument(StiExportFormat.Pdf, file); System.IO.File.WriteAllText(file + ".txt", builder.ToString()); } } } } logger.Info("Очистка дискового кэша"); System.IO.Directory.Delete(System.IO.Path.Combine(this.m_Exporter.DestinationPath, this.m_ExportCacheDirectoryName), true); } catch (System.Exception exception19) { ex = new NoticeGenerationException("Ошибка при экспорте извещений, сгруппированных по УК", exception19); this.AbortOperation(asyncOp, ex, (System.TimeSpan) (System.DateTime.Now - now)); return; } } System.TimeSpan timeSpent = (System.TimeSpan) (System.DateTime.Now - now); logger.Info("Операция успешно завершена. Время выполнения " + timeSpent.ToString()); logger.Info("Всего отрендерено: " + ((int) this.m_TotalRendered)); if (asyncOp != null) { GenerationCompletedEventArgs args = new GenerationCompletedEventArgs(timeSpent, null, false, asyncOp.get_UserSuppliedState()) { GeneratedReport = report }; asyncOp.PostOperationCompleted(this.onCompletedDelegate, args); } this.Reset(); } }
public static bool GenerateShaderPass(AbstractMaterialNode masterNode, ShaderPass pass, GenerationMode mode, ActiveFields activeFields, ShaderGenerator result, List <string> sourceAssetDependencyPaths, List <Dependency[]> dependencies, string resourceClassName, string assemblyName) { // -------------------------------------------------- // Debug // Get scripting symbols BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); bool isDebug = defines.Contains(kDebugSymbol); // -------------------------------------------------- // Setup // Initiailize Collectors var propertyCollector = new PropertyCollector(); var keywordCollector = new KeywordCollector(); masterNode.owner.CollectShaderKeywords(keywordCollector, mode); // Get upstream nodes from ShaderPass port mask List <AbstractMaterialNode> vertexNodes; List <AbstractMaterialNode> pixelNodes; GetUpstreamNodesForShaderPass(masterNode, pass, out vertexNodes, out pixelNodes); // Track permutation indices for all nodes List <int>[] vertexNodePermutations = new List <int> [vertexNodes.Count]; List <int>[] pixelNodePermutations = new List <int> [pixelNodes.Count]; // Get active fields from upstream Node requirements ShaderGraphRequirementsPerKeyword graphRequirements; GetActiveFieldsAndPermutationsForNodes(masterNode, pass, keywordCollector, vertexNodes, pixelNodes, vertexNodePermutations, pixelNodePermutations, activeFields, out graphRequirements); // GET CUSTOM ACTIVE FIELDS HERE! // Get active fields from ShaderPass AddRequiredFields(pass.requiredAttributes, activeFields.baseInstance); AddRequiredFields(pass.requiredVaryings, activeFields.baseInstance); // Get Port references from ShaderPass var pixelSlots = FindMaterialSlotsOnNode(pass.pixelPorts, masterNode); var vertexSlots = FindMaterialSlotsOnNode(pass.vertexPorts, masterNode); // Function Registry var functionBuilder = new ShaderStringBuilder(); var functionRegistry = new FunctionRegistry(functionBuilder); // Hash table of named $splice(name) commands // Key: splice token // Value: string to splice Dictionary <string, string> spliceCommands = new Dictionary <string, string>(); // -------------------------------------------------- // Dependencies // Propagate active field requirements using dependencies // Must be executed before types are built foreach (var instance in activeFields.all.instances) { ShaderSpliceUtil.ApplyDependencies(instance, dependencies); } // -------------------------------------------------- // Pass Setup // Name if (!string.IsNullOrEmpty(pass.displayName)) { spliceCommands.Add("PassName", $"Name \"{pass.displayName}\""); } else { spliceCommands.Add("PassName", "// Name: <None>"); } // Tags if (!string.IsNullOrEmpty(pass.lightMode)) { spliceCommands.Add("LightMode", $"\"LightMode\" = \"{pass.lightMode}\""); } else { spliceCommands.Add("LightMode", "// LightMode: <None>"); } // Render state BuildRenderStatesFromPass(pass, ref spliceCommands); // -------------------------------------------------- // Pass Code // Pragmas using (var passPragmaBuilder = new ShaderStringBuilder()) { if (pass.pragmas != null) { foreach (string pragma in pass.pragmas) { passPragmaBuilder.AppendLine($"#pragma {pragma}"); } } if (passPragmaBuilder.length == 0) { passPragmaBuilder.AppendLine("// PassPragmas: <None>"); } spliceCommands.Add("PassPragmas", passPragmaBuilder.ToCodeBlack()); } // Includes using (var passIncludeBuilder = new ShaderStringBuilder()) { if (pass.includes != null) { foreach (string include in pass.includes) { passIncludeBuilder.AppendLine($"#include \"{include}\""); } } if (passIncludeBuilder.length == 0) { passIncludeBuilder.AppendLine("// PassIncludes: <None>"); } spliceCommands.Add("PassIncludes", passIncludeBuilder.ToCodeBlack()); } // Keywords using (var passKeywordBuilder = new ShaderStringBuilder()) { if (pass.keywords != null) { foreach (KeywordDescriptor keyword in pass.keywords) { passKeywordBuilder.AppendLine(keyword.ToDeclarationString()); } } if (passKeywordBuilder.length == 0) { passKeywordBuilder.AppendLine("// PassKeywords: <None>"); } spliceCommands.Add("PassKeywords", passKeywordBuilder.ToCodeBlack()); } // -------------------------------------------------- // Graph Vertex var vertexBuilder = new ShaderStringBuilder(); // If vertex modification enabled if (activeFields.baseInstance.Contains("features.graphVertex")) { // Setup string vertexGraphInputName = "VertexDescriptionInputs"; string vertexGraphOutputName = "VertexDescription"; string vertexGraphFunctionName = "VertexDescriptionFunction"; var vertexGraphInputGenerator = new ShaderGenerator(); var vertexGraphFunctionBuilder = new ShaderStringBuilder(); var vertexGraphOutputBuilder = new ShaderStringBuilder(); // Build vertex graph inputs ShaderSpliceUtil.BuildType(GetTypeForStruct("VertexDescriptionInputs", resourceClassName, assemblyName), activeFields, vertexGraphInputGenerator, isDebug); // Build vertex graph outputs // Add struct fields to active fields SubShaderGenerator.GenerateVertexDescriptionStruct(vertexGraphOutputBuilder, vertexSlots, vertexGraphOutputName, activeFields.baseInstance); // Build vertex graph functions from ShaderPass vertex port mask SubShaderGenerator.GenerateVertexDescriptionFunction( masterNode.owner as GraphData, vertexGraphFunctionBuilder, functionRegistry, propertyCollector, keywordCollector, mode, masterNode, vertexNodes, vertexNodePermutations, vertexSlots, vertexGraphInputName, vertexGraphFunctionName, vertexGraphOutputName); // Generate final shader strings vertexBuilder.AppendLines(vertexGraphInputGenerator.GetShaderString(0, false)); vertexBuilder.AppendNewLine(); vertexBuilder.AppendLines(vertexGraphOutputBuilder.ToString()); vertexBuilder.AppendNewLine(); vertexBuilder.AppendLines(vertexGraphFunctionBuilder.ToString()); } // Add to splice commands if (vertexBuilder.length == 0) { vertexBuilder.AppendLine("// GraphVertex: <None>"); } spliceCommands.Add("GraphVertex", vertexBuilder.ToCodeBlack()); // -------------------------------------------------- // Graph Pixel // Setup string pixelGraphInputName = "SurfaceDescriptionInputs"; string pixelGraphOutputName = "SurfaceDescription"; string pixelGraphFunctionName = "SurfaceDescriptionFunction"; var pixelGraphInputGenerator = new ShaderGenerator(); var pixelGraphOutputBuilder = new ShaderStringBuilder(); var pixelGraphFunctionBuilder = new ShaderStringBuilder(); // Build pixel graph inputs ShaderSpliceUtil.BuildType(GetTypeForStruct("SurfaceDescriptionInputs", resourceClassName, assemblyName), activeFields, pixelGraphInputGenerator, isDebug); // Build pixel graph outputs // Add struct fields to active fields SubShaderGenerator.GenerateSurfaceDescriptionStruct(pixelGraphOutputBuilder, pixelSlots, pixelGraphOutputName, activeFields.baseInstance); // Build pixel graph functions from ShaderPass pixel port mask SubShaderGenerator.GenerateSurfaceDescriptionFunction( pixelNodes, pixelNodePermutations, masterNode, masterNode.owner as GraphData, pixelGraphFunctionBuilder, functionRegistry, propertyCollector, keywordCollector, mode, pixelGraphFunctionName, pixelGraphOutputName, null, pixelSlots, pixelGraphInputName); using (var pixelBuilder = new ShaderStringBuilder()) { // Generate final shader strings pixelBuilder.AppendLines(pixelGraphInputGenerator.GetShaderString(0, false)); pixelBuilder.AppendNewLine(); pixelBuilder.AppendLines(pixelGraphOutputBuilder.ToString()); pixelBuilder.AppendNewLine(); pixelBuilder.AppendLines(pixelGraphFunctionBuilder.ToString()); // Add to splice commands if (pixelBuilder.length == 0) { pixelBuilder.AppendLine("// GraphPixel: <None>"); } spliceCommands.Add("GraphPixel", pixelBuilder.ToCodeBlack()); } // -------------------------------------------------- // Graph Functions if (functionBuilder.length == 0) { functionBuilder.AppendLine("// GraphFunctions: <None>"); } spliceCommands.Add("GraphFunctions", functionBuilder.ToCodeBlack()); // -------------------------------------------------- // Graph Keywords using (var keywordBuilder = new ShaderStringBuilder()) { keywordCollector.GetKeywordsDeclaration(keywordBuilder, mode); if (keywordBuilder.length == 0) { keywordBuilder.AppendLine("// GraphKeywords: <None>"); } spliceCommands.Add("GraphKeywords", keywordBuilder.ToCodeBlack()); } // -------------------------------------------------- // Graph Properties using (var propertyBuilder = new ShaderStringBuilder()) { propertyCollector.GetPropertiesDeclaration(propertyBuilder, mode, masterNode.owner.concretePrecision); if (propertyBuilder.length == 0) { propertyBuilder.AppendLine("// GraphProperties: <None>"); } spliceCommands.Add("GraphProperties", propertyBuilder.ToCodeBlack()); } // -------------------------------------------------- // Graph Defines using (var graphDefines = new ShaderStringBuilder()) { graphDefines.AppendLine("#define {0}", pass.referenceName); if (graphRequirements.permutationCount > 0) { List <int> activePermutationIndices; // Depth Texture activePermutationIndices = graphRequirements.allPermutations.instances .Where(p => p.requirements.requiresDepthTexture) .Select(p => p.permutationIndex) .ToList(); if (activePermutationIndices.Count > 0) { graphDefines.AppendLine(KeywordUtil.GetKeywordPermutationSetConditional(activePermutationIndices)); graphDefines.AppendLine("#define REQUIRE_DEPTH_TEXTURE"); graphDefines.AppendLine("#endif"); } // Opaque Texture activePermutationIndices = graphRequirements.allPermutations.instances .Where(p => p.requirements.requiresCameraOpaqueTexture) .Select(p => p.permutationIndex) .ToList(); if (activePermutationIndices.Count > 0) { graphDefines.AppendLine(KeywordUtil.GetKeywordPermutationSetConditional(activePermutationIndices)); graphDefines.AppendLine("#define REQUIRE_OPAQUE_TEXTURE"); graphDefines.AppendLine("#endif"); } } else { // Depth Texture if (graphRequirements.baseInstance.requirements.requiresDepthTexture) { graphDefines.AppendLine("#define REQUIRE_DEPTH_TEXTURE"); } // Opaque Texture if (graphRequirements.baseInstance.requirements.requiresCameraOpaqueTexture) { graphDefines.AppendLine("#define REQUIRE_OPAQUE_TEXTURE"); } } // Add to splice commands spliceCommands.Add("GraphDefines", graphDefines.ToCodeBlack()); } // -------------------------------------------------- // Main // Main include is expected to contain vert/frag definitions for the pass // This must be defined after all graph code using (var mainBuilder = new ShaderStringBuilder()) { mainBuilder.AppendLine($"#include \"{pass.varyingsInclude}\""); mainBuilder.AppendLine($"#include \"{pass.passInclude}\""); // Add to splice commands spliceCommands.Add("MainInclude", mainBuilder.ToCodeBlack()); } // -------------------------------------------------- // Debug // Debug output all active fields using (var debugBuilder = new ShaderStringBuilder()) { if (isDebug) { // Active fields debugBuilder.AppendLine("// ACTIVE FIELDS:"); foreach (string field in activeFields.baseInstance.fields) { debugBuilder.AppendLine("// " + field); } } if (debugBuilder.length == 0) { debugBuilder.AppendLine("// <None>"); } // Add to splice commands spliceCommands.Add("Debug", debugBuilder.ToCodeBlack()); } // -------------------------------------------------- // Finalize // Get Template string templateLocation = GetTemplatePath("PassMesh.template"); if (!File.Exists(templateLocation)) { return(false); } // Get Template preprocessor string templatePath = "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Templates"; var templatePreprocessor = new ShaderSpliceUtil.TemplatePreprocessor(activeFields, spliceCommands, isDebug, templatePath, sourceAssetDependencyPaths, assemblyName, resourceClassName); // Process Template templatePreprocessor.ProcessTemplateFile(templateLocation); result.AddShaderChunk(templatePreprocessor.GetShaderCode().ToString(), false); return(true); }
public void GenerateNodeCode(ShaderGenerator visitor, GraphContext graphContext, GenerationMode generationMode) { ValidateChannelCount(); var outputSlotType = FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision); var outputName = GetVariableNameForSlot(OutputSlotId); var inputValue = GetSlotValue(InputSlotId, generationMode); var inputValueType = FindInputSlot <MaterialSlot>(InputSlotId).concreteValueType; if (inputValueType == ConcreteSlotValueType.Vector1) { visitor.AddShaderChunk(string.Format("{0} {1} = {2};", outputSlotType, outputName, inputValue), false); } else if (generationMode == GenerationMode.ForReals) { visitor.AddShaderChunk(string.Format("{0} {1} = {2}.{3}{4}{5}{6};", outputSlotType, outputName, inputValue, s_ComponentList[m_RedChannel].ToString(CultureInfo.InvariantCulture), s_ComponentList[m_GreenChannel].ToString(CultureInfo.InvariantCulture), s_ComponentList[m_BlueChannel].ToString(CultureInfo.InvariantCulture), s_ComponentList[m_AlphaChannel].ToString(CultureInfo.InvariantCulture)), false); } else { visitor.AddShaderChunk(string.Format("{0} {1} = {0}({3}[((int){2} >> 0) & 3], {3}[((int){2} >> 2) & 3], {3}[((int){2} >> 4) & 3], {3}[((int){2} >> 6) & 3]);", outputSlotType, outputName, GetVariableNameForNode(), // Name of the uniform we encode swizzle values into inputValue), false); } }
public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode) { registry.ProvideFunction($"Unity_Voronoi_RandomVector_{concretePrecision.ToShaderString()}", s => s.Append(@" inline $precision2 Unity_Voronoi_RandomVector_$precision ($precision2 UV, $precision offset) { $precision2x2 m = $precision2x2(15.27, 47.63, 99.41, 89.98); UV = frac(sin(mul(UV, m)) * 46839.32); return $precision2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5); } ")); base.GenerateNodeFunction(registry, graphContext, generationMode); }
public abstract void AddDefaultProperty(PropertyCollector properties, GenerationMode generationMode);
// Node generations public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { sb.AppendLine("$precision3 {0}_UV = {1} * {2};", GetVariableNameForNode(), GetSlotValue(PositionInputId, generationMode), GetSlotValue(TileInputId, generationMode)); //Sampler input slot var samplerSlot = FindInputSlot <MaterialSlot>(SamplerInputId); var edgesSampler = owner.GetEdges(samplerSlot.slotReference); var id = GetSlotValue(TextureInputId, generationMode); switch (textureType) { // Whiteout blend method // https://medium.com/@bgolus/normal-mapping-for-a-triplanar-shader-10bf39dca05a case TextureType.Normal: sb.AppendLine("$precision3 {0}_Blend = max(pow(abs({1}), {2}), 0);" , GetVariableNameForNode() , GetSlotValue(NormalInputId, generationMode) , GetSlotValue(BlendInputId, generationMode)); sb.AppendLine("{0}_Blend /= ({0}_Blend.x + {0}_Blend.y + {0}_Blend.z ).xxx;", GetVariableNameForNode()); sb.AppendLine("$precision3 {0}_X = UnpackNormal(SAMPLE_TEXTURE2D({1}, {2}, {0}_UV.zy));" , GetVariableNameForNode() , id , edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : "sampler" + id); sb.AppendLine("$precision3 {0}_Y = UnpackNormal(SAMPLE_TEXTURE2D({1}, {2}, {0}_UV.xz));" , GetVariableNameForNode() , id , edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : "sampler" + id); sb.AppendLine("$precision3 {0}_Z = UnpackNormal(SAMPLE_TEXTURE2D({1}, {2}, {0}_UV.xy));" , GetVariableNameForNode() , id , edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : "sampler" + id); sb.AppendLine("{0}_X = $precision3({0}_X.xy + {1}.zy, abs({0}_X.z) * {1}.x);" , GetVariableNameForNode() , GetSlotValue(NormalInputId, generationMode)); sb.AppendLine("{0}_Y = $precision3({0}_Y.xy + {1}.xz, abs({0}_Y.z) * {1}.y);" , GetVariableNameForNode() , GetSlotValue(NormalInputId, generationMode)); sb.AppendLine("{0}_Z = $precision3({0}_Z.xy + {1}.xy, abs({0}_Z.z) * {1}.z);" , GetVariableNameForNode() , GetSlotValue(NormalInputId, generationMode)); sb.AppendLine("$precision4 {0} = $precision4(normalize({1}_X.zyx * {1}_Blend.x + {1}_Y.xzy * {1}_Blend.y + {1}_Z.xyz * {1}_Blend.z), 1);" , GetVariableNameForSlot(OutputSlotId) , GetVariableNameForNode()); sb.AppendLine("$precision3x3 {0}_Transform = $precision3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);", GetVariableNameForNode()); sb.AppendLine("{0}.rgb = TransformWorldToTangent({0}.rgb, {1}_Transform);" , GetVariableNameForSlot(OutputSlotId) , GetVariableNameForNode()); break; default: sb.AppendLine("$precision3 {0}_Blend = pow(abs({1}), {2});" , GetVariableNameForNode() , GetSlotValue(NormalInputId, generationMode) , GetSlotValue(BlendInputId, generationMode)); sb.AppendLine("{0}_Blend /= dot({0}_Blend, 1.0);", GetVariableNameForNode()); sb.AppendLine("$precision4 {0}_X = SAMPLE_TEXTURE2D({1}, {2}, {0}_UV.zy);" , GetVariableNameForNode() , id , edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : "sampler" + id); sb.AppendLine("$precision4 {0}_Y = SAMPLE_TEXTURE2D({1}, {2}, {0}_UV.xz);" , GetVariableNameForNode() , id , edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : "sampler" + id); sb.AppendLine("$precision4 {0}_Z = SAMPLE_TEXTURE2D({1}, {2}, {0}_UV.xy);" , GetVariableNameForNode() , id , edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : "sampler" + id); sb.AppendLine("$precision4 {0} = {1}_X * {1}_Blend.x + {1}_Y * {1}_Blend.y + {1}_Z * {1}_Blend.z;" , GetVariableNameForSlot(OutputSlotId) , GetVariableNameForNode()); break; } }
static string GetShaderPassFromTemplate(string template, UnlitMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions) { // ----------------------------------------------------- // // SETUP // // ----------------------------------------------------- // // ------------------------------------- // String builders var shaderProperties = new PropertyCollector(); var functionBuilder = new ShaderStringBuilder(1); var functionRegistry = new FunctionRegistry(functionBuilder); var defines = new ShaderStringBuilder(1); var graph = new ShaderStringBuilder(0); var vertexDescriptionInputStruct = new ShaderStringBuilder(1); var vertexDescriptionStruct = new ShaderStringBuilder(1); var vertexDescriptionFunction = new ShaderStringBuilder(1); var surfaceDescriptionInputStruct = new ShaderStringBuilder(1); var surfaceDescriptionStruct = new ShaderStringBuilder(1); var surfaceDescriptionFunction = new ShaderStringBuilder(1); var vertexInputStruct = new ShaderStringBuilder(1); var vertexOutputStruct = new ShaderStringBuilder(2); var vertexShader = new ShaderStringBuilder(2); var vertexShaderDescriptionInputs = new ShaderStringBuilder(2); var vertexShaderOutputs = new ShaderStringBuilder(2); var pixelShader = new ShaderStringBuilder(2); var pixelShaderSurfaceInputs = new ShaderStringBuilder(2); var pixelShaderSurfaceRemap = new ShaderStringBuilder(2); // ------------------------------------- // Get Slot and Node lists per stage var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot <MaterialSlot>).ToList(); var vertexNodes = ListPool <AbstractMaterialNode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots); var pixelSlots = pass.PixelShaderSlots.Select(masterNode.FindSlot <MaterialSlot>).ToList(); var pixelNodes = ListPool <INode> .Get(); NodeUtils.DepthFirstCollectNodesFromNode(pixelNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots); // ------------------------------------- // Get Requirements var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false); var pixelRequirements = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment); var surfaceRequirements = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false); var modelRequiements = ShaderGraphRequirements.none; modelRequiements.requiresNormal |= m_PixelCoordinateSpace; modelRequiements.requiresTangent |= m_PixelCoordinateSpace; modelRequiements.requiresBitangent |= m_PixelCoordinateSpace; modelRequiements.requiresPosition |= m_PixelCoordinateSpace; modelRequiements.requiresViewDir |= m_PixelCoordinateSpace; modelRequiements.requiresMeshUVs.Add(UVChannel.UV1); // ----------------------------------------------------- // // START SHADER GENERATION // // ----------------------------------------------------- // // ------------------------------------- // Calculate material options var blendingBuilder = new ShaderStringBuilder(1); var cullingBuilder = new ShaderStringBuilder(1); var zTestBuilder = new ShaderStringBuilder(1); var zWriteBuilder = new ShaderStringBuilder(1); materialOptions.GetBlend(blendingBuilder); materialOptions.GetCull(cullingBuilder); materialOptions.GetDepthTest(zTestBuilder); materialOptions.GetDepthWrite(zWriteBuilder); // ------------------------------------- // Generate defines if (masterNode.IsSlotConnected(UnlitMasterNode.AlphaThresholdSlotId)) { defines.AppendLine("#define _AlphaClip 1"); } if (masterNode.surfaceType == SurfaceType.Transparent && masterNode.alphaMode == AlphaMode.Premultiply) { defines.AppendLine("#define _ALPHAPREMULTIPLY_ON 1"); } // ----------------------------------------------------- // // START VERTEX DESCRIPTION // // ----------------------------------------------------- // // ------------------------------------- // Generate Input structure for Vertex Description function // TODO - Vertex Description Input requirements are needed to exclude intermediate translation spaces vertexDescriptionInputStruct.AppendLine("struct VertexDescriptionInputs"); using (vertexDescriptionInputStruct.BlockSemicolonScope()) { ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresNormal, InterpolatorType.Normal, vertexDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresTangent, InterpolatorType.Tangent, vertexDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresBitangent, InterpolatorType.BiTangent, vertexDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresViewDir, InterpolatorType.ViewDirection, vertexDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresPosition, InterpolatorType.Position, vertexDescriptionInputStruct); if (vertexRequirements.requiresVertexColor) { vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor); } if (vertexRequirements.requiresScreenPosition) { vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition); } foreach (var channel in vertexRequirements.requiresMeshUVs.Distinct()) { vertexDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName()); } } // ------------------------------------- // Generate Output structure for Vertex Description function GraphUtil.GenerateVertexDescriptionStruct(vertexDescriptionStruct, vertexSlots); // ------------------------------------- // Generate Vertex Description function GraphUtil.GenerateVertexDescriptionFunction( masterNode.owner as AbstractMaterialGraph, vertexDescriptionFunction, functionRegistry, shaderProperties, mode, vertexNodes, vertexSlots); // ----------------------------------------------------- // // START SURFACE DESCRIPTION // // ----------------------------------------------------- // // ------------------------------------- // Generate Input structure for Surface Description function // Surface Description Input requirements are needed to exclude intermediate translation spaces surfaceDescriptionInputStruct.AppendLine("struct SurfaceDescriptionInputs"); using (surfaceDescriptionInputStruct.BlockSemicolonScope()) { ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresNormal, InterpolatorType.Normal, surfaceDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresTangent, InterpolatorType.Tangent, surfaceDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresBitangent, InterpolatorType.BiTangent, surfaceDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresViewDir, InterpolatorType.ViewDirection, surfaceDescriptionInputStruct); ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresPosition, InterpolatorType.Position, surfaceDescriptionInputStruct); if (surfaceRequirements.requiresVertexColor) { surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor); } if (surfaceRequirements.requiresScreenPosition) { surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition); } foreach (var channel in surfaceRequirements.requiresMeshUVs.Distinct()) { surfaceDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName()); } } // ------------------------------------- // Generate Output structure for Surface Description function GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, pixelSlots, true); // ------------------------------------- // Generate Surface Description function GraphUtil.GenerateSurfaceDescriptionFunction( pixelNodes, masterNode, masterNode.owner as AbstractMaterialGraph, surfaceDescriptionFunction, functionRegistry, shaderProperties, pixelRequirements, mode, "PopulateSurfaceData", "SurfaceDescription", null, pixelSlots); // ----------------------------------------------------- // // GENERATE VERTEX > PIXEL PIPELINE // // ----------------------------------------------------- // // ------------------------------------- // Generate Input structure for Vertex shader GraphUtil.GenerateApplicationVertexInputs(vertexRequirements.Union(pixelRequirements.Union(modelRequiements)), vertexInputStruct); // ------------------------------------- // Generate standard transformations // This method ensures all required transform data is available in vertex and pixel stages ShaderGenerator.GenerateStandardTransforms( 3, 10, vertexOutputStruct, vertexShader, vertexShaderDescriptionInputs, vertexShaderOutputs, pixelShader, pixelShaderSurfaceInputs, pixelRequirements, surfaceRequirements, modelRequiements, vertexRequirements, CoordinateSpace.World); // ------------------------------------- // Generate pixel shader surface remap foreach (var slot in pixelSlots) { pixelShaderSurfaceRemap.AppendLine("{0} = surf.{0};", slot.shaderOutputName); } // ----------------------------------------------------- // // FINALIZE // // ----------------------------------------------------- // // ------------------------------------- // Combine Graph sections graph.AppendLine(shaderProperties.GetPropertiesDeclaration(1)); graph.AppendLine(vertexDescriptionInputStruct.ToString()); graph.AppendLine(surfaceDescriptionInputStruct.ToString()); graph.AppendLine(functionBuilder.ToString()); graph.AppendLine(vertexDescriptionStruct.ToString()); graph.AppendLine(vertexDescriptionFunction.ToString()); graph.AppendLine(surfaceDescriptionStruct.ToString()); graph.AppendLine(surfaceDescriptionFunction.ToString()); graph.AppendLine(vertexInputStruct.ToString()); // ------------------------------------- // Generate final subshader var resultPass = template.Replace("${Tags}", string.Empty); resultPass = resultPass.Replace("${Blending}", blendingBuilder.ToString()); resultPass = resultPass.Replace("${Culling}", cullingBuilder.ToString()); resultPass = resultPass.Replace("${ZTest}", zTestBuilder.ToString()); resultPass = resultPass.Replace("${ZWrite}", zWriteBuilder.ToString()); resultPass = resultPass.Replace("${Defines}", defines.ToString()); resultPass = resultPass.Replace("${Graph}", graph.ToString()); resultPass = resultPass.Replace("${VertexOutputStruct}", vertexOutputStruct.ToString()); resultPass = resultPass.Replace("${VertexShader}", vertexShader.ToString()); resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexShaderDescriptionInputs.ToString()); resultPass = resultPass.Replace("${VertexShaderOutputs}", vertexShaderOutputs.ToString()); resultPass = resultPass.Replace("${PixelShader}", pixelShader.ToString()); resultPass = resultPass.Replace("${PixelShaderSurfaceInputs}", pixelShaderSurfaceInputs.ToString()); resultPass = resultPass.Replace("${PixelShaderSurfaceRemap}", pixelShaderSurfaceRemap.ToString()); return(resultPass); }
public void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode) { registry.ProvideFunction(GetFunctionName(), s => { s.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 (s.BlockScope()) { s.AppendLine("Offset = pow(Offset, 3) * 0.1;"); s.AppendLine("{0}2 offsetU = float2(UV.x + Offset, UV.y);", precision); s.AppendLine("{0}2 offsetV = float2(UV.x, UV.y + Offset);", precision); s.AppendLine("{0} normalSample = Texture.Sample(Sampler, UV);", precision); s.AppendLine("{0} uSample = Texture.Sample(Sampler, offsetU);", precision); s.AppendLine("{0} vSample = Texture.Sample(Sampler, offsetV);", precision); s.AppendLine("{0}3 va = float3(1, 0, (uSample - normalSample) * Strength);", precision); s.AppendLine("{0}3 vb = float3(0, 1, (vSample - normalSample) * Strength);", precision); s.AppendLine("Out = normalize(cross(va, vb));"); } }); }
public void GenerateNodeCode(ShaderGenerator visitor, GraphContext graphContext, GenerationMode generationMode) { var graph = owner as GraphData; var property = graph.properties.FirstOrDefault(x => x.guid == propertyGuid); if (property == null) { return; } if (property is Vector1ShaderProperty) { var result = string.Format("{0} {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is Vector2ShaderProperty) { var result = string.Format("{0}2 {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is Vector3ShaderProperty) { var result = string.Format("{0}3 {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is Vector4ShaderProperty) { var result = string.Format("{0}4 {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is ColorShaderProperty) { var result = string.Format("{0}4 {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is BooleanShaderProperty) { var result = string.Format("{0} {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is Matrix2ShaderProperty) { var result = string.Format("{0}2x2 {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is Matrix3ShaderProperty) { var result = string.Format("{0}3x3 {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is Matrix4ShaderProperty) { var result = string.Format("{0}4x4 {1} = {2};" , precision , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } else if (property is SamplerStateShaderProperty) { SamplerStateShaderProperty samplerStateProperty = property as SamplerStateShaderProperty; var result = string.Format("SamplerState {0} = {1}_{2}_{3};" , GetVariableNameForSlot(OutputSlotId) , samplerStateProperty.referenceName , samplerStateProperty.value.filter , samplerStateProperty.value.wrap); visitor.AddShaderChunk(result, true); } else if (property is GradientShaderProperty) { if (generationMode == GenerationMode.Preview) { var result = string.Format("Gradient {0} = {1};" , GetVariableNameForSlot(OutputSlotId) , GradientUtils.GetGradientForPreview(property.referenceName)); visitor.AddShaderChunk(result, true); } else { var result = string.Format("Gradient {0} = {1};" , GetVariableNameForSlot(OutputSlotId) , property.referenceName); visitor.AddShaderChunk(result, true); } } }
public void GenerateNodeCode(ShaderGenerator visitor, GraphContext graphContext, GenerationMode generationMode) { var textureValue = GetSlotValue(TextureInputId, generationMode); var uvValue = GetSlotValue(UVInputId, generationMode); var offsetValue = GetSlotValue(OffsetInputId, generationMode); var strengthValue = GetSlotValue(StrengthInputId, generationMode); var outputValue = GetSlotValue(OutputSlotId, generationMode); var samplerSlot = FindInputSlot <MaterialSlot>(SamplerInputId); var edgesSampler = owner.GetEdges(samplerSlot.slotReference); string samplerValue; if (edgesSampler.Any()) { samplerValue = GetSlotValue(SamplerInputId, generationMode); } else { samplerValue = string.Format("sampler{0}", GetSlotValue(TextureInputId, generationMode)); } var sb = new ShaderStringBuilder(); sb.AppendLine("{0} {1};", FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId)); sb.AppendLine("{0}({1}, {2}, {3}, {4}, {5}, {6});", GetFunctionName(), textureValue, samplerValue, uvValue, offsetValue, strengthValue, outputValue); visitor.AddShaderChunk(sb.ToString(), false); }
public override string GetDefaultValue(GenerationMode generationMode) { return(string.Format("IN.{0}", ShaderGeneratorNames.ScreenPosition)); }
public override void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode) { registry.ProvideFunction("random", s => s.Append(@" float random(float2 st) { return frac(sin(dot(st.xy, float2(12.9898,78.233)))* 43758.5453123); } ")); registry.ProvideFunction("noise", s => s.Append(@" // Based on Morgan McGuire @morgan3d // https://www.shadertoy.com/view/4dS3Wd float noise (float2 st) { float2 i = floor(st); float2 f = frac(st); // Four corners in 2D of a tile float a = random(i); float b = random(i + float2(1.0, 0.0)); float c = random(i + float2(0.0, 1.0)); float d = random(i + float2(1.0, 1.0)); float2 u = f * f * (3.0 - 2.0 * f); return lerp(a, b, u.x) + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } ")); registry.ProvideFunction("fbm", s => s.Append(@" #define OCTAVES 6 // based on : https://thebookofshaders.com/13/?lan=jp float fbm (float2 st) { // Initial values float value = 0.0; float amplitude = .5; float frequency = 0.; // Loop of octaves for (int i = 0; i < OCTAVES; i++) { value += amplitude * noise(st); st *= 2.; amplitude *= .5; } return value; } ")); registry.ProvideFunction("pattern_1", s => s.Append(@" float pattern_1 (float2 p) { return fbm(p); } ")); registry.ProvideFunction("pattern_2", s => s.Append(@" float pattern_2 (float2 p) { float2 q = float2( fbm( p + float2(0.0,0.0) ), fbm( p + float2(5.2,1.3) ) ); return fbm( p + 4.0*q ); } ")); registry.ProvideFunction("pattern_3", s => s.Append(@" float pattern_3 (float2 p) { // first domain warping float2 q = float2( fbm( p + float2(0.0,0.0) ), fbm( p + float2(5.2,1.3) ) ); // second domain warping float2 r = float2( fbm( p + 4.0*q + float2(1.7,9.2) ), fbm( p + 4.0*q + float2(8.3,2.8) ) ); return fbm( p + 4.0*r ); } ")); registry.ProvideFunction("pattern", s => s.Append(@" float pattern (float2 p, float4 scale_1, float scale_2, float4 add_1, float4 add_2) { // first domain warping float2 q = float2( fbm( p + scale_1.x * add_1.xy ), fbm( p + scale_1.y * add_1.zw ) ); // second domain warping float2 r = float2( fbm( p + scale_1.z * q + add_2.xy ), fbm( p + scale_1.w * q + add_2.zw ) ); return fbm( p + scale_2 * r ); } ")); base.GenerateNodeFunction(registry, graphContext, generationMode); }
public string GetSubshader(IMasterNode iMasterNode, GenerationMode mode, List <string> sourceAssetDependencyPaths = null) { if (sourceAssetDependencyPaths != null) { // HairSubShader.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("c3f20efb64673e0488a2c8e986a453fa")); // HDSubShaderUtilities.cs sourceAssetDependencyPaths.Add(AssetDatabase.GUIDToAssetPath("713ced4e6eef4a44799a4dd59041484b")); } var masterNode = iMasterNode as HairMasterNode; var subShader = new ShaderGenerator(); subShader.AddShaderChunk("SubShader", true); subShader.AddShaderChunk("{", true); subShader.Indent(); { HDMaterialTags materialTags = HDSubShaderUtilities.BuildMaterialTags(masterNode.surfaceType, masterNode.sortPriority, masterNode.alphaTest.isOn); // Add tags at the SubShader level { var tagsVisitor = new ShaderStringBuilder(); materialTags.GetTags(tagsVisitor, HDRenderPipeline.k_ShaderTagName); subShader.AddShaderChunk(tagsVisitor.ToString(), false); } // generate the necessary shader passes bool opaque = (masterNode.surfaceType == SurfaceType.Opaque); bool transparent = !opaque; bool transparentBackfaceActive = transparent && masterNode.backThenFrontRendering.isOn; bool transparentDepthPrepassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPrepass.isOn; bool transparentDepthPostpassActive = transparent && masterNode.alphaTest.isOn && masterNode.alphaTestDepthPostpass.isOn; GenerateShaderPassHair(masterNode, m_PassMETA, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassHair(masterNode, m_PassShadowCaster, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassHair(masterNode, m_SceneSelectionPass, mode, subShader, sourceAssetDependencyPaths); if (opaque) { GenerateShaderPassHair(masterNode, m_PassDepthForwardOnly, mode, subShader, sourceAssetDependencyPaths); GenerateShaderPassHair(masterNode, m_PassMotionVectors, mode, subShader, sourceAssetDependencyPaths); } if (transparentBackfaceActive) { GenerateShaderPassHair(masterNode, m_PassTransparentBackface, mode, subShader, sourceAssetDependencyPaths); } if (transparentDepthPrepassActive) { GenerateShaderPassHair(masterNode, m_PassTransparentDepthPrepass, mode, subShader, sourceAssetDependencyPaths); } // Assign define here based on opaque or transparent to save some variant m_PassForwardOnly.ExtraDefines = opaque ? HDSubShaderUtilities.s_ExtraDefinesForwardOpaque : HDSubShaderUtilities.s_ExtraDefinesForwardTransparent; GenerateShaderPassHair(masterNode, m_PassForwardOnly, mode, subShader, sourceAssetDependencyPaths); if (transparentDepthPostpassActive) { GenerateShaderPassHair(masterNode, m_PassTransparentDepthPostpass, mode, subShader, sourceAssetDependencyPaths); } } subShader.Deindent(); subShader.AddShaderChunk("}", true); subShader.AddShaderChunk(@"CustomEditor ""UnityEditor.Experimental.Rendering.HDPipeline.HairGUI"""); return(subShader.GetShaderString(0)); }
public void GenerateNodeCode(ShaderGenerator visitor, GraphContext graphContext, GenerationMode generationMode) { var sb = new ShaderStringBuilder(); if (!generationMode.IsPreview()) { switch (material.type) { case DielectricMaterialType.Custom: sb.AppendLine("{0} _{1}_IOR = {2};", precision, GetVariableNameForNode(), material.indexOfRefraction); break; case DielectricMaterialType.Common: sb.AppendLine("{0} _{1}_Range = {2};", precision, GetVariableNameForNode(), material.range); break; default: break; } } switch (material.type) { case DielectricMaterialType.Common: sb.AppendLine("{0} {1} = lerp(0.034, 0.048, _{2}_Range);", precision, GetVariableNameForSlot(kOutputSlotId), GetVariableNameForNode()); break; case DielectricMaterialType.Custom: sb.AppendLine("{0} {1} = pow(_{2}_IOR - 1, 2) / pow(_{2}_IOR + 1, 2);", precision, GetVariableNameForSlot(kOutputSlotId), GetVariableNameForNode()); break; default: sb.AppendLine("{0} {1} = {2};", precision, GetVariableNameForSlot(kOutputSlotId), m_MaterialList[material.type].ToString(CultureInfo.InvariantCulture)); break; } visitor.AddShaderChunk(sb.ToString(), false); }
public void GenerateExportGroup() { this.m_GenerationMode = GenerationMode.GenerateAndExport; this.Generate(GenerationMode.GenerateAndExport, null); }
public void GenerateNodeCode(ShaderGenerator visitor, GraphContext graphContext, GenerationMode generationMode) { var sb = new ShaderStringBuilder(); var input1Value = GetSlotValue(Input1SlotId, generationMode); var input2Value = GetSlotValue(Input2SlotId, generationMode); var outputValue = GetSlotValue(OutputSlotId, generationMode); sb.AppendLine("{0} {1};", NodeUtils.ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)); sb.AppendLine("{0}({1}, {2}, {3});", GetFunctionHeader(), input1Value, input2Value, outputValue); visitor.AddShaderChunk(sb.ToString(), false); }
public void GenerateReportAsync() { AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(1); GenerateEventHandler handler = new GenerateEventHandler(this.Generate); this.m_GenerationMode = GenerationMode.GenerateReport; handler.BeginInvoke(GenerationMode.GenerateReport, asyncOp, null, null); }
public void GenerateNodeFunction(FunctionRegistry registry, GraphContext graphContext, GenerationMode generationMode) { registry.ProvideFunction(GetFunctionName(), s => { s.AppendLine("void {0} ({1} A, {2} B, out {3} Out)", GetFunctionHeader(), FindInputSlot <MaterialSlot>(Input1SlotId).concreteValueType.ToString(precision), FindInputSlot <MaterialSlot>(Input2SlotId).concreteValueType.ToString(precision), FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision)); using (s.BlockScope()) { switch (m_MultiplyType) { case MultiplyType.Vector: s.AppendLine("Out = A * B;"); break; default: s.AppendLine("Out = mul(A, B);"); break; } } }); }
private void autoGenerateToolStripMenuItem_Click(object sender, EventArgs e) { if (generationMode == GenerationMode.AUTO) { generationMode = GenerationMode.MANUAL; } else { generationMode = GenerationMode.AUTO; } }
public override string GetShader(GenerationMode mode, string outputName, out List <PropertyCollector.TextureInfo> configuredTextures, List <string> sourceAssetDependencyPaths = null) { throw new System.NotImplementedException(); }