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);
        }
        public HDRPreprocessShaders()
        {
            // TODO: Grab correct configuration/quality asset.
            if (ShaderBuildPreprocessor.hdrpAssets == null || ShaderBuildPreprocessor.hdrpAssets.Count == 0)
            {
                return;
            }

            shaderProcessorsList = HDEditorUtils.GetBaseShaderPreprocessorList();
        }
Beispiel #3
0
 static void Drawer_SectionCookies(SerializedHDRenderPipelineAsset serialized, Editor owner)
 {
     EditorGUILayout.PropertyField(serialized.renderPipelineSettings.lightLoopSettings.cookieSize, k_CoockieSizeContent);
     EditorGUI.BeginChangeCheck();
     EditorGUILayout.DelayedIntField(serialized.renderPipelineSettings.lightLoopSettings.cookieTexArraySize, k_CookieTextureArraySizeContent);
     if (EditorGUI.EndChangeCheck())
     {
         serialized.renderPipelineSettings.lightLoopSettings.cookieTexArraySize.intValue = Mathf.Clamp(serialized.renderPipelineSettings.lightLoopSettings.cookieTexArraySize.intValue, 1, TextureCache.k_MaxSupported);
     }
     if (serialized.renderPipelineSettings.lightLoopSettings.cookieTexArraySize.hasMultipleDifferentValues)
     {
         EditorGUILayout.HelpBox(k_MultipleDifferenteValueMessage, MessageType.Info);
     }
     else
     {
         long currentCache = TextureCache2D.GetApproxCacheSizeInByte(serialized.renderPipelineSettings.lightLoopSettings.cookieTexArraySize.intValue, serialized.renderPipelineSettings.lightLoopSettings.cookieSize.intValue, 1);
         if (currentCache > HDRenderPipeline.k_MaxCacheSize)
         {
             int    reserved = TextureCache2D.GetMaxCacheSizeForWeightInByte(HDRenderPipeline.k_MaxCacheSize, serialized.renderPipelineSettings.lightLoopSettings.cookieSize.intValue, 1);
             string message  = string.Format(k_CacheErrorFormat, HDEditorUtils.HumanizeWeight(currentCache), reserved);
             EditorGUILayout.HelpBox(message, MessageType.Error);
         }
         else
         {
             string message = string.Format(k_CacheInfoFormat, HDEditorUtils.HumanizeWeight(currentCache));
             EditorGUILayout.HelpBox(message, MessageType.Info);
         }
     }
     EditorGUILayout.PropertyField(serialized.renderPipelineSettings.lightLoopSettings.pointCookieSize, k_PointCoockieSizeContent);
     EditorGUI.BeginChangeCheck();
     EditorGUILayout.DelayedIntField(serialized.renderPipelineSettings.lightLoopSettings.cubeCookieTexArraySize, k_PointCookieTextureArraySizeContent);
     if (EditorGUI.EndChangeCheck())
     {
         serialized.renderPipelineSettings.lightLoopSettings.cubeCookieTexArraySize.intValue = Mathf.Clamp(serialized.renderPipelineSettings.lightLoopSettings.cubeCookieTexArraySize.intValue, 1, TextureCache.k_MaxSupported);
     }
     if (serialized.renderPipelineSettings.lightLoopSettings.cubeCookieTexArraySize.hasMultipleDifferentValues)
     {
         EditorGUILayout.HelpBox(k_MultipleDifferenteValueMessage, MessageType.Info);
     }
     else
     {
         long currentCache = TextureCacheCubemap.GetApproxCacheSizeInByte(serialized.renderPipelineSettings.lightLoopSettings.cubeCookieTexArraySize.intValue, serialized.renderPipelineSettings.lightLoopSettings.pointCookieSize.intValue, 1);
         if (currentCache > HDRenderPipeline.k_MaxCacheSize)
         {
             int    reserved = TextureCacheCubemap.GetMaxCacheSizeForWeightInByte(HDRenderPipeline.k_MaxCacheSize, serialized.renderPipelineSettings.lightLoopSettings.pointCookieSize.intValue, 1);
             string message  = string.Format(k_CacheErrorFormat, HDEditorUtils.HumanizeWeight(currentCache), reserved);
             EditorGUILayout.HelpBox(message, MessageType.Error);
         }
         else
         {
             string message = string.Format(k_CacheInfoFormat, HDEditorUtils.HumanizeWeight(currentCache));
             EditorGUILayout.HelpBox(message, MessageType.Info);
         }
     }
 }
Beispiel #4
0
        public HDRPreprocessShaders()
        {
            // TODO: Grab correct configuration/quality asset.
            HDRenderPipelineAsset hdPipelineAsset = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;

            if (hdPipelineAsset == null)
            {
                return;
            }

            materialList = HDEditorUtils.GetBaseShaderPreprocessorList();
        }
        public HDRPreprocessShaders()
        {
            // TODO: Grab correct configuration/quality asset.
            HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;

            if (hdPipeline != null)
            {
                m_CurrentHDRPAsset = hdPipeline.asset;

                materialList = HDEditorUtils.GetBaseShaderPreprocessorList();
            }
        }
        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();
        }
Beispiel #7
0
        void DrawShaderGraphGUI()
        {
            // Filter out properties we don't want to draw:
            PropertiesDefaultGUI(properties);

            // If we change a property in a shadergraph, we trigger a material keyword reset
            if (CheckPropertyChanged(properties))
            {
                foreach (var material in materials)
                {
                    HDEditorUtils.ResetMaterialKeywords(material);
                }
            }

            if (properties.Length > 0)
            {
                EditorGUILayout.Space();
            }

            if ((m_Features & Features.DiffusionProfileAsset) != 0)
            {
                DrawDiffusionProfileUI();
            }

            if ((m_Features & Features.EnableInstancing) != 0)
            {
                materialEditor.EnableInstancingField();
            }

            if ((m_Features & Features.DoubleSidedGI) != 0)
            {
                // If the shader graph have a double sided flag, then we don't display this field.
                // The double sided GI value will be synced with the double sided property during the SetupBaseUnlitKeywords()
                if (!materials[0].HasProperty(kDoubleSidedEnable))
                {
                    materialEditor.DoubleSidedGIField();
                }
            }

            if ((m_Features & Features.EmissionGI) != 0)
            {
                DrawEmissionGI();
            }

            if ((m_Features & Features.MotionVector) != 0)
            {
                DrawMotionVectorToggle();
            }
        }
            // Tool bars
            public static void DrawToolbars(SerializedHDProbe serialized, Editor owner)
            {
                var provider = new TProvider();

                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                GUI.changed = false;

                for (int i = 0; i < k_ListModes.Length; ++i)
                {
                    EditMode.DoInspectorToolbar(k_ListModes[i], k_ListContent[i], HDEditorUtils.GetBoundsGetter(owner), owner);
                }

                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
            }
Beispiel #9
0
        public static SettingsProvider CreateSettingsProvider()
        {
            return(new SettingsProvider("Project/Quality/HDRP", SettingsScope.Project)
            {
                activateHandler = (searchContext, rootElement) =>
                {
                    HDEditorUtils.AddStyleSheets(rootElement);

                    var panel = new QualitySettingsPanelVisualElement(searchContext);
                    panel.style.flexGrow = 1;

                    rootElement.Add(panel);
                },
                keywords = new [] { "quality", "hdrp" }
            });
        }
Beispiel #10
0
        static void ResetAllLoadedMaterialKeywords(string descriptionPrefix, float progressScale, float progressOffset)
        {
            var materials = Resources.FindObjectsOfTypeAll <Material>();

            bool VSCEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);

            for (int i = 0, length = materials.Length; i < length; i++)
            {
                EditorUtility.DisplayProgressBar(
                    "Setup materials Keywords...",
                    string.Format("{0}{1} / {2} materials cleaned.", descriptionPrefix, i, length),
                    (i / (float)(length - 1)) * progressScale + progressOffset);

                CheckOutFile(VSCEnabled, materials[i]);
                HDEditorUtils.ResetMaterialKeywords(materials[i]);
            }
        }
        public HDRPreprocessShaders()
        {
            // Samplegame hack
            m_CurrentHDRPAsset = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
            materialList       = HDEditorUtils.GetBaseShaderPreprocessorList();

            // EXISTING CODE; BROKEN WHEN BUILDING BATCHMOD

            /*
             * // TODO: Grab correct configuration/quality asset.
             * HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
             * if (hdPipeline != null)
             * {
             *  m_CurrentHDRPAsset = hdPipeline.asset;
             *
             *  materialList = HDEditorUtils.GetBaseShaderPreprocessorList();
             * }
             */
        }
Beispiel #12
0
        public HDRPreprocessShaders()
        {
            // TODO: Grab correct configuration/quality asset.
            HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;

            if (hdPipeline != null)
            {
                m_CurrentHDRPAsset = hdPipeline.asset;
            }

            m_StripperFuncs = new Dictionary <string, VariantStrippingFunc>();

            List <BaseShaderPreprocessor> materialList = HDEditorUtils.GetBaseShaderPreprocessorList();

            // Fill the dictionary with material to handle
            foreach (BaseShaderPreprocessor material in materialList)
            {
                material.AddStripperFuncs(m_StripperFuncs);
            }
        }
Beispiel #13
0
        static void ResetAllMaterialKeywords()
        {
            try
            {
                var materials = Resources.FindObjectsOfTypeAll <Material>();

                for (int i = 0, length = materials.Length; i < length; i++)
                {
                    EditorUtility.DisplayProgressBar(
                        "Setup materials Keywords...",
                        string.Format("{0} / {1} materials cleaned.", i, length),
                        i / (float)(length - 1));

                    HDEditorUtils.ResetMaterialKeywords(materials[i]);
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }
        }
Beispiel #14
0
        // Version 2

        // Update decal material after we added AO and metal selection. It was default to 0 and need to default to 4 now.
        // Also we have rename _SupportDBuffer to _SupportDecals
        static bool UpdateMaterial_Decals_2(string path, Material mat)
        {
            bool dirty = false;

            if (mat.shader.name == "HDRenderPipeline/Decal")
            {
                float maskBlendMode = mat.GetFloat("_MaskBlendMode");

                if (maskBlendMode == 0.0f)
                {
                    mat.SetFloat("_MaskBlendMode", (float)Decal.MaskBlendFlags.Smoothness);
                    dirty = true;
                }
            }
            else
            {
                // Find the missing property in the file and update EmissiveColor
                string[] readText = File.ReadAllLines(path);

                foreach (string line in readText)
                {
                    if (line.Contains("_SupportDBuffer:"))
                    {
                        int    startPos    = line.IndexOf(":") + 1;
                        string sub         = line.Substring(startPos);
                        float  enableDecal = float.Parse(sub);
                        mat.SetFloat("_SupportDecals", enableDecal);

                        // Decal need to also update keywords _DISABLE_DECALS
                        HDEditorUtils.ResetMaterialKeywords(mat);

                        dirty = true;
                    }
                }
            }

            return(dirty);
        }
        static void ResetAllMaterialAssetsKeywords(float progressScale, float progressOffset)
        {
            var matIds = AssetDatabase.FindAssets("t:Material");

            bool VCSEnabled = (UnityEditor.VersionControl.Provider.enabled && UnityEditor.VersionControl.Provider.isActive);

            for (int i = 0, length = matIds.Length; i < length; i++)
            {
                var path = AssetDatabase.GUIDToAssetPath(matIds[i]);
                var mat  = AssetDatabase.LoadAssetAtPath <Material>(path);

                EditorUtility.DisplayProgressBar(
                    "Setup material asset's Keywords...",
                    string.Format("{0} / {1} materials cleaned.", i, length),
                    (i / (float)(length - 1)) * progressScale + progressOffset);

                CoreEditorUtils.CheckOutFile(VCSEnabled, mat);
                var h = Debug.unityLogger.logHandler;
                Debug.unityLogger.logHandler = new UnityContextualLogHandler(mat);
                HDEditorUtils.ResetMaterialKeywords(mat);
                Debug.unityLogger.logHandler = h;
            }
        }
        void UpdateAreaLightEmissiveMeshComponents()
        {
            foreach (var hdLightData in m_AdditionalLightDatas)
            {
                hdLightData.UpdateAreaLightEmissiveMesh();

                MeshRenderer emissiveMeshRenderer = hdLightData.GetComponent <MeshRenderer>();
                MeshFilter   emissiveMeshFilter   = hdLightData.GetComponent <MeshFilter>();

                // If the display emissive mesh is disabled, skip to the next selected light
                if (emissiveMeshFilter == null || emissiveMeshRenderer == null)
                {
                    continue;
                }

                // We only load the mesh and it's material here, because we can't do that inside HDAdditionalLightData (Editor assembly)
                // Every other properties of the mesh is updated in HDAdditionalLightData to support timeline and editor records
                switch (hdLightData.lightTypeExtent)
                {
                case LightTypeExtent.Tube:
                    emissiveMeshFilter.mesh = HDEditorUtils.LoadAsset <Mesh>("Runtime/RenderPipelineResources/Mesh/Cylinder.fbx");
                    break;

                case LightTypeExtent.Rectangle:
                default:
                    emissiveMeshFilter.mesh = HDEditorUtils.LoadAsset <Mesh>("Runtime/RenderPipelineResources/Mesh/Quad.FBX");
                    break;
                }
                if (emissiveMeshRenderer.sharedMaterial == null)
                {
                    emissiveMeshRenderer.sharedMaterial = new Material(Shader.Find("HDRP/Unlit"));
                }
                emissiveMeshRenderer.sharedMaterial.SetFloat("_IncludeIndirectLighting", 0.0f);
            }

            m_SerializedHDLight.needUpdateAreaLightEmissiveMeshComponents = false;
        }
Beispiel #17
0
        static void ResetAllMaterialKeywordsInProject()
        {
            try
            {
                var matIds = AssetDatabase.FindAssets("t:Material");

                for (int i = 0, length = matIds.Length; i < length; i++)
                {
                    var path = AssetDatabase.GUIDToAssetPath(matIds[i]);
                    var mat  = AssetDatabase.LoadAssetAtPath <Material>(path);

                    EditorUtility.DisplayProgressBar(
                        "Setup materials Keywords...",
                        string.Format("{0} / {1} materials cleaned.", i, length),
                        i / (float)(length - 1));

                    HDEditorUtils.ResetMaterialKeywords(mat);
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }
        }
Beispiel #18
0
        static void Execute(CommandLineAction action)
        {
            switch (action.operation)
            {
            case CommandLineOperation.ResetMaterialKeywords:
            {
                Console.WriteLine("[HDEditorCLI][ResetMaterialKeywords] Starting material reset");

                var matIds = AssetDatabase.FindAssets("t:Material");

                for (int i = 0, length = matIds.Length; i < length; i++)
                {
                    var path = AssetDatabase.GUIDToAssetPath(matIds[i]);
                    var mat  = AssetDatabase.LoadAssetAtPath <Material>(path);

                    if (HDEditorUtils.ResetMaterialKeywords(mat))
                    {
                        Console.WriteLine("[HDEditorCLI][ResetMaterialKeywords] " + path);
                    }
                }
                break;
            }
            }
        }
Beispiel #19
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);
            }
Beispiel #20
0
        void UpdateAreaLightEmissiveMesh()
        {
            foreach (var lightData in m_AdditionalLightDatas)
            {
                GameObject   lightGameObject      = lightData.gameObject;
                MeshRenderer emissiveMeshRenderer = lightData.GetComponent <MeshRenderer>();
                MeshFilter   emissiveMeshFilter   = lightData.GetComponent <MeshFilter>();
                Light        light = lightGameObject.GetComponent <Light>();

                bool displayAreaLightEmissiveMesh = IsAreaLightShape(m_LightShape) && m_LightShape != LightShape.Line && m_AdditionalLightData.displayAreaLightEmissiveMesh.boolValue;

                // Ensure that the emissive mesh components are here
                if (displayAreaLightEmissiveMesh)
                {
                    if (emissiveMeshRenderer == null)
                    {
                        emissiveMeshRenderer = lightGameObject.AddComponent <MeshRenderer>();
                    }
                    if (emissiveMeshFilter == null)
                    {
                        emissiveMeshFilter = lightGameObject.AddComponent <MeshFilter>();
                    }
                }
                else // Or remove them if the option is disabled
                {
                    if (emissiveMeshRenderer != null)
                    {
                        DestroyImmediate(emissiveMeshRenderer);
                    }
                    if (emissiveMeshFilter != null)
                    {
                        DestroyImmediate(emissiveMeshFilter);
                    }

                    // Skip to the next light
                    continue;
                }

                float areaLightIntensity = 0.0f;

                // Update Mesh emissive value
                switch (m_LightShape)
                {
                case LightShape.Rectangle:
                    emissiveMeshFilter.mesh = HDEditorUtils.LoadAsset <Mesh>("RenderPipelineResources/Quad.FBX");
                    lightGameObject.transform.localScale = new Vector3(lightData.shapeWidth, lightData.shapeHeight, 0);
                    // Do the same conversion as for light intensity
                    areaLightIntensity = LightUtils.ConvertRectLightIntensity(
                        m_AdditionalLightData.areaIntensity.floatValue,
                        lightData.shapeWidth,
                        lightData.shapeHeight);
                    break;

                default:
                    break;
                }

                if (emissiveMeshRenderer.sharedMaterial == null)
                {
                    emissiveMeshRenderer.material = new Material(Shader.Find("HDRenderPipeline/Unlit"));
                }

                emissiveMeshRenderer.sharedMaterial.SetColor("_UnlitColor", Color.black);
                // Note that we must use the light in linear RGB
                emissiveMeshRenderer.sharedMaterial.SetColor("_EmissiveColor", light.color.linear * areaLightIntensity);
            }
        }
Beispiel #21
0
        static void Drawer_SectionReflection(SerializedHDRenderPipelineAsset serialized, Editor owner)
        {
            EditorGUILayout.PropertyField(serialized.renderPipelineSettings.supportSSR, k_SupportSSRContent);

            EditorGUILayout.Space();

            EditorGUILayout.PropertyField(serialized.renderPipelineSettings.lightLoopSettings.reflectionCacheCompressed, k_CompressProbeCacheContent);
            EditorGUILayout.PropertyField(serialized.renderPipelineSettings.lightLoopSettings.reflectionCubemapSize, k_CubemapSizeContent);
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.DelayedIntField(serialized.renderPipelineSettings.lightLoopSettings.reflectionProbeCacheSize, k_ProbeCacheSizeContent);
            if (EditorGUI.EndChangeCheck())
            {
                serialized.renderPipelineSettings.lightLoopSettings.reflectionProbeCacheSize.intValue = Mathf.Clamp(serialized.renderPipelineSettings.lightLoopSettings.reflectionProbeCacheSize.intValue, 1, TextureCache.k_MaxSupported);
            }
            if (serialized.renderPipelineSettings.lightLoopSettings.reflectionProbeCacheSize.hasMultipleDifferentValues)
            {
                EditorGUILayout.HelpBox(k_MultipleDifferenteValueMessage, MessageType.Info);
            }
            else
            {
                long currentCache = ReflectionProbeCache.GetApproxCacheSizeInByte(serialized.renderPipelineSettings.lightLoopSettings.reflectionProbeCacheSize.intValue, serialized.renderPipelineSettings.lightLoopSettings.reflectionCubemapSize.intValue, serialized.renderPipelineSettings.lightLoopSettings.supportFabricConvolution.boolValue ? 2 : 1);
                if (currentCache > HDRenderPipeline.k_MaxCacheSize)
                {
                    int    reserved = ReflectionProbeCache.GetMaxCacheSizeForWeightInByte(HDRenderPipeline.k_MaxCacheSize, serialized.renderPipelineSettings.lightLoopSettings.reflectionCubemapSize.intValue, serialized.renderPipelineSettings.lightLoopSettings.supportFabricConvolution.boolValue ? 2 : 1);
                    string message  = string.Format(k_CacheErrorFormat, HDEditorUtils.HumanizeWeight(currentCache), reserved);
                    EditorGUILayout.HelpBox(message, MessageType.Error);
                }
                else
                {
                    string message = string.Format(k_CacheInfoFormat, HDEditorUtils.HumanizeWeight(currentCache));
                    EditorGUILayout.HelpBox(message, MessageType.Info);
                }
            }

            EditorGUILayout.Space();

            EditorGUILayout.PropertyField(serialized.renderPipelineSettings.lightLoopSettings.planarReflectionCacheCompressed, k_CompressPlanarProbeCacheContent);
            EditorGUILayout.PropertyField(serialized.renderPipelineSettings.lightLoopSettings.planarReflectionCubemapSize, k_PlanarTextureSizeContent);
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.DelayedIntField(serialized.renderPipelineSettings.lightLoopSettings.planarReflectionProbeCacheSize, k_PlanarProbeCacheSizeContent);
            if (EditorGUI.EndChangeCheck())
            {
                serialized.renderPipelineSettings.lightLoopSettings.planarReflectionProbeCacheSize.intValue = Mathf.Clamp(serialized.renderPipelineSettings.lightLoopSettings.planarReflectionProbeCacheSize.intValue, 1, TextureCache.k_MaxSupported);
            }
            if (serialized.renderPipelineSettings.lightLoopSettings.planarReflectionProbeCacheSize.hasMultipleDifferentValues)
            {
                EditorGUILayout.HelpBox(k_MultipleDifferenteValueMessage, MessageType.Info);
            }
            else
            {
                long currentCache = PlanarReflectionProbeCache.GetApproxCacheSizeInByte(serialized.renderPipelineSettings.lightLoopSettings.planarReflectionProbeCacheSize.intValue, serialized.renderPipelineSettings.lightLoopSettings.planarReflectionCubemapSize.intValue, 1);
                if (currentCache > HDRenderPipeline.k_MaxCacheSize)
                {
                    int    reserved = PlanarReflectionProbeCache.GetMaxCacheSizeForWeightInByte(HDRenderPipeline.k_MaxCacheSize, serialized.renderPipelineSettings.lightLoopSettings.planarReflectionCubemapSize.intValue, 1);
                    string message  = string.Format(k_CacheErrorFormat, HDEditorUtils.HumanizeWeight(currentCache), reserved);
                    EditorGUILayout.HelpBox(message, MessageType.Error);
                }
                else
                {
                    string message = string.Format(k_CacheInfoFormat, HDEditorUtils.HumanizeWeight(currentCache));
                    EditorGUILayout.HelpBox(message, MessageType.Info);
                }
            }

            EditorGUILayout.Space();

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.DelayedIntField(serialized.renderPipelineSettings.lightLoopSettings.maxEnvLightsOnScreen, k_MaxEnvContent);
            if (EditorGUI.EndChangeCheck())
            {
                serialized.renderPipelineSettings.lightLoopSettings.maxEnvLightsOnScreen.intValue = Mathf.Clamp(serialized.renderPipelineSettings.lightLoopSettings.maxEnvLightsOnScreen.intValue, 1, HDRenderPipeline.k_MaxEnvLightsOnScreen);
            }
        }
Beispiel #22
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);
        }
 protected virtual LightingExplorerTableColumn[] GetHDLightColumns()
 {
     return(new[]
     {
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Name, HDStyles.Name, null, 200),                                               // 0: Name
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Checkbox, HDStyles.On, "m_Enabled", 25),                                       // 1: Enabled
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Enum, HDStyles.Type, "m_Type", 60),                                            // 2: Type
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Enum, HDStyles.Mode, "m_Lightmapping", 60),                                    // 3: Mixed mode
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Enum, HDStyles.Range, "m_Range", 60),                                          // 4: Range
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Checkbox, HDStyles.ColorTemperatureMode, "m_UseColorTemperature", 100),        // 5: Color Temperature Mode
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Color, HDStyles.Color, "m_Color", 60),                                         // 6: Color
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Float, HDStyles.ColorTemperature, "m_ColorTemperature", 100, (r, prop, dep) => // 7: Color Temperature
         {
             if (prop.serializedObject.FindProperty("m_UseColorTemperature").boolValue)
             {
                 prop = prop.serializedObject.FindProperty("m_ColorTemperature");
                 prop.floatValue = EditorGUI.FloatField(r, prop.floatValue);
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Float, HDStyles.Intensity, "m_Intensity", 60, (r, prop, dep) =>                // 8: Intensity
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null || lightDataPairing[light].hdAdditionalLightData == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             float intensity = lightDataPairing[light].hdAdditionalLightData.intensity;
             EditorGUI.BeginChangeCheck();
             intensity = EditorGUI.FloatField(r, intensity);
             if (EditorGUI.EndChangeCheck())
             {
                 Undo.RecordObject(lightDataPairing[light].hdAdditionalLightData, "Changed light intensity");
                 lightDataPairing[light].hdAdditionalLightData.intensity = intensity;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Float, HDStyles.Unit, "m_Intensity", 60, (r, prop, dep) =>                // 9: Unit
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null || lightDataPairing[light].hdAdditionalLightData == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             LightUnit unit = lightDataPairing[light].hdAdditionalLightData.lightUnit;
             EditorGUI.BeginChangeCheck();
             unit = (LightUnit)EditorGUI.EnumPopup(r, unit);
             if (EditorGUI.EndChangeCheck())
             {
                 lightDataPairing[light].hdAdditionalLightData.lightUnit = unit;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Float, HDStyles.IndirectMultiplier, "m_BounceIntensity", 90),                  // 10: Indirect multiplier
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Checkbox, HDStyles.Shadows, "m_Shadows.m_Type", 60, (r, prop, dep) =>          // 11: Shadows
         {
             EditorGUI.BeginChangeCheck();
             bool shadows = EditorGUI.Toggle(r, prop.intValue != (int)LightShadows.None);
             if (EditorGUI.EndChangeCheck())
             {
                 prop.intValue = shadows ? (int)LightShadows.Soft : (int)LightShadows.None;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Checkbox, HDStyles.ContactShadows, "m_Shadows.m_Type", 100, (r, prop, dep) =>  // 12: Contact Shadows
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null || lightDataPairing[light].additionalShadowData == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             bool contactShadows = lightDataPairing[light].additionalShadowData.contactShadows;
             EditorGUI.BeginChangeCheck();
             contactShadows = EditorGUI.Toggle(r, contactShadows);
             if (EditorGUI.EndChangeCheck())
             {
                 lightDataPairing[light].additionalShadowData.contactShadows = contactShadows;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Int, HDStyles.ShadowResolution, "m_Intensity", 60, (r, prop, dep) =>           // 13: Shadow resolution
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null || lightDataPairing[light].additionalShadowData == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             int shadowResolution = lightDataPairing[light].additionalShadowData.shadowResolution;
             EditorGUI.BeginChangeCheck();
             shadowResolution = EditorGUI.IntField(r, shadowResolution);
             if (EditorGUI.EndChangeCheck())
             {
                 lightDataPairing[light].additionalShadowData.shadowResolution = shadowResolution;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Checkbox, HDStyles.AffectDiffuse, "m_Intensity", 90, (r, prop, dep) =>         // 14: Affect Diffuse
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null || lightDataPairing[light].hdAdditionalLightData == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             bool affectDiffuse = lightDataPairing[light].hdAdditionalLightData.affectDiffuse;
             EditorGUI.BeginChangeCheck();
             affectDiffuse = EditorGUI.Toggle(r, affectDiffuse);
             if (EditorGUI.EndChangeCheck())
             {
                 lightDataPairing[light].hdAdditionalLightData.affectDiffuse = affectDiffuse;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Checkbox, HDStyles.AffectSpecular, "m_Intensity", 90, (r, prop, dep) =>        // 15: Affect Specular
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null || lightDataPairing[light].hdAdditionalLightData == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             bool affectSpecular = lightDataPairing[light].hdAdditionalLightData.affectSpecular;
             EditorGUI.BeginChangeCheck();
             affectSpecular = EditorGUI.Toggle(r, affectSpecular);
             if (EditorGUI.EndChangeCheck())
             {
                 lightDataPairing[light].hdAdditionalLightData.affectSpecular = affectSpecular;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Float, HDStyles.FadeDistance, "m_Intensity", 60, (r, prop, dep) =>                // 16: Fade Distance
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null || lightDataPairing[light].hdAdditionalLightData == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             float fadeDistance = lightDataPairing[light].hdAdditionalLightData.fadeDistance;
             EditorGUI.BeginChangeCheck();
             fadeDistance = EditorGUI.FloatField(r, fadeDistance);
             if (EditorGUI.EndChangeCheck())
             {
                 Undo.RecordObject(lightDataPairing[light].hdAdditionalLightData, "Changed light fade distance");
                 lightDataPairing[light].hdAdditionalLightData.fadeDistance = fadeDistance;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Float, HDStyles.ShadowFadeDistance, "m_Intensity", 60, (r, prop, dep) =>           // 17: Shadow Fade Distance
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null || lightDataPairing[light].additionalShadowData == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             float shadowFadeDistance = lightDataPairing[light].additionalShadowData.shadowFadeDistance;
             EditorGUI.BeginChangeCheck();
             shadowFadeDistance = EditorGUI.FloatField(r, shadowFadeDistance);
             if (EditorGUI.EndChangeCheck())
             {
                 Undo.RecordObject(lightDataPairing[light].additionalShadowData, "Changed light shadow fade distance");
                 lightDataPairing[light].additionalShadowData.shadowFadeDistance = shadowFadeDistance;
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Custom, HDStyles.LightLayer, "m_RenderingLayerMask", 80, (r, prop, dep) =>     // 18: Light Layer
         {
             using (new EditorGUI.DisabledScope(!(GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset).currentPlatformRenderPipelineSettings.supportLightLayers))
             {
                 HDEditorUtils.LightLayerMaskPropertyDrawer(r, prop);
             }
         }),
         new LightingExplorerTableColumn(LightingExplorerTableColumn.DataType.Custom, HDStyles.IsPrefab, "m_Intensity", 60, (r, prop, dep) =>                // 19: Prefab
         {
             Light light = prop.serializedObject.targetObject as Light;
             if (light == null)
             {
                 EditorGUI.LabelField(r, "null");
                 return;
             }
             bool isPrefab = lightDataPairing[light].isPrefab;
             if (isPrefab)
             {
                 EditorGUI.ObjectField(r, lightDataPairing[light].prefabRoot, typeof(GameObject), false);
             }
         }),
     });
 }
        public override void Convert(Material srcMaterial, Material dstMaterial)
        {
            dstMaterial.hideFlags = HideFlags.DontUnloadUnusedAsset;

            base.Convert(srcMaterial, dstMaterial);

            // ---------- Mask Map ----------

            // Metallic
            bool    hasMetallic = false;
            Texture metallicMap = TextureCombiner.TextureFromColor(Color.black);

            if ((srcMaterial.shader.name == Standard) || (srcMaterial.shader.name == Standard_Rough))
            {
                hasMetallic = srcMaterial.GetTexture("_MetallicGlossMap") != null;
                if (hasMetallic)
                {
                    metallicMap = TextureCombiner.GetTextureSafe(srcMaterial, "_MetallicGlossMap", Color.white);
                }
                else
                {
                    metallicMap = TextureCombiner.TextureFromColor(Color.white);
                }

                // Convert _Metallic value from Gamma to Linear, or set to 1 if a map is used
                float metallicValue = Mathf.Pow(srcMaterial.GetFloat("_Metallic"), 2.2f);
                dstMaterial.SetFloat("_Metallic", hasMetallic? 1f : metallicValue);
            }

            // Occlusion
            bool    hasOcclusion = srcMaterial.GetTexture("_OcclusionMap") != null;
            Texture occlusionMap = Texture2D.whiteTexture;

            if (hasOcclusion)
            {
                occlusionMap = TextureCombiner.GetTextureSafe(srcMaterial, "_OcclusionMap", Color.white);
            }

            dstMaterial.SetFloat("_AORemapMin", 1f - srcMaterial.GetFloat("_OcclusionStrength"));

            // Detail Mask
            bool    hasDetailMask = srcMaterial.GetTexture("_DetailMask") != null;
            Texture detailMaskMap = Texture2D.whiteTexture;

            if (hasDetailMask)
            {
                detailMaskMap = TextureCombiner.GetTextureSafe(srcMaterial, "_DetailMask", Color.white);
            }

            // Smoothness
            bool      hasSmoothness = false;
            Texture2D smoothnessMap = TextureCombiner.TextureFromColor(Color.white);

            dstMaterial.SetFloat("_SmoothnessRemapMax", srcMaterial.GetFloat("_Glossiness"));

            if (srcMaterial.shader.name == Standard_Rough)
            {
                hasSmoothness = srcMaterial.GetTexture("_SpecGlossMap") != null;

                if (hasSmoothness)
                {
                    smoothnessMap = (Texture2D)TextureCombiner.GetTextureSafe(srcMaterial, "_SpecGlossMap", Color.grey);
                }
            }
            else
            {
                string smoothnessTextureChannel = "_MainTex";

                if (srcMaterial.GetFloat("_SmoothnessTextureChannel") == 0)
                {
                    if (srcMaterial.shader.name == Standard)
                    {
                        smoothnessTextureChannel = "_MetallicGlossMap";
                    }
                    if (srcMaterial.shader.name == Standard_Spec)
                    {
                        smoothnessTextureChannel = "_SpecGlossMap";
                    }
                }

                smoothnessMap = (Texture2D)srcMaterial.GetTexture(smoothnessTextureChannel);
                if (smoothnessMap != null)
                {
                    hasSmoothness = true;

                    dstMaterial.SetFloat("_SmoothnessRemapMax", srcMaterial.GetFloat("_GlossMapScale"));

                    if (!TextureCombiner.TextureHasAlpha(smoothnessMap))
                    {
                        smoothnessMap = TextureCombiner.TextureFromColor(Color.white);
                    }
                }
                else
                {
                    smoothnessMap = TextureCombiner.TextureFromColor(Color.white);
                }
            }


            // Build the mask map
            if (hasMetallic || hasOcclusion || hasDetailMask || hasSmoothness)
            {
                Texture2D maskMap;

                TextureCombiner maskMapCombiner = new TextureCombiner(
                    metallicMap, 0,                                                         // R: Metallic from red
                    occlusionMap, 1,                                                        // G: Occlusion from green
                    detailMaskMap, 3,                                                       // B: Detail Mask from alpha
                    smoothnessMap, (srcMaterial.shader.name == Standard_Rough) ? -4 : 3     // A: Smoothness Texture from inverse greyscale for roughness setup, or alpha
                    );

                string maskMapPath = AssetDatabase.GetAssetPath(srcMaterial);
                maskMapPath = maskMapPath.Remove(maskMapPath.Length - 4) + "_MaskMap.png";
                maskMap     = maskMapCombiner.Combine(maskMapPath);
                dstMaterial.SetTexture("_MaskMap", maskMap);
            }

            // Specular Setup Specific
            if (srcMaterial.shader.name == Standard_Spec)
            {
                // if there is a specular map, change the specular color to white
                if (srcMaterial.GetTexture("_SpecGlossMap") != null)
                {
                    dstMaterial.SetColor("_SpecularColor", Color.white);
                }
            }

            // ---------- Height Map ----------
            bool hasHeightMap = srcMaterial.GetTexture("_ParallaxMap") != null;

            if (hasHeightMap) // Enable Parallax Occlusion Mapping
            {
                dstMaterial.SetFloat("_DisplacementMode", 2);
                dstMaterial.SetFloat("_HeightPoMAmplitude", srcMaterial.GetFloat("_Parallax") * 2f);
            }

            // ---------- Detail Map ----------
            bool hasDetailAlbedo = srcMaterial.GetTexture("_DetailAlbedoMap") != null;
            bool hasDetailNormal = srcMaterial.GetTexture("_DetailNormalMap") != null;

            if (hasDetailAlbedo || hasDetailNormal)
            {
                Texture2D       detailMap;
                TextureCombiner detailCombiner = new TextureCombiner(
                    TextureCombiner.GetTextureSafe(srcMaterial, "_DetailAlbedoMap", Color.grey), 4,     // Albedo (overlay)
                    TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 1,     // Normal Y
                    TextureCombiner.midGrey, 1,                                                         // Smoothness
                    TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 0      // Normal X
                    );
                string detailMapPath = AssetDatabase.GetAssetPath(srcMaterial);
                detailMapPath = detailMapPath.Remove(detailMapPath.Length - 4) + "_DetailMap.png";
                detailMap     = detailCombiner.Combine(detailMapPath);
                dstMaterial.SetTexture("_DetailMap", detailMap);
            }


            // Blend Mode
            int previousBlendMode = srcMaterial.GetInt("_Mode");

            switch (previousBlendMode)
            {
            case 0:     // Opaque
                dstMaterial.SetFloat("_SurfaceType", 0);
                dstMaterial.SetFloat("_BlendMode", 0);
                dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
                dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
                break;

            case 1:     // Cutout
                dstMaterial.SetFloat("_SurfaceType", 0);
                dstMaterial.SetFloat("_BlendMode", 0);
                dstMaterial.SetFloat("_AlphaCutoffEnable", 1);
                dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
                break;

            case 2:     // Fade -> Alpha + Disable preserve specular
                dstMaterial.SetFloat("_SurfaceType", 1);
                dstMaterial.SetFloat("_BlendMode", 0);
                dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
                dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 0);
                break;

            case 3:     // Transparent -> Alpha
                dstMaterial.SetFloat("_SurfaceType", 1);
                dstMaterial.SetFloat("_BlendMode", 0);
                dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
                dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
                break;
            }

            Color hdrEmission = srcMaterial.GetColor("_EmissionColor");

            // Get the _EMISSION keyword of the Standard shader
            if (!srcMaterial.IsKeywordEnabled("_EMISSION"))
            {
                hdrEmission = Color.black;
            }

            // Emission toggle of Particle Standard Surface
            if (srcMaterial.HasProperty("_EmissionEnabled"))
            {
                if (srcMaterial.GetFloat("_EmissionEnabled") == 0)
                {
                    hdrEmission = Color.black;
                }
            }

            dstMaterial.SetColor("_EmissiveColor", hdrEmission);

            HDEditorUtils.ResetMaterialKeywords(dstMaterial);
        }
 static internal void Drawer_ToolBarButton(
     ToolBar button, Editor owner,
     params GUILayoutOption[] options
     )
 => HDEditorUtils.DrawToolBarButton(button, owner, k_ToolbarMode, k_ToolbarContents, options);
            public static void DoToolbarShortcutKey(Editor owner)
            {
                var provider  = new TProvider();
                var toolbars  = provider.toolbars;
                var shortcuts = provider.shortcuts;

                var evt = Event.current;

                if (evt.type != EventType.KeyDown || !evt.shift)
                {
                    return;
                }

                if (shortcuts.TryGetValue(evt.keyCode, out ToolBar toolbar))
                {
                    bool used = false;
                    foreach (ToolBar t in toolbars)
                    {
                        if ((t & toolbar) > 0)
                        {
                            used = true;
                            break;
                        }
                    }
                    if (!used)
                    {
                        return;
                    }

                    var targetMode = k_ToolbarMode[toolbar];
                    var mode       = EditMode.editMode == targetMode ? EditMode.SceneViewEditMode.None : targetMode;
                    EditorApplication.delayCall += () => EditMode.ChangeEditMode(mode, HDEditorUtils.GetBoundsGetter(owner)(), owner);
                    evt.Use();
                }
            }
        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);
            }