static void CreateHDRenderPipeline()
        {
            var instance = ScriptableObject.CreateInstance <HDRenderPipelineAsset>();

            AssetDatabase.CreateAsset(instance, HDEditorUtils.GetHDRenderPipelinePath() + "HDRenderPipelineAsset.asset");

            // If it exist, load renderPipelineResources
            instance.renderPipelineResources = AssetDatabase.LoadAssetAtPath <RenderPipelineResources>(s_RenderPipelineResourcesPath);
        }
        static void CreateRenderPipelineResources()
        {
            string HDRenderPipelinePath = HDEditorUtils.GetHDRenderPipelinePath();
            string PostProcessingPath   = HDEditorUtils.GetPostProcessingPath();
            string CorePath             = HDEditorUtils.GetCorePath();

            var instance = ScriptableObject.CreateInstance <RenderPipelineResources>();

            instance.debugDisplayLatlongShader      = Load <Shader>(HDRenderPipelinePath + "Debug/DebugDisplayLatlong.Shader");
            instance.debugViewMaterialGBufferShader = Load <Shader>(HDRenderPipelinePath + "Debug/DebugViewMaterialGBuffer.Shader");
            instance.debugViewTilesShader           = Load <Shader>(HDRenderPipelinePath + "Debug/DebugViewTiles.Shader");
            instance.debugFullScreenShader          = Load <Shader>(HDRenderPipelinePath + "Debug/DebugFullScreen.Shader");

            instance.deferredShader         = Load <Shader>(HDRenderPipelinePath + "Lighting/Deferred.Shader");
            instance.subsurfaceScatteringCS = Load <ComputeShader>(HDRenderPipelinePath + "Material/Lit/Resources/SubsurfaceScattering.compute");
            instance.volumetricLightingCS   = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/Volumetrics/Resources/VolumetricLighting.compute");
            instance.gaussianPyramidCS      = Load <ComputeShader>(PostProcessingPath + "Shaders/Builtins/GaussianDownsample.compute");
            instance.depthPyramidCS         = Load <ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/DepthDownsample.compute");
            instance.copyChannelCS          = Load <ComputeShader>(CorePath + "Resources/GPUCopy.compute");
            instance.applyDistortionCS      = Load <ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ApplyDistorsion.compute");

            instance.clearDispatchIndirectShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/cleardispatchindirect.compute");
            instance.buildDispatchIndirectShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/builddispatchindirect.compute");
            instance.buildScreenAABBShader          = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/scrbound.compute");
            instance.buildPerTileLightListShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/lightlistbuild.compute");
            instance.buildPerBigTileLightListShader = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/lightlistbuild-bigtile.compute");
            instance.buildPerVoxelLightListShader   = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/lightlistbuild-clustered.compute");
            instance.buildMaterialFlagsShader       = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/materialflags.compute");
            instance.deferredComputeShader          = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/Deferred.compute");

            instance.deferredDirectionalShadowComputeShader = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/TilePass/DeferredDirectionalShadow.compute");

            // SceneSettings
            // These shaders don't need to be reference by RenderPipelineResource as they are not use at runtime (only to draw in editor)
            // instance.drawSssProfile = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>(HDRenderPipelinePath + "SceneSettings/DrawSssProfile.shader");
            // instance.drawTransmittanceGraphShader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>(HDRenderPipelinePath + "SceneSettings/DrawTransmittanceGraph.shader");

            instance.cameraMotionVectors = Load <Shader>(HDRenderPipelinePath + "RenderPipelineResources/CameraMotionVectors.shader");

            // Sky
            instance.blitCubemap                 = Load <Shader>(HDRenderPipelinePath + "Sky/BlitCubemap.shader");
            instance.buildProbabilityTables      = Load <ComputeShader>(HDRenderPipelinePath + "Sky/BuildProbabilityTables.compute");
            instance.computeGgxIblSampleData     = Load <ComputeShader>(HDRenderPipelinePath + "Sky/ComputeGgxIblSampleData.compute");
            instance.GGXConvolve                 = Load <Shader>(HDRenderPipelinePath + "Sky/GGXConvolve.shader");
            instance.opaqueAtmosphericScattering = Load <Shader>(HDRenderPipelinePath + "Sky/OpaqueAtmosphericScattering.shader");

            // Skybox/Cubemap is a builtin shader, must use Sahder.Find to access it. It is fine because we are in the editor
            instance.skyboxCubemap = Shader.Find("Skybox/Cubemap");

            AssetDatabase.CreateAsset(instance, s_RenderPipelineResourcesPath);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
Ejemplo n.º 3
0
            public override void Action(int instanceId, string pathName, string resourceFile)
            {
                var newAsset = CreateInstance <RenderPipelineResources>();

                newAsset.name = Path.GetFileName(pathName);

                // Load default renderPipelineResources / Material / Shader
                string HDRenderPipelinePath = HDEditorUtils.GetHDRenderPipelinePath();
                string CorePath             = HDEditorUtils.GetCorePath();

                newAsset.defaultDiffuseMaterial = Load <Material>(HDRenderPipelinePath + "RenderPipelineResources/DefaultHDMaterial.mat");
                newAsset.defaultDecalMaterial   = Load <Material>(HDRenderPipelinePath + "RenderPipelineResources/DefaultHDDecalMaterial.mat");
                newAsset.defaultShader          = Load <Shader>(HDRenderPipelinePath + "Material/Lit/Lit.shader");

                newAsset.debugFontTexture               = Load <Texture2D>(HDRenderPipelinePath + "RenderPipelineResources/DebugFont.tga");
                newAsset.debugDisplayLatlongShader      = Load <Shader>(HDRenderPipelinePath + "Debug/DebugDisplayLatlong.Shader");
                newAsset.debugViewMaterialGBufferShader = Load <Shader>(HDRenderPipelinePath + "Debug/DebugViewMaterialGBuffer.Shader");
                newAsset.debugViewTilesShader           = Load <Shader>(HDRenderPipelinePath + "Debug/DebugViewTiles.Shader");
                newAsset.debugFullScreenShader          = Load <Shader>(HDRenderPipelinePath + "Debug/DebugFullScreen.Shader");
                newAsset.debugColorPickerShader         = Load <Shader>(HDRenderPipelinePath + "Debug/DebugColorPicker.Shader");

                newAsset.deferredShader    = Load <Shader>(HDRenderPipelinePath + "Lighting/Deferred.Shader");
                newAsset.colorPyramidCS    = Load <ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ColorPyramid.compute");
                newAsset.depthPyramidCS    = Load <ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/DepthPyramid.compute");
                newAsset.copyChannelCS     = Load <ComputeShader>(CorePath + "CoreResources/GPUCopy.compute");
                newAsset.texturePaddingCS  = Load <ComputeShader>(CorePath + "CoreResources/TexturePadding.compute");
                newAsset.applyDistortionCS = Load <ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ApplyDistorsion.compute");

                newAsset.clearDispatchIndirectShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/cleardispatchindirect.compute");
                newAsset.buildDispatchIndirectShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/builddispatchindirect.compute");
                newAsset.buildScreenAABBShader          = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/scrbound.compute");
                newAsset.buildPerTileLightListShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/lightlistbuild.compute");
                newAsset.buildPerBigTileLightListShader = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/lightlistbuild-bigtile.compute");
                newAsset.buildPerVoxelLightListShader   = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/lightlistbuild-clustered.compute");
                newAsset.buildMaterialFlagsShader       = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/materialflags.compute");
                newAsset.deferredComputeShader          = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/Deferred.compute");

                newAsset.deferredDirectionalShadowComputeShader = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/DeferredDirectionalShadow.compute");
                newAsset.volumeVoxelizationCS = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/Volumetrics/VolumeVoxelization.compute");
                newAsset.volumetricLightingCS = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/Volumetrics/VolumetricLighting.compute");

                newAsset.subsurfaceScatteringCS = Load <ComputeShader>(HDRenderPipelinePath + "Material/SubsurfaceScattering/SubsurfaceScattering.compute");
                newAsset.subsurfaceScattering   = Load <Shader>(HDRenderPipelinePath + "Material/SubsurfaceScattering/SubsurfaceScattering.shader");
                newAsset.combineLighting        = Load <Shader>(HDRenderPipelinePath + "Material/SubsurfaceScattering/CombineLighting.shader");

                // General
                newAsset.cameraMotionVectors = Load <Shader>(HDRenderPipelinePath + "RenderPipelineResources/CameraMotionVectors.shader");
                newAsset.copyStencilBuffer   = Load <Shader>(HDRenderPipelinePath + "RenderPipelineResources/CopyStencilBuffer.shader");
                newAsset.copyDepthBuffer     = Load <Shader>(HDRenderPipelinePath + "RenderPipelineResources/CopyDepthBuffer.shader");
                newAsset.blit = Load <Shader>(HDRenderPipelinePath + "RenderPipelineResources/Blit.shader");

                // Sky
                newAsset.blitCubemap                 = Load <Shader>(HDRenderPipelinePath + "Sky/BlitCubemap.shader");
                newAsset.buildProbabilityTables      = Load <ComputeShader>(HDRenderPipelinePath + "Material/GGXConvolution/BuildProbabilityTables.compute");
                newAsset.computeGgxIblSampleData     = Load <ComputeShader>(HDRenderPipelinePath + "Material/GGXConvolution/ComputeGgxIblSampleData.compute");
                newAsset.GGXConvolve                 = Load <Shader>(HDRenderPipelinePath + "Material/GGXConvolution/GGXConvolve.shader");
                newAsset.opaqueAtmosphericScattering = Load <Shader>(HDRenderPipelinePath + "Sky/OpaqueAtmosphericScattering.shader");
                newAsset.hdriSky       = Load <Shader>(HDRenderPipelinePath + "Sky/HDRISky/HDRISky.shader");
                newAsset.proceduralSky = Load <Shader>(HDRenderPipelinePath + "Sky/ProceduralSky/ProceduralSky.shader");

                // Utilities / Core
                newAsset.encodeBC6HCS        = Load <ComputeShader>(CorePath + "CoreResources/EncodeBC6H.compute");
                newAsset.cubeToPanoShader    = Load <Shader>(CorePath + "CoreResources/CubeToPano.shader");
                newAsset.blitCubeTextureFace = Load <Shader>(CorePath + "CoreResources/BlitCubeTextureFace.shader");

                // Skybox/Cubemap is a builtin shader, must use Sahder.Find to access it. It is fine because we are in the editor
                newAsset.skyboxCubemap = Shader.Find("Skybox/Cubemap");

                // Shadow
                newAsset.shadowClearShader    = Load <Shader>(CorePath + "Shadow/ShadowClear.shader");
                newAsset.shadowBlurMoments    = Load <ComputeShader>(CorePath + "Shadow/ShadowBlurMoments.compute");
                newAsset.debugShadowMapShader = Load <Shader>(CorePath + "Shadow/DebugDisplayShadowMap.shader");

                AssetDatabase.CreateAsset(newAsset, pathName);
                ProjectWindowUtil.ShowCreatedAsset(newAsset);
            }
Ejemplo n.º 4
0
        private static bool GenerateShaderPass(UnlitMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List <string> sourceAssetDependencyPaths)
        {
            var templateLocation = Path.Combine(Path.Combine(Path.Combine(HDEditorUtils.GetHDRenderPipelinePath(), "Editor"), "ShaderGraph"), pass.TemplateName);

            if (!File.Exists(templateLocation))
            {
                // TODO: produce error here
                return(false);
            }

            sourceAssetDependencyPaths.Add(templateLocation);

            // grab all of the active nodes
            var activeNodeList = ListPool <INode> .Get();

            NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);

            // graph requirements describe what the graph itself requires
            var graphRequirements = ShaderGraphRequirements.FromNodes(activeNodeList, ShaderStageCapability.All, true, true);

            ShaderStringBuilder graphNodeFunctions = new ShaderStringBuilder();

            graphNodeFunctions.IncreaseIndent();
            var functionRegistry = new FunctionRegistry(graphNodeFunctions);

            // Build the list of active slots based on what the pass requires
            // TODO: this can be a shared function -- From here through GraphUtil.GenerateSurfaceDescription(..)
            var activeSlots = new List <MaterialSlot>();

            foreach (var id in pass.PixelShaderSlots)
            {
                MaterialSlot slot = masterNode.FindSlot <MaterialSlot>(id);
                if (slot != null)
                {
                    activeSlots.Add(slot);
                }
            }

            // build the graph outputs structure to hold the results of each active slots (and fill out activeFields to indicate they are active)
            string            graphInputStructName  = "SurfaceDescriptionInputs";
            string            graphOutputStructName = "SurfaceDescription";
            string            graphEvalFunctionName = "SurfaceDescriptionFunction";
            var               graphEvalFunction     = new ShaderStringBuilder();
            var               graphOutputs          = new ShaderStringBuilder();
            PropertyCollector graphProperties       = new PropertyCollector();

            // build the graph outputs structure, and populate activeFields with the fields of that structure
            HashSet <string> activeFields = new HashSet <string>();

            GraphUtil.GenerateSurfaceDescriptionStruct(graphOutputs, activeSlots, true);

            // Build the graph evaluation code, to evaluate the specified slots
            GraphUtil.GenerateSurfaceDescriptionFunction(
                activeNodeList,
                masterNode,
                masterNode.owner as AbstractMaterialGraph,
                graphEvalFunction,
                functionRegistry,
                graphProperties,
                graphRequirements,  // TODO : REMOVE UNUSED
                mode,
                graphEvalFunctionName,
                graphOutputStructName,
                null,
                activeSlots,
                graphInputStructName);

            var blendCode     = new ShaderStringBuilder();
            var cullCode      = new ShaderStringBuilder();
            var zTestCode     = new ShaderStringBuilder();
            var zWriteCode    = new ShaderStringBuilder();
            var stencilCode   = new ShaderStringBuilder();
            var colorMaskCode = new ShaderStringBuilder();

            HDSubShaderUtilities.BuildRenderStatesFromPassAndMaterialOptions(pass, materialOptions, blendCode, cullCode, zTestCode, zWriteCode, stencilCode, colorMaskCode);

            if (masterNode.twoSided.isOn)
            {
                activeFields.Add("DoubleSided");
                if (pass.ShaderPassName != "SHADERPASS_VELOCITY")   // HACK to get around lack of a good interpolator dependency system
                {                                                   // we need to be able to build interpolators using multiple input structs
                                                                    // also: should only require isFrontFace if Normals are required...
                    activeFields.Add("DoubleSided.Mirror");         // TODO: change this depending on what kind of normal flip you want..
                    activeFields.Add("FragInputs.isFrontFace");     // will need this for determining normal flip mode
                }
            }

            if (pass.PixelShaderSlots != null)
            {
                foreach (var slotId in pass.PixelShaderSlots)
                {
                    var slot = masterNode.FindSlot <MaterialSlot>(slotId);
                    if (slot != null)
                    {
                        var rawSlotName    = slot.RawDisplayName().ToString();
                        var descriptionVar = string.Format("{0}.{1}", graphOutputStructName, rawSlotName);
                        activeFields.Add(descriptionVar);
                    }
                }
            }

            var packedInterpolatorCode = new ShaderGenerator();
            var graphInputs            = new ShaderGenerator();

            HDRPShaderStructs.Generate(
                packedInterpolatorCode,
                graphInputs,
                graphRequirements,
                pass.RequiredFields,
                CoordinateSpace.World,
                activeFields);

            // debug output all active fields
            var interpolatorDefines = new ShaderGenerator();
            {
                interpolatorDefines.AddShaderChunk("// ACTIVE FIELDS:");
                foreach (string f in activeFields)
                {
                    interpolatorDefines.AddShaderChunk("//   " + f);
                }
            }

            ShaderGenerator defines = new ShaderGenerator();
            {
                defines.AddShaderChunk(string.Format("#define SHADERPASS {0}", pass.ShaderPassName), true);
                if (pass.ExtraDefines != null)
                {
                    foreach (var define in pass.ExtraDefines)
                    {
                        defines.AddShaderChunk(define);
                    }
                }
                defines.AddGenerator(interpolatorDefines);
            }

            var shaderPassIncludes = new ShaderGenerator();

            if (pass.Includes != null)
            {
                foreach (var include in pass.Includes)
                {
                    shaderPassIncludes.AddShaderChunk(include);
                }
            }


            // build graph code
            var graph = new ShaderGenerator();

            graph.AddShaderChunk("// Graph Inputs");
            graph.Indent();
            graph.AddGenerator(graphInputs);
            graph.Deindent();
            graph.AddShaderChunk("// Graph Outputs");
            graph.Indent();
            graph.AddShaderChunk(graphOutputs.ToString());
            //graph.AddGenerator(graphOutputs);
            graph.Deindent();
            graph.AddShaderChunk("// Graph Properties (uniform inputs)");
            graph.AddShaderChunk(graphProperties.GetPropertiesDeclaration(1));
            graph.AddShaderChunk("// Graph Node Functions");
            graph.AddShaderChunk(graphNodeFunctions.ToString());
            graph.AddShaderChunk("// Graph Evaluation");
            graph.Indent();
            graph.AddShaderChunk(graphEvalFunction.ToString());
            //graph.AddGenerator(graphEvalFunction);
            graph.Deindent();

            // build the hash table of all named fragments      TODO: could make this Dictionary<string, ShaderGenerator / string>  ?
            Dictionary <string, string> namedFragments = new Dictionary <string, string>();

            namedFragments.Add("${Defines}", defines.GetShaderString(2, false));
            namedFragments.Add("${Graph}", graph.GetShaderString(2, false));
            namedFragments.Add("${LightMode}", pass.LightMode);
            namedFragments.Add("${PassName}", pass.Name);
            namedFragments.Add("${Includes}", shaderPassIncludes.GetShaderString(2, false));
            namedFragments.Add("${InterpolatorPacking}", packedInterpolatorCode.GetShaderString(2, false));
            namedFragments.Add("${Blending}", blendCode.ToString());
            namedFragments.Add("${Culling}", cullCode.ToString());
            namedFragments.Add("${ZTest}", zTestCode.ToString());
            namedFragments.Add("${ZWrite}", zWriteCode.ToString());
            namedFragments.Add("${Stencil}", stencilCode.ToString());
            namedFragments.Add("${ColorMask}", colorMaskCode.ToString());
            namedFragments.Add("${LOD}", materialOptions.lod.ToString());
            namedFragments.Add("${VariantDefines}", GetVariantDefines(masterNode));

            // process the template to generate the shader code for this pass   TODO: could make this a shared function
            string[] templateLines            = File.ReadAllLines(templateLocation);
            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            foreach (string line in templateLines)
            {
                ShaderSpliceUtil.PreprocessShaderCode(line, activeFields, namedFragments, builder);
                builder.AppendLine();
            }

            result.AddShaderChunk(builder.ToString(), false);

            return(true);
        }
Ejemplo n.º 5
0
        private static bool GenerateShaderPassLit(AbstractMaterialNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions, ShaderGenerator result, List <string> sourceAssetDependencyPaths)
        {
            var templateLocation = Path.Combine(Path.Combine(Path.Combine(HDEditorUtils.GetHDRenderPipelinePath(), "Editor"), "ShaderGraph"), pass.TemplateName);

            if (!File.Exists(templateLocation))
            {
                // TODO: produce error here
                return(false);
            }

            if (sourceAssetDependencyPaths != null)
            {
                sourceAssetDependencyPaths.Add(templateLocation);
            }

            // grab all of the active nodes (for pixel and vertex graphs)
            var vertexNodes = ListPool <INode> .Get();

            NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);

            var pixelNodes = ListPool <INode> .Get();

            NodeUtils.DepthFirstCollectNodesFromNode(pixelNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);

            // graph requirements describe what the graph itself requires
            var pixelRequirements  = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false);  // TODO: is ShaderStageCapability.Fragment correct?
            var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false);

            // Function Registry tracks functions to remove duplicates, it wraps a string builder that stores the combined function string
            ShaderStringBuilder graphNodeFunctions = new ShaderStringBuilder();

            graphNodeFunctions.IncreaseIndent();
            var functionRegistry = new FunctionRegistry(graphNodeFunctions);

            // TODO: this can be a shared function for all HDRP master nodes -- From here through GraphUtil.GenerateSurfaceDescription(..)

            // Build the list of active slots based on what the pass requires
            var pixelSlots  = HDSubShaderUtilities.FindMaterialSlotsOnNode(pass.PixelShaderSlots, masterNode);
            var vertexSlots = HDSubShaderUtilities.FindMaterialSlotsOnNode(pass.VertexShaderSlots, masterNode);

            // properties used by either pixel and vertex shader
            PropertyCollector sharedProperties = new PropertyCollector();

            // build the graph outputs structure to hold the results of each active slots (and fill out activeFields to indicate they are active)
            string pixelGraphInputStructName           = "SurfaceDescriptionInputs";
            string pixelGraphOutputStructName          = "SurfaceDescription";
            string pixelGraphEvalFunctionName          = "SurfaceDescriptionFunction";
            ShaderStringBuilder pixelGraphEvalFunction = new ShaderStringBuilder();
            ShaderStringBuilder pixelGraphOutputs      = new ShaderStringBuilder();

            // dependency tracker -- set of active fields
            HashSet <string> activeFields = GetActiveFieldsFromMasterNode(masterNode, pass);

            // build initial requirements
            HDRPShaderStructs.AddActiveFieldsFromPixelGraphRequirements(activeFields, pixelRequirements);

            // build the graph outputs structure, and populate activeFields with the fields of that structure
            GraphUtil.GenerateSurfaceDescriptionStruct(pixelGraphOutputs, pixelSlots, true, pixelGraphOutputStructName, activeFields);

            // Build the graph evaluation code, to evaluate the specified slots
            GraphUtil.GenerateSurfaceDescriptionFunction(
                pixelNodes,
                masterNode,
                masterNode.owner as AbstractMaterialGraph,
                pixelGraphEvalFunction,
                functionRegistry,
                sharedProperties,
                pixelRequirements,  // TODO : REMOVE UNUSED
                mode,
                pixelGraphEvalFunctionName,
                pixelGraphOutputStructName,
                null,
                pixelSlots,
                pixelGraphInputStructName);

            string vertexGraphInputStructName           = "VertexDescriptionInputs";
            string vertexGraphOutputStructName          = "VertexDescription";
            string vertexGraphEvalFunctionName          = "VertexDescriptionFunction";
            ShaderStringBuilder vertexGraphEvalFunction = new ShaderStringBuilder();
            ShaderStringBuilder vertexGraphOutputs      = new ShaderStringBuilder();

            // check for vertex animation -- enables HAVE_VERTEX_MODIFICATION
            bool vertexActive = false;

            if (masterNode.IsSlotConnected(PBRMasterNode.PositionSlotId))
            {
                vertexActive = true;
                activeFields.Add("features.modifyMesh");
                HDRPShaderStructs.AddActiveFieldsFromVertexGraphRequirements(activeFields, vertexRequirements);

                // -------------------------------------
                // Generate Output structure for Vertex Description function
                GraphUtil.GenerateVertexDescriptionStruct(vertexGraphOutputs, vertexSlots, vertexGraphOutputStructName, activeFields);

                // -------------------------------------
                // Generate Vertex Description function
                GraphUtil.GenerateVertexDescriptionFunction(
                    masterNode.owner as AbstractMaterialGraph,
                    vertexGraphEvalFunction,
                    functionRegistry,
                    sharedProperties,
                    mode,
                    vertexNodes,
                    vertexSlots,
                    vertexGraphInputStructName,
                    vertexGraphEvalFunctionName,
                    vertexGraphOutputStructName);
            }

            var blendCode     = new ShaderStringBuilder();
            var cullCode      = new ShaderStringBuilder();
            var zTestCode     = new ShaderStringBuilder();
            var zWriteCode    = new ShaderStringBuilder();
            var stencilCode   = new ShaderStringBuilder();
            var colorMaskCode = new ShaderStringBuilder();

            HDSubShaderUtilities.BuildRenderStatesFromPassAndMaterialOptions(pass, materialOptions, blendCode, cullCode, zTestCode, zWriteCode, stencilCode, colorMaskCode);

            HDRPShaderStructs.AddRequiredFields(pass.RequiredFields, activeFields);

            // apply dependencies to the active fields, and build interpolators (TODO: split this function)
            var packedInterpolatorCode = new ShaderGenerator();

            HDRPShaderStructs.Generate(
                packedInterpolatorCode,
                activeFields);

            // debug output all active fields
            var interpolatorDefines = new ShaderGenerator();
            {
                interpolatorDefines.AddShaderChunk("// ACTIVE FIELDS:");
                foreach (string f in activeFields)
                {
                    interpolatorDefines.AddShaderChunk("//   " + f);
                }
            }

            // build graph inputs structures
            ShaderGenerator pixelGraphInputs = new ShaderGenerator();

            ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.SurfaceDescriptionInputs), activeFields, pixelGraphInputs);
            ShaderGenerator vertexGraphInputs = new ShaderGenerator();

            ShaderSpliceUtil.BuildType(typeof(HDRPShaderStructs.VertexDescriptionInputs), activeFields, vertexGraphInputs);

            ShaderGenerator defines = new ShaderGenerator();
            {
                defines.AddShaderChunk(string.Format("#define SHADERPASS {0}", pass.ShaderPassName), true);
                if (pass.ExtraDefines != null)
                {
                    foreach (var define in pass.ExtraDefines)
                    {
                        defines.AddShaderChunk(define);
                    }
                }
                defines.AddGenerator(interpolatorDefines);
            }

            var shaderPassIncludes = new ShaderGenerator();

            if (pass.Includes != null)
            {
                foreach (var include in pass.Includes)
                {
                    shaderPassIncludes.AddShaderChunk(include);
                }
            }


            // build graph code
            var graph = new ShaderGenerator();
            {
                graph.AddShaderChunk("// Shared Graph Properties (uniform inputs)");
                graph.AddShaderChunk(sharedProperties.GetPropertiesDeclaration(1));

                if (vertexActive)
                {
                    graph.AddShaderChunk("// Vertex Graph Inputs");
                    graph.Indent();
                    graph.AddGenerator(vertexGraphInputs);
                    graph.Deindent();
                    graph.AddShaderChunk("// Vertex Graph Outputs");
                    graph.Indent();
                    graph.AddShaderChunk(vertexGraphOutputs.ToString());
                    graph.Deindent();
                }

                graph.AddShaderChunk("// Pixel Graph Inputs");
                graph.Indent();
                graph.AddGenerator(pixelGraphInputs);
                graph.Deindent();
                graph.AddShaderChunk("// Pixel Graph Outputs");
                graph.Indent();
                graph.AddShaderChunk(pixelGraphOutputs.ToString());
                graph.Deindent();

                graph.AddShaderChunk("// Shared Graph Node Functions");
                graph.AddShaderChunk(graphNodeFunctions.ToString());

                if (vertexActive)
                {
                    graph.AddShaderChunk("// Vertex Graph Evaluation");
                    graph.Indent();
                    graph.AddShaderChunk(vertexGraphEvalFunction.ToString());
                    graph.Deindent();
                }

                graph.AddShaderChunk("// Pixel Graph Evaluation");
                graph.Indent();
                graph.AddShaderChunk(pixelGraphEvalFunction.ToString());
                graph.Deindent();
            }

            // build the hash table of all named fragments      TODO: could make this Dictionary<string, ShaderGenerator / string>  ?
            Dictionary <string, string> namedFragments = new Dictionary <string, string>();

            namedFragments.Add("${Defines}", defines.GetShaderString(2, false));
            namedFragments.Add("${Graph}", graph.GetShaderString(2, false));
            namedFragments.Add("${LightMode}", pass.LightMode);
            namedFragments.Add("${PassName}", pass.Name);
            namedFragments.Add("${Includes}", shaderPassIncludes.GetShaderString(2, false));
            namedFragments.Add("${InterpolatorPacking}", packedInterpolatorCode.GetShaderString(2, false));
            namedFragments.Add("${Blending}", blendCode.ToString());
            namedFragments.Add("${Culling}", cullCode.ToString());
            namedFragments.Add("${ZTest}", zTestCode.ToString());
            namedFragments.Add("${ZWrite}", zWriteCode.ToString());
            namedFragments.Add("${Stencil}", stencilCode.ToString());
            namedFragments.Add("${ColorMask}", colorMaskCode.ToString());
            namedFragments.Add("${LOD}", materialOptions.lod.ToString());

            // process the template to generate the shader code for this pass   TODO: could make this a shared function
            string[] templateLines            = File.ReadAllLines(templateLocation);
            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            foreach (string line in templateLines)
            {
                ShaderSpliceUtil.PreprocessShaderCode(line, activeFields, namedFragments, builder);
                builder.AppendLine();
            }

            result.AddShaderChunk(builder.ToString(), false);

            return(true);
        }
            public override void Action(int instanceId, string pathName, string resourceFile)
            {
                var newAsset = CreateInstance <RenderPipelineResources>();

                newAsset.name = Path.GetFileName(pathName);

                // Load default renderPipelineResources / Material / Shader
                string HDRenderPipelinePath = HDEditorUtils.GetHDRenderPipelinePath();
                string PostProcessingPath   = HDEditorUtils.GetPostProcessingPath();
                string CorePath             = HDEditorUtils.GetCorePath();

                newAsset.debugDisplayLatlongShader      = Load <Shader>(HDRenderPipelinePath + "Debug/DebugDisplayLatlong.Shader");
                newAsset.debugViewMaterialGBufferShader = Load <Shader>(HDRenderPipelinePath + "Debug/DebugViewMaterialGBuffer.Shader");
                newAsset.debugViewTilesShader           = Load <Shader>(HDRenderPipelinePath + "Debug/DebugViewTiles.Shader");
                newAsset.debugFullScreenShader          = Load <Shader>(HDRenderPipelinePath + "Debug/DebugFullScreen.Shader");

                newAsset.deferredShader    = Load <Shader>(HDRenderPipelinePath + "Lighting/Deferred.Shader");
                newAsset.gaussianPyramidCS = Load <ComputeShader>(PostProcessingPath + "Shaders/Builtins/GaussianDownsample.compute");
                newAsset.depthPyramidCS    = Load <ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/DepthDownsample.compute");
                newAsset.copyChannelCS     = Load <ComputeShader>(CorePath + "Resources/GPUCopy.compute");
                newAsset.applyDistortionCS = Load <ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ApplyDistorsion.compute");

                newAsset.clearDispatchIndirectShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/cleardispatchindirect.compute");
                newAsset.buildDispatchIndirectShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/builddispatchindirect.compute");
                newAsset.buildScreenAABBShader          = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/scrbound.compute");
                newAsset.buildPerTileLightListShader    = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/lightlistbuild.compute");
                newAsset.buildPerBigTileLightListShader = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/lightlistbuild-bigtile.compute");
                newAsset.buildPerVoxelLightListShader   = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/lightlistbuild-clustered.compute");
                newAsset.buildMaterialFlagsShader       = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/materialflags.compute");
                newAsset.deferredComputeShader          = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/LightLoop/Deferred.compute");

                newAsset.deferredDirectionalShadowComputeShader = Load <ComputeShader>(HDRenderPipelinePath + "Lighting/DeferredDirectionalShadow.compute");

                // SubsurfaceScattering
                // These shaders don't need to be reference by RenderPipelineResource as they are not use at runtime (only to draw in editor)
                // instance.drawSssProfile = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>(HDRenderPipelinePath + "SceneSettings/DrawSssProfile.shader");
                // instance.drawTransmittanceGraphShader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>(HDRenderPipelinePath + "SceneSettings/DrawTransmittanceGraph.shader");

                newAsset.subsurfaceScatteringCS = Load <ComputeShader>(HDRenderPipelinePath + "Material/SubsurfaceScattering/SubsurfaceScattering.compute");
                newAsset.subsurfaceScattering   = Load <Shader>(HDRenderPipelinePath + "Material/SubsurfaceScattering/SubsurfaceScattering.shader");
                newAsset.combineLighting        = Load <Shader>(HDRenderPipelinePath + "Material/SubsurfaceScattering/CombineLighting.shader");

                // General
                newAsset.cameraMotionVectors = Load <Shader>(HDRenderPipelinePath + "RenderPipelineResources/CameraMotionVectors.shader");
                newAsset.copyStencilBuffer   = Load <Shader>(HDRenderPipelinePath + "RenderPipelineResources/copyStencilBuffer.shader");

                // Sky
                newAsset.blitCubemap                 = Load <Shader>(HDRenderPipelinePath + "Sky/BlitCubemap.shader");
                newAsset.buildProbabilityTables      = Load <ComputeShader>(HDRenderPipelinePath + "Material/GGXConvolution/BuildProbabilityTables.compute");
                newAsset.computeGgxIblSampleData     = Load <ComputeShader>(HDRenderPipelinePath + "Material/GGXConvolution/ComputeGgxIblSampleData.compute");
                newAsset.GGXConvolve                 = Load <Shader>(HDRenderPipelinePath + "Material/GGXConvolution/GGXConvolve.shader");
                newAsset.opaqueAtmosphericScattering = Load <Shader>(HDRenderPipelinePath + "Sky/OpaqueAtmosphericScattering.shader");

                newAsset.encodeBC6HCS = Load <ComputeShader>(CorePath + "Resources/EncodeBC6H.compute");

                // Skybox/Cubemap is a builtin shader, must use Sahder.Find to access it. It is fine because we are in the editor
                newAsset.skyboxCubemap = Shader.Find("Skybox/Cubemap");

                AssetDatabase.CreateAsset(newAsset, pathName);
                ProjectWindowUtil.ShowCreatedAsset(newAsset);
            }