You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1434 lines
63 KiB

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<AnalyticDerivativeSettings>(
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
}
}