using UnityEditor.ShaderGraph; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using BlendOp = UnityEditor.ShaderGraph.BlendOp; namespace UnityEditor.Rendering.HighDefinition.ShaderGraph { static partial class HDShaderPasses { public static StructCollection GenerateStructs(StructCollection input, bool useVFX, bool useTessellation) { StructCollection structs = input == null ? new StructCollection() : new StructCollection { input }; structs.Add(useTessellation && !useVFX ? CoreStructCollections.BasicTessellation : CoreStructCollections.Basic); return structs; } public static PragmaCollection GeneratePragmas(PragmaCollection input, bool useVFX, bool useTessellation, bool useInstancing = true) { PragmaCollection pragmas = input == null ? new PragmaCollection() : new PragmaCollection { input }; if (useVFX) pragmas.Add(CorePragmas.BasicVFX); else pragmas.Add(useTessellation ? CorePragmas.BasicTessellation : CorePragmas.Basic); if (useInstancing) pragmas.Add(Pragma.MultiCompileInstancing); return pragmas; } public static DefineCollection GenerateDefines(DefineCollection input, bool useVFX, bool useTessellation) { DefineCollection defines = input == null ? new DefineCollection() : new DefineCollection { input }; if (useTessellation && !useVFX) defines.Add(CoreDefines.Tessellation); return defines; } private static bool isAnalyticDerivativesEnabled => GraphicsSettings.TryGetRenderPipelineSettings( out var analyticDerivativeSettings) && analyticDerivativeSettings.emulation; #region Distortion Pass public static PassDescriptor GenerateDistortionPass(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "DistortionVectors", referenceName = "SHADERPASS_DISTORTION", lightMode = "DistortionVectors", useInPreview = true, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = CoreRequiredFields.Basic, renderStates = GenerateRenderState(), pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.ShaderGraphRaytracingDefault, useVFX, useTessellation), includes = GenerateIncludes(), customInterpolators = CoreCustomInterpolators.Common, }; RenderStateCollection GenerateRenderState() { return new RenderStateCollection { { RenderState.Blend(Blend.One, Blend.One, Blend.One, Blend.One), new FieldCondition(HDFields.DistortionAdd, true) }, { RenderState.Blend(Blend.DstColor, Blend.Zero, Blend.DstAlpha, Blend.Zero), new FieldCondition(HDFields.DistortionMultiply, true) }, { RenderState.Blend(Blend.One, Blend.Zero, Blend.One, Blend.Zero), new FieldCondition(HDFields.DistortionReplace, true) }, { RenderState.BlendOp((BlendOp)BlendOp.Add, BlendOp.Add) }, { RenderState.Cull(CoreRenderStates.Uniforms.cullMode) }, { RenderState.ZWrite(ZWrite.Off) }, { RenderState.ZTest(ZTest.Always), new FieldCondition(HDFields.DistortionDepthTest, false) }, { RenderState.ZTest(ZTest.LEqual), new FieldCondition(HDFields.DistortionDepthTest, true) }, { RenderState.Stencil(new StencilDescriptor() { WriteMask = CoreRenderStates.Uniforms.stencilWriteMaskDistortionVec, Ref = CoreRenderStates.Uniforms.stencilRefDistortionVec, Comp = "Always", Pass = "Replace", }) } }; } IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kDisortionVectors, IncludeLocation.Postgraph); return includes; } } #endregion #region Scene Picking Pass public static PassDescriptor GenerateScenePicking(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "ScenePickingPass", referenceName = "SHADERPASS_DEPTH_ONLY", lightMode = "Picking", useInPreview = false, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = GenerateRequiredFields(), renderStates = CoreRenderStates.ScenePicking, pragmas = GeneratePragmas(CorePragmas.DotsInstancedEditorSync, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.ScenePicking, useVFX, useTessellation), includes = GenerateIncludes(supportLighting), customInterpolators = CoreCustomInterpolators.Common, }; FieldCollection GenerateRequiredFields() { var fieldCollection = new FieldCollection(); fieldCollection.Add(CoreRequiredFields.Basic); fieldCollection.Add(CoreRequiredFields.AddWriteNormalBuffer); return fieldCollection; } IncludeCollection GenerateIncludes(bool supportLighting) { var includes = new IncludeCollection(); includes.Add(CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassDepthOnly, IncludeLocation.Postgraph); return includes; } } #endregion #region Scene Selection Pass public static PassDescriptor GenerateSceneSelection(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "SceneSelectionPass", referenceName = "SHADERPASS_DEPTH_ONLY", lightMode = "SceneSelectionPass", useInPreview = false, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = CoreRequiredFields.Basic, renderStates = CoreRenderStates.SceneSelection, pragmas = GeneratePragmas(CorePragmas.DotsInstancedEditorSync, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.SceneSelection, useVFX, useTessellation), includes = GenerateIncludes(), customInterpolators = CoreCustomInterpolators.Common, }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassDepthOnly, IncludeLocation.Postgraph); return includes; } } #endregion #region Shadow Caster Pass static public PassDescriptor GenerateShadowCaster(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor() { // Definition displayName = "ShadowCaster", referenceName = "SHADERPASS_SHADOWS", lightMode = "ShadowCaster", useInPreview = false, validPixelBlocks = new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.Alpha, BlockFields.SurfaceDescription.AlphaClipThreshold, HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow, HDBlockFields.SurfaceDescription.DepthOffset, HDBlockFields.SurfaceDescription.DiffusionProfileHash // not used, but keeps the UnityPerMaterial cbuffer identical }, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = CoreRequiredFields.Basic, renderStates = CoreRenderStates.ShadowCaster, pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(null, useVFX, useTessellation), includes = GenerateIncludes(), customInterpolators = CoreCustomInterpolators.Common, }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassDepthOnly, IncludeLocation.Postgraph); return includes; } } #endregion #region META pass public static PassDescriptor GenerateMETA(bool supportLighting, bool useVFX) { return new PassDescriptor { // Definition displayName = "META", referenceName = "SHADERPASS_LIGHT_TRANSPORT", lightMode = "META", useInPreview = false, // We don't need any vertex inputs on meta pass: validVertexBlocks = new BlockFieldDescriptor[0], // Collections structs = GenerateStructs(null, useVFX, false), requiredFields = CoreRequiredFields.Meta, renderStates = CoreRenderStates.Meta, // Note: no tessellation for meta pass pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, false), defines = GenerateDefines(CoreDefines.Meta, useVFX, false), keywords = new KeywordCollection() { CoreKeywordDescriptors.EditorVisualization }, includes = GenerateIncludes(), }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); // Use Unity's built-in matrices for meta pass rendering includes.Add(CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassLightTransport, IncludeLocation.Postgraph); return includes; } } #endregion #region Depth Forward Only public static PassDescriptor GenerateDepthForwardOnlyPass(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "DepthForwardOnly", referenceName = "SHADERPASS_DEPTH_ONLY", lightMode = "DepthForwardOnly", useInPreview = true, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = GenerateRequiredFields(), renderStates = GenerateRenderState(), pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(supportLighting ? CoreDefines.DepthForwardOnly : CoreDefines.DepthForwardOnlyUnlit, useVFX, useTessellation), includes = GenerateIncludes(), customInterpolators = CoreCustomInterpolators.Common, }; FieldCollection GenerateRequiredFields() { var fieldCollection = new FieldCollection(); fieldCollection.Add(supportLighting ? CoreRequiredFields.BasicSurfaceData : CoreRequiredFields.Basic); fieldCollection.Add(CoreRequiredFields.AddWriteNormalBuffer); return fieldCollection; } RenderStateCollection GenerateRenderState() { var renderState = new RenderStateCollection { CoreRenderStates.DepthOnly }; return renderState; } IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassDepthOnly, IncludeLocation.Postgraph); return includes; } } #endregion #region Motion Vectors public static PassDescriptor GenerateMotionVectors(bool supportLighting, bool supportForward, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "MotionVectors", referenceName = "SHADERPASS_MOTION_VECTORS", lightMode = "MotionVectors", useInPreview = false, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = GenerateRequiredFields(), renderStates = GenerateRenderState(), pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), // For shadow matte (unlit SG only) we need to enable write normal buffer // For lighting case: we want to use WRITE_NORMAL_BUFFER as a define in forward only case and WRITE_NORMAL_BUFFER as a keyword in Lit case. // This is handled in CollectPassKeywords() function in SurfaceSubTarget.cs so we don't add it here. defines = GenerateDefines(CoreDefines.MotionVectorUnlit, useVFX, useTessellation), includes = GenerateIncludes(), customInterpolators = CoreCustomInterpolators.Common, }; FieldCollection GenerateRequiredFields() { var fieldCollection = new FieldCollection(); fieldCollection.Add(CoreRequiredFields.BasicSurfaceData); fieldCollection.Add(CoreRequiredFields.AddWriteNormalBuffer); return fieldCollection; } RenderStateCollection GenerateRenderState() { var renderState = new RenderStateCollection(); renderState.Add(CoreRenderStates.MotionVectors); return renderState; } IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassMotionVectors, IncludeLocation.Postgraph); return includes; } } #endregion #region Forward Only public static PassDescriptor GenerateForwardOnlyPass(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "ForwardOnly", referenceName = supportLighting ? "SHADERPASS_FORWARD" : "SHADERPASS_FORWARD_UNLIT", lightMode = "ForwardOnly", useInPreview = true, // Collections structs = GenerateStructs(null, useVFX, useTessellation), // We need motion vector version as Forward pass support transparent motion vector and we can't use ifdef for it requiredFields = supportLighting ? CoreRequiredFields.BasicLighting : CoreRequiredFields.BasicSurfaceData, renderStates = CoreRenderStates.Forward, pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(supportLighting ? CoreDefines.Forward : CoreDefines.ForwardUnlit, useVFX, useTessellation), includes = GenerateIncludes(), analyticDerivativesEnabled = isAnalyticDerivativesEnabled, analyticDerivativesApplyEmulate = true, virtualTextureFeedback = true, customInterpolators = CoreCustomInterpolators.Common }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) { includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kLighting, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kLightLoopDef, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); if (supportLighting) includes.Add(CoreIncludes.kLightLoop, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); if (supportLighting) includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph); else includes.Add(CoreIncludes.kPassForwardUnlit, IncludeLocation.Postgraph); return includes; } } #endregion #region Back then front pass public static PassDescriptor GenerateBackThenFront(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "TransparentBackface", referenceName = supportLighting ? "SHADERPASS_FORWARD" : "SHADERPASS_FORWARD_UNLIT", lightMode = "TransparentBackface", useInPreview = true, // Collections structs = GenerateStructs(null, useVFX, useTessellation), // BackThenFront is a forward pass and thus require same settings requiredFields = supportLighting ? CoreRequiredFields.BasicLighting : CoreRequiredFields.BasicSurfaceData, renderStates = CoreRenderStates.TransparentBackface, pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.BackThenFront, useVFX, useTessellation), includes = GenerateIncludes(), virtualTextureFeedback = true, customInterpolators = CoreCustomInterpolators.Common }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) { includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kLighting, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kLightLoopDef, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); if (supportLighting) includes.Add(CoreIncludes.kLightLoop, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); if (supportLighting) includes.Add(CoreIncludes.kPassForward, IncludeLocation.Postgraph); else includes.Add(CoreIncludes.kPassForwardUnlit, IncludeLocation.Postgraph); return includes; } } #endregion #region Transparent Depth Prepass public static PassDescriptor GenerateTransparentDepthPrepass(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "TransparentDepthPrepass", referenceName = "SHADERPASS_TRANSPARENT_DEPTH_PREPASS", lightMode = "TransparentDepthPrepass", useInPreview = true, validPixelBlocks = supportLighting ? new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.Alpha, HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass, BlockFields.SurfaceDescription.AlphaClipThreshold, HDBlockFields.SurfaceDescription.DepthOffset, BlockFields.SurfaceDescription.NormalTS, BlockFields.SurfaceDescription.NormalWS, BlockFields.SurfaceDescription.NormalOS, BlockFields.SurfaceDescription.Smoothness, HDBlockFields.SurfaceDescription.DiffusionProfileHash // not used, but keeps the UnityPerMaterial cbuffer identical } : new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.Alpha, HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass, BlockFields.SurfaceDescription.AlphaClipThreshold, HDBlockFields.SurfaceDescription.DepthOffset, HDBlockFields.SurfaceDescription.DiffusionProfileHash // not used, but keeps the UnityPerMaterial cbuffer identical }, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = GenerateRequiredFields(), renderStates = GenerateRenderState(), pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), // For TransparentDepthPrepass, WRITE_NORMAL_BUFFER is define in the ShaderPass.template directly as it rely on other define defines = GenerateDefines(CoreDefines.TransparentDepthPrepass, useVFX, useTessellation), includes = GenerateIncludes(), customInterpolators = CoreCustomInterpolators.Common, }; FieldCollection GenerateRequiredFields() { var fieldCollection = new FieldCollection(); fieldCollection.Add(CoreRequiredFields.Basic); fieldCollection.Add(CoreRequiredFields.AddWriteNormalBuffer); // Always define as we can't test condition for it return fieldCollection; } RenderStateCollection GenerateRenderState() { var renderState = new RenderStateCollection { { RenderState.Blend(Blend.One, Blend.Zero) }, { RenderState.Cull(CoreRenderStates.Uniforms.cullMode) }, { RenderState.ZWrite(ZWrite.On) }, { RenderState.Stencil(new StencilDescriptor() { WriteMask = CoreRenderStates.Uniforms.stencilWriteMaskDepth, Ref = CoreRenderStates.Uniforms.stencilRefDepth, Comp = "Always", Pass = "Replace", }) }, }; return renderState; } IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassDepthOnly, IncludeLocation.Postgraph); return includes; } } #endregion #region Transparent Depth Postpass public static PassDescriptor GenerateTransparentDepthPostpass(bool supportLighting, bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "TransparentDepthPostpass", referenceName = "SHADERPASS_TRANSPARENT_DEPTH_POSTPASS", lightMode = "TransparentDepthPostpass", useInPreview = true, validPixelBlocks = new BlockFieldDescriptor[] { BlockFields.SurfaceDescription.Alpha, HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPostpass, HDBlockFields.SurfaceDescription.DepthOffset, BlockFields.SurfaceDescription.AlphaClipThreshold, }, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = CoreRequiredFields.Basic, renderStates = GenerateRenderState(), pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.TransparentDepthPostpass, useVFX, useTessellation), includes = GenerateIncludes(), customInterpolators = CoreCustomInterpolators.Common, }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection(); includes.Add(CoreIncludes.CorePregraph); if (supportLighting) includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPassDepthOnly, IncludeLocation.Postgraph); return includes; } RenderStateCollection GenerateRenderState() { var renderState = new RenderStateCollection { { RenderState.Blend(Blend.One, Blend.Zero) }, { RenderState.Cull(CoreRenderStates.Uniforms.cullMode) }, { RenderState.ZWrite(ZWrite.On) }, { RenderState.ColorMask("ColorMask 0") }, }; return renderState; } } #endregion #region Lit DepthOnly public static PassDescriptor GenerateLitDepthOnly(bool useVFX, bool useTessellation) { return new PassDescriptor { displayName = "DepthOnly", referenceName = "SHADERPASS_DEPTH_ONLY", lightMode = "DepthOnly", useInPreview = true, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = GenerateRequiredFields(), renderStates = CoreRenderStates.DepthOnly, pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.ShaderGraphRaytracingDefault, useVFX, useTessellation), keywords = LitDepthOnlyKeywords, includes = DepthOnlyIncludes, customInterpolators = CoreCustomInterpolators.Common, }; FieldCollection GenerateRequiredFields() { var fieldCollection = new FieldCollection(); fieldCollection.Add(CoreRequiredFields.Basic); fieldCollection.Add(CoreRequiredFields.AddWriteNormalBuffer); return fieldCollection; } } public static IncludeCollection DepthOnlyIncludes = new IncludeCollection { { CoreIncludes.CorePregraph }, { CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph }, { CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.CoreUtility }, { CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph }, { CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph }, { CoreIncludes.kPassDepthOnly, IncludeLocation.Postgraph }, }; public static KeywordCollection LitDepthOnlyKeywords = new KeywordCollection { { CoreKeywordDescriptors.WriteNormalBuffer }, }; #endregion #region GBuffer public static PassDescriptor GenerateGBuffer(bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "GBuffer", referenceName = "SHADERPASS_GBUFFER", lightMode = "GBuffer", useInPreview = true, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = CoreRequiredFields.BasicLighting, renderStates = GBufferRenderState, pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.ShaderGraphRaytracingDefault, useVFX, useTessellation), keywords = GBufferKeywords, includes = GBufferIncludes, analyticDerivativesEnabled = isAnalyticDerivativesEnabled, analyticDerivativesApplyEmulate = true, virtualTextureFeedback = true, customInterpolators = CoreCustomInterpolators.Common, }; } public static KeywordCollection GBufferKeywords = new KeywordCollection { { CoreKeywordDescriptors.RenderingLayers }, }; public static IncludeCollection GBufferIncludes = new IncludeCollection { { CoreIncludes.CorePregraph }, { CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph }, { CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.CoreUtility }, { CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph }, { CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph }, { CoreIncludes.kPassGBuffer, IncludeLocation.Postgraph }, }; public static RenderStateCollection GBufferRenderState = new RenderStateCollection { { RenderState.Cull(CoreRenderStates.Uniforms.cullMode) }, { RenderState.ZTest(CoreRenderStates.Uniforms.zTestGBuffer) }, { RenderState.Stencil(new StencilDescriptor() { WriteMask = CoreRenderStates.Uniforms.stencilWriteMaskGBuffer, Ref = CoreRenderStates.Uniforms.stencilRefGBuffer, Comp = "Always", Pass = "Replace", }) }, }; #endregion #region Lit Forward public static PassDescriptor GenerateLitForward(bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "Forward", referenceName = "SHADERPASS_FORWARD", lightMode = "Forward", useInPreview = true, // Collections structs = GenerateStructs(null, useVFX, useTessellation), // We need motion vector version as Forward pass support transparent motion vector and we can't use ifdef for it requiredFields = CoreRequiredFields.BasicLighting, renderStates = CoreRenderStates.Forward, pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.ForwardLit, useVFX, useTessellation), includes = ForwardIncludes, virtualTextureFeedback = true, customInterpolators = CoreCustomInterpolators.Common, }; } public static IncludeCollection ForwardIncludes = new IncludeCollection { { CoreIncludes.CorePregraph }, { CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph }, { CoreIncludes.kLighting, IncludeLocation.Pregraph }, { CoreIncludes.kLightLoopDef, IncludeLocation.Pregraph }, { CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.kLightLoop, IncludeLocation.Pregraph }, { CoreIncludes.CoreUtility }, { CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph }, { CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph }, { CoreIncludes.kPassForward, IncludeLocation.Postgraph }, }; #endregion #region Lit Raytracing Prepass public static PassDescriptor GenerateLitRaytracingPrepass() { return new PassDescriptor { // Definition displayName = "RayTracingPrepass", referenceName = "SHADERPASS_CONSTANT", lightMode = "RayTracingPrepass", useInPreview = false, // Collections structs = GenerateStructs(null, false, false), requiredFields = CoreRequiredFields.Basic, renderStates = RayTracingPrepassRenderState, // no tessellation for raytracing pragmas = GeneratePragmas(null, false, false), defines = GenerateDefines(CoreDefines.ShaderGraphRaytracingDefault, false, false), includes = RayTracingPrepassIncludes, customInterpolators = CoreCustomInterpolators.Common, }; } public static IncludeCollection RayTracingPrepassIncludes = new IncludeCollection { { CoreIncludes.CorePregraph }, { CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph }, { CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.CoreUtility }, { CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph }, { CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph }, { CoreIncludes.kPassConstant, IncludeLocation.Postgraph }, }; public static RenderStateCollection RayTracingPrepassRenderState = new RenderStateCollection { { RenderState.Blend(Blend.One, Blend.Zero) }, { RenderState.Cull(CoreRenderStates.Uniforms.cullMode) }, { RenderState.ZWrite(ZWrite.On) }, // Note: we use default ZTest LEqual so if the object have already been render in depth prepass, it will re-render to tag stencil }; #endregion #region Raytracing Indirect public static KeywordCollection IndirectDiffuseKeywordCollection = new KeywordCollection { { CoreKeywordDescriptors.multiBounceIndirect }, }; public static PassDescriptor GenerateRaytracingIndirect(bool supportLighting) { return new PassDescriptor { // Definition displayName = "IndirectDXR", referenceName = "SHADERPASS_RAYTRACING_INDIRECT", lightMode = "IndirectDXR", useInPreview = false, requiredFields = supportLighting ? CoreRequiredFields.BasicLighting : CoreRequiredFields.Basic, // Collections structs = CoreStructCollections.BasicRaytracing, pragmas = CorePragmas.BasicRaytracing, defines = supportLighting ? RaytracingIndirectDefines : RaytracingIndirectUnlitDefines, keywords = supportLighting ? IndirectDiffuseKeywordCollection : null, includes = GenerateIncludes(), }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection { CoreIncludes.RaytracingCorePregraph }; includes.Add(CoreIncludes.kRaytracingIntersection, IncludeLocation.Pregraph); if (supportLighting) { includes.Add(CoreIncludes.kLighting, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kLightLoopDef, IncludeLocation.Pregraph); } // Each material has a specific hlsl file that should be included pre-graph and holds the lighting model includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); // We need to then include the ray tracing missing bits for the lighting models (based on which lighting model) includes.Add(CoreIncludes.kRaytracingPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); // We want to have the ray tracing light loop if this is an indirect sub-shader or a forward one and it is not the unlit shader if (supportLighting) includes.Add(CoreIncludes.kRaytracingLightLoop, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kRaytracingCommon, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); // Decal if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } // post graph includes includes.Add(CoreIncludes.kPassRaytracingIndirect, IncludeLocation.Postgraph); return includes; } } public static DefineCollection RaytracingIndirectUnlitDefines = new DefineCollection { { Defines.shadowLow }, { Defines.raytracingRaytraced }, }; public static DefineCollection RaytracingIndirectDefines = new DefineCollection { { Defines.shadowLow }, { Defines.raytracingRaytraced }, { Defines.pathtracingDisableLightCluster }, { CoreKeywordDescriptors.HasLightloop, 1 }, }; #endregion #region Raytracing Visibility public static PassDescriptor GenerateRaytracingVisibility(bool supportLighting) { return new PassDescriptor { // Definition displayName = "VisibilityDXR", referenceName = "SHADERPASS_RAYTRACING_VISIBILITY", lightMode = "VisibilityDXR", useInPreview = false, // Port Mask // validVertexBlocks = CoreBlockMasks.Vertex, // validPixelBlocks = RaytracingVisibilityFragment, // Collections structs = CoreStructCollections.BasicRaytracing, pragmas = CorePragmas.BasicRaytracing, defines = supportLighting ? RaytracingVisibilityDefines : null, requiredFields = CoreRequiredFields.Basic, keywords = CoreKeywords.RaytracingVisiblity, includes = GenerateIncludes(), }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection { CoreIncludes.RaytracingCorePregraph }; // We want the generic payload if this is not a gbuffer or a subsurface subshader includes.Add(CoreIncludes.kRaytracingIntersection, IncludeLocation.Pregraph); // Each material has a specific hlsl file that should be included pre-graph and holds the lighting model includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); // We need to then include the ray tracing missing bits for the lighting models (based on which lighting model) includes.Add(CoreIncludes.kRaytracingPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); includes.Add(CoreIncludes.kRaytracingCommon, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); // post graph includes includes.Add(CoreIncludes.kPassRaytracingVisbility, IncludeLocation.Postgraph); return includes; } } public static DefineCollection RaytracingVisibilityDefines = new DefineCollection { { Defines.raytracingRaytraced }, }; #endregion #region Raytracing Forward public static PassDescriptor GenerateRaytracingForward(bool supportLighting) { return new PassDescriptor { // Definition displayName = "ForwardDXR", referenceName = "SHADERPASS_RAYTRACING_FORWARD", lightMode = "ForwardDXR", useInPreview = false, requiredFields = supportLighting ? CoreRequiredFields.BasicLighting : CoreRequiredFields.Basic, // Port Mask // validVertexBlocks = CoreBlockMasks.Vertex, // validPixelBlocks = RaytracingForwardFragment, // Collections structs = CoreStructCollections.BasicRaytracing, pragmas = CorePragmas.BasicRaytracing, defines = supportLighting ? RaytracingForwardDefines : RaytracingForwardUnlitDefines, includes = GenerateIncludes(), }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection { CoreIncludes.RaytracingCorePregraph }; // We want the generic payload if this is not a gbuffer or a subsurface subshader includes.Add(CoreIncludes.kRaytracingIntersection, IncludeLocation.Pregraph); // We want to have the lighting include if this is an indirect sub-shader, a forward one or the path tracing (and this is not an unlit) if (supportLighting) { includes.Add(CoreIncludes.kLighting, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kLightLoopDef, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); } // Each material has a specific hlsl file that should be included pre-graph and holds the lighting model includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); // We need to then include the ray tracing missing bits for the lighting models (based on which lighting model) includes.Add(CoreIncludes.kRaytracingPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); // We want to have the ray tracing light loop if this is an indirect sub-shader or a forward one and it is not the unlit shader if (supportLighting) includes.Add(CoreIncludes.kRaytracingLightLoop, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kRaytracingCommon, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); // post graph includes includes.Add(CoreIncludes.kPassRaytracingForward, IncludeLocation.Postgraph); return includes; } } public static DefineCollection RaytracingForwardDefines = new DefineCollection { { Defines.shadowLow }, { Defines.raytracingRaytraced }, { CoreKeywordDescriptors.HasLightloop, 1 }, }; public static DefineCollection RaytracingForwardUnlitDefines = new DefineCollection { { Defines.shadowLow }, { Defines.raytracingRaytraced }, }; #endregion #region Raytracing GBuffer public static PassDescriptor GenerateRaytracingGBuffer(bool supportLighting) { return new PassDescriptor { // Definition displayName = "GBufferDXR", referenceName = "SHADERPASS_RAYTRACING_GBUFFER", lightMode = "GBufferDXR", useInPreview = false, requiredFields = supportLighting ? CoreRequiredFields.BasicLighting : CoreRequiredFields.Basic, // Port Mask // validVertexBlocks = CoreBlockMasks.Vertex, // validPixelBlocks = RaytracingGBufferFragment, // Collections structs = CoreStructCollections.BasicRaytracing, pragmas = CorePragmas.BasicRaytracing, defines = RaytracingGBufferDefines, keywords = supportLighting ? CoreKeywords.RaytracingGBuffer : null, includes = GenerateIncludes(), }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection { CoreIncludes.RaytracingCorePregraph }; includes.Add(CoreIncludes.kRaytracingIntersectionGBuffer, IncludeLocation.Pregraph); // Each material has a specific hlsl file that should be included pre-graph and holds the lighting model includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); // We want to have the normal buffer include if this is a gbuffer and unlit shader if (!supportLighting) includes.Add(CoreIncludes.kNormalBuffer, IncludeLocation.Pregraph); // If this is the gbuffer sub-shader, we want the standard lit data includes.Add(CoreIncludes.kStandardLit, IncludeLocation.Pregraph); // We need to then include the ray tracing missing bits for the lighting models (based on which lighting model) includes.Add(CoreIncludes.kRaytracingPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); includes.Add(CoreIncludes.kRaytracingCommon, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } // post graph includes includes.Add(CoreIncludes.kPassRaytracingGBuffer, IncludeLocation.Postgraph); return includes; } } public static DefineCollection RaytracingGBufferDefines = new DefineCollection { { Defines.shadowLow }, { Defines.raytracingRaytraced }, { Defines.pathtracingDisableLightCluster }, }; #endregion #region Raytracing Debug public static PassDescriptor GenerateRaytracingDebug() { return new PassDescriptor { // Definition displayName = "DebugDXR", referenceName = "SHADERPASS_RAYTRACING_DEBUG", lightMode = "DebugDXR", useInPreview = false, requiredFields = CoreRequiredFields.Basic, // Collections structs = CoreStructCollections.BasicRaytracing, pragmas = CorePragmas.BasicRaytracing, defines = null, keywords = null, includes = GenerateIncludes(), // The DebugDXR pass is special and have its own template passTemplatePath = $"{HDUtils.GetHDRenderPipelinePath()}Editor/Material/ShaderGraph/Templates/RaytraceDebug.template" }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection { }; includes.Add(CoreIncludes.kRaytracingMacros, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kShaderVariablesRaytracing, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kMaterial, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kRaytracingIntersection, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kRaytracingCommon, IncludeLocation.Pregraph); // post graph includes includes.Add(CoreIncludes.kPassRaytracingDebug, IncludeLocation.Postgraph); return includes; } } #endregion #region Path Tracing public static PassDescriptor GeneratePathTracing(bool supportLighting) { return new PassDescriptor { //Definition displayName = "PathTracingDXR", referenceName = "SHADERPASS_PATH_TRACING", lightMode = "PathTracingDXR", useInPreview = false, //Port mask // validVertexBlocks = CoreBlockMasks.Vertex, // validPixelBlocks = PathTracingFragment, //Collections structs = CoreStructCollections.BasicRaytracing, pragmas = CorePragmas.BasicRaytracing, defines = supportLighting ? RaytracingPathTracingDefines : null, requiredFields = supportLighting ? CoreRequiredFields.BasicLighting : CoreRequiredFields.Basic, includes = GenerateIncludes(), }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection { CoreIncludes.RaytracingCorePregraph }; // We want the generic payload if this is not a gbuffer or a subsurface subshader includes.Add(CoreIncludes.kRaytracingIntersection, IncludeLocation.Pregraph); // We want to have the lighting include if this is an indirect sub-shader, a forward one or the path tracing (and this is not an unlit) if (supportLighting) { includes.Add(CoreIncludes.kLighting, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kLightLoopDef, IncludeLocation.Pregraph); // Ensure to include ray tracing light cluster includes.Add(CoreIncludes.kRaytracingLightCluster, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph); } // Each material has a specific hlsl file that should be included pre-graph and holds the lighting model includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); // We need to then include path tracing support for the material includes.Add(CoreIncludes.kPathtracingPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); includes.Add(CoreIncludes.kRaytracingCommon, IncludeLocation.Pregraph); if (supportLighting) { includes.Add(CoreIncludes.kDecalUtilities, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kPostDecalsPlaceholder, IncludeLocation.Pregraph); } includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); // post graph includes includes.Add(CoreIncludes.kPassPathTracing, IncludeLocation.Postgraph); return includes; } } public static DefineCollection RaytracingPathTracingDefines = new DefineCollection { { Defines.shadowLow }, { Defines.raytracingPathtraced }, { Defines.pathtracingDisableLightCluster }, { CoreKeywordDescriptors.HasLightloop, 1 }, }; #endregion #region Raytracing Subsurface public static PassDescriptor GenerateRaytracingSubsurface() { return new PassDescriptor { //Definition displayName = "SubSurfaceDXR", referenceName = "SHADERPASS_RAYTRACING_SUB_SURFACE", lightMode = "SubSurfaceDXR", useInPreview = false, requiredFields = CoreRequiredFields.BasicLighting, // //Port mask // validVertexBlocks = CoreBlockMasks.Vertex, // validPixelBlocks = LitBlockMasks.FragmentDefault, //Collections structs = CoreStructCollections.BasicRaytracing, pragmas = CorePragmas.BasicRaytracing, defines = RaytracingSubsurfaceDefines, includes = GenerateIncludes(), }; IncludeCollection GenerateIncludes() { var includes = new IncludeCollection { CoreIncludes.RaytracingCorePregraph }; // We want the sub-surface payload if we are in the subsurface sub shader includes.Add(CoreIncludes.kRaytracingIntersectionSubSurface, IncludeLocation.Pregraph); // Each material has a specific hlsl file that should be included pre-graph and holds the lighting model includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph); // We need to then include the ray tracing missing bits for the lighting models (based on which lighting model) includes.Add(CoreIncludes.kRaytracingPlaceholder, IncludeLocation.Pregraph); includes.Add(CoreIncludes.CoreUtility); includes.Add(CoreIncludes.kRaytracingCommon, IncludeLocation.Pregraph); includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph); // post graph includes includes.Add(CoreIncludes.kPassRaytracingSubSurface, IncludeLocation.Postgraph); return includes; } } public static DefineCollection RaytracingSubsurfaceDefines = new DefineCollection { { Defines.shadowLow }, { Defines.raytracingRaytraced }, }; #endregion #region FullScreen Debug public static PassDescriptor GenerateFullScreenDebug(bool useVFX, bool useTessellation) { return new PassDescriptor { // Definition displayName = "FullScreenDebug", referenceName = "SHADERPASS_FULL_SCREEN_DEBUG", lightMode = "FullScreenDebug", useInPreview = false, // Collections structs = GenerateStructs(null, useVFX, useTessellation), requiredFields = CoreRequiredFields.Basic, pragmas = GeneratePragmas(CorePragmas.DotsInstanced, useVFX, useTessellation), defines = GenerateDefines(CoreDefines.ShaderGraphRaytracingDefault, useVFX, useTessellation), renderStates = FullScreenDebugRenderState, includes = GenerateIncludes(), customInterpolators = CoreCustomInterpolators.Common, }; IncludeCollection GenerateIncludes() { return new IncludeCollection { { CoreIncludes.CorePregraph }, { CoreIncludes.kNormalSurfaceGradient, IncludeLocation.Pregraph }, { CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph }, { CoreIncludes.CoreUtility }, { CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph }, { CoreIncludes.kPassFullScreenDebug, IncludeLocation.Postgraph }, }; } } public static RenderStateCollection FullScreenDebugRenderState = new RenderStateCollection { { RenderState.Cull(CoreRenderStates.Uniforms.cullMode) }, { RenderState.ZWrite(ZWrite.Off) }, { RenderState.ZTest(ZTest.LEqual) }, }; #endregion #region Define Utility public static class Defines { // Shadows public static DefineCollection shadowLow = new DefineCollection { { CoreKeywordDescriptors.PunctualShadow, 0 }, { CoreKeywordDescriptors.DirectionalShadow, 0 } }; // Raytracing Quality public static DefineCollection raytracingDefault = new DefineCollection { { RayTracingQualityNode.GetRayTracingQualityKeyword(), 0 } }; public static DefineCollection raytracingRaytraced = new DefineCollection { { RayTracingQualityNode.GetRayTracingQualityKeyword(), 1 } }; public static DefineCollection raytracingPathtraced = new DefineCollection { { RayTracingQualityNode.GetRayTracingQualityKeyword(), 2 } }; // Path tracing specific defines public static DefineCollection pathtracingDisableLightCluster = new DefineCollection { { CoreKeywordDescriptors.DisableLightloopTileAndCluster, 1 }, { CoreKeywordDescriptors.PathTracingclusteredDecals, 1 } }; } #endregion } }