2021-09-09 20:42:29 -04:00

1270 lines
52 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using UnityEditor.ShaderGraph;
using UnityEditor.ShaderGraph.Internal;
namespace UnityEditor.Rendering.HighDefinition.ShaderGraph
{
static class HDShaderPasses
{
#region Distortion Pass
public static PassDescriptor GenerateDistortionPass(bool supportLighting)
{
return new PassDescriptor
{
// Definition
displayName = "DistortionVectors",
referenceName = "SHADERPASS_DISTORTION",
lightMode = "DistortionVectors",
useInPreview = true,
// Collections
renderStates = GenerateRenderState(),
pragmas = CorePragmas.DotsInstancedInV1AndV2,
defines = CoreDefines.ShaderGraphRaytracingDefault,
includes = GenerateIncludes(),
};
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.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()
{
return new PassDescriptor
{
// Definition
displayName = "ScenePickingPass",
referenceName = "SHADERPASS_DEPTH_ONLY",
lightMode = "Picking",
useInPreview = false,
// Collections
renderStates = CoreRenderStates.ScenePicking,
pragmas = CorePragmas.DotsInstancedInV1AndV2EditorSync,
defines = CoreDefines.ScenePicking,
includes = GenerateIncludes(),
};
IncludeCollection GenerateIncludes()
{
var includes = new IncludeCollection();
includes.Add(CoreIncludes.kPickingSpaceTransforms, IncludeLocation.Pregraph);
includes.Add(CoreIncludes.CorePregraph);
includes.Add(CoreIncludes.kPassPlaceholder, IncludeLocation.Pregraph);
includes.Add(CoreIncludes.CoreUtility);
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)
{
return new PassDescriptor
{
// Definition
displayName = "SceneSelectionPass",
referenceName = "SHADERPASS_DEPTH_ONLY",
lightMode = "SceneSelectionPass",
useInPreview = false,
// Collections
renderStates = CoreRenderStates.SceneSelection,
pragmas = CorePragmas.DotsInstancedInV1AndV2EditorSync,
defines = CoreDefines.SceneSelection,
includes = GenerateIncludes(),
};
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 Shadow Caster Pass
static public PassDescriptor GenerateShadowCaster(bool supportLighting)
{
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
renderStates = CoreRenderStates.ShadowCaster,
pragmas = CorePragmas.DotsInstancedInV2Only,
includes = GenerateIncludes(),
};
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)
{
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
requiredFields = CoreRequiredFields.Meta,
renderStates = CoreRenderStates.Meta,
pragmas = CorePragmas.DotsInstancedInV1AndV2,
defines = CoreDefines.ShaderGraphRaytracingDefault,
includes = GenerateIncludes(),
};
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.kPassLightTransport, IncludeLocation.Postgraph);
return includes;
}
}
#endregion
#region Depth Forward Only
public static PassDescriptor GenerateDepthForwardOnlyPass(bool supportLighting)
{
return new PassDescriptor
{
// Definition
displayName = "DepthForwardOnly",
referenceName = "SHADERPASS_DEPTH_ONLY",
lightMode = "DepthForwardOnly",
useInPreview = true,
// Collections
requiredFields = GenerateRequiredFields(),
renderStates = GenerateRenderState(),
pragmas = CorePragmas.DotsInstancedInV2Only,
defines = supportLighting ? CoreDefines.DepthForwardOnly : CoreDefines.DepthForwardOnlyUnlit,
includes = GenerateIncludes(),
};
RenderStateCollection GenerateRenderState()
{
var renderState = new RenderStateCollection { CoreRenderStates.DepthOnly };
return renderState;
}
FieldCollection GenerateRequiredFields()
{
return new FieldCollection()
{
HDStructFields.AttributesMesh.normalOS,
HDStructFields.AttributesMesh.tangentOS,
HDStructFields.AttributesMesh.uv0,
HDStructFields.AttributesMesh.uv1,
HDStructFields.AttributesMesh.color,
HDStructFields.AttributesMesh.uv2,
HDStructFields.AttributesMesh.uv3,
HDStructFields.FragInputs.tangentToWorld,
HDStructFields.FragInputs.positionRWS,
HDStructFields.FragInputs.texCoord1,
HDStructFields.FragInputs.texCoord2,
HDStructFields.FragInputs.texCoord3,
HDStructFields.FragInputs.color,
};
}
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)
{
return new PassDescriptor
{
// Definition
displayName = "MotionVectors",
referenceName = "SHADERPASS_MOTION_VECTORS",
lightMode = "MotionVectors",
useInPreview = false,
// Collections
requiredFields = CoreRequiredFields.LitFull,
renderStates = GenerateRenderState(),
defines = GenerateDefines(),
pragmas = CorePragmas.DotsInstancedInV2Only,
includes = GenerateIncludes(),
};
DefineCollection GenerateDefines()
{
if (!supportLighting)
{
// For shadow matte (unlit SG only) we need to enable write normal buffer
return CoreDefines.MotionVectorUnlit;
}
var defines = new DefineCollection { Defines.raytracingDefault };
// TODO: do a #define WRITE_NORMAL_BUFFER for motion vector in forward only material case instead of a multi-compile
// if (supportForward)
// {
// defines.Add(CoreKeywordDescriptors.WriteNormalBuffer, 1);
// }
return defines;
}
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)
{
return new PassDescriptor
{
// Definition
displayName = "ForwardOnly",
referenceName = supportLighting ? "SHADERPASS_FORWARD" : "SHADERPASS_FORWARD_UNLIT",
lightMode = "ForwardOnly",
useInPreview = true,
// Collections
requiredFields = GenerateRequiredFields(),
renderStates = CoreRenderStates.Forward,
pragmas = CorePragmas.DotsInstancedInV2Only,
defines = supportLighting ? CoreDefines.Forward : CoreDefines.ForwardUnlit,
includes = GenerateIncludes(),
virtualTextureFeedback = true,
};
FieldCollection GenerateRequiredFields()
{
if (supportLighting)
return CoreRequiredFields.LitFull;
else
{
return new FieldCollection
{
// TODO: add preprocessor protection for this interpolator: _TRANSPARENT_WRITES_MOTION_VEC
HDStructFields.FragInputs.positionRWS,
};
}
}
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)
{
return new PassDescriptor
{
// Definition
displayName = "TransparentBackface",
referenceName = supportLighting ? "SHADERPASS_FORWARD" : "SHADERPASS_FORWARD_UNLIT",
lightMode = "TransparentBackface",
useInPreview = true,
// Collections
requiredFields = CoreRequiredFields.LitMinimal,
renderStates = CoreRenderStates.TransparentBackface,
pragmas = CorePragmas.DotsInstancedInV1AndV2,
defines = CoreDefines.BackThenFront,
includes = GenerateIncludes(),
};
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)
{
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
requiredFields = TransparentDepthPrepassFields,
renderStates = GenerateRenderState(),
pragmas = CorePragmas.DotsInstancedInV1AndV2,
defines = CoreDefines.TransparentDepthPrepass,
includes = GenerateIncludes(),
};
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;
}
}
public static FieldCollection TransparentDepthPrepassFields = new FieldCollection()
{
HDStructFields.AttributesMesh.normalOS,
HDStructFields.AttributesMesh.tangentOS,
HDStructFields.AttributesMesh.uv0,
HDStructFields.AttributesMesh.uv1,
HDStructFields.AttributesMesh.color,
HDStructFields.AttributesMesh.uv2,
HDStructFields.AttributesMesh.uv3,
HDStructFields.FragInputs.tangentToWorld,
HDStructFields.FragInputs.positionRWS,
HDStructFields.FragInputs.texCoord1,
HDStructFields.FragInputs.texCoord2,
HDStructFields.FragInputs.texCoord3,
HDStructFields.FragInputs.color,
};
#endregion
#region Transparent Depth Postpass
public static PassDescriptor GenerateTransparentDepthPostpass(bool supportLighting)
{
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
renderStates = GenerateRenderState(),
pragmas = CorePragmas.DotsInstancedInV1AndV2,
defines = CoreDefines.TransparentDepthPostpass,
includes = GenerateIncludes(),
};
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()
{
return new PassDescriptor
{
displayName = "DepthOnly",
referenceName = "SHADERPASS_DEPTH_ONLY",
lightMode = "DepthOnly",
useInPreview = true,
// Collections
requiredFields = CoreRequiredFields.LitFull,
renderStates = CoreRenderStates.DepthOnly,
pragmas = CorePragmas.DotsInstancedInV1AndV2,
defines = CoreDefines.ShaderGraphRaytracingDefault,
keywords = LitDepthOnlyKeywords,
includes = DepthOnlyIncludes,
};
}
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()
{
return new PassDescriptor
{
// Definition
displayName = "GBuffer",
referenceName = "SHADERPASS_GBUFFER",
lightMode = "GBuffer",
useInPreview = true,
// Collections
requiredFields = CoreRequiredFields.LitMinimal,
renderStates = GBufferRenderState,
pragmas = CorePragmas.DotsInstancedInV1AndV2,
defines = CoreDefines.ShaderGraphRaytracingDefault,
keywords = GBufferKeywords,
includes = GBufferIncludes,
virtualTextureFeedback = true,
};
}
public static KeywordCollection GBufferKeywords = new KeywordCollection
{
{ CoreKeywordDescriptors.LightLayers },
};
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()
{
return new PassDescriptor
{
// Definition
displayName = "Forward",
referenceName = "SHADERPASS_FORWARD",
lightMode = "Forward",
useInPreview = true,
// Collections
requiredFields = CoreRequiredFields.LitMinimal,
renderStates = CoreRenderStates.Forward,
pragmas = CorePragmas.DotsInstancedInV1AndV2,
defines = CoreDefines.Forward,
includes = ForwardIncludes,
virtualTextureFeedback = true,
};
}
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
renderStates = RayTracingPrepassRenderState,
pragmas = CorePragmas.Basic,
defines = CoreDefines.ShaderGraphRaytracingDefault,
includes = RayTracingPrepassIncludes,
};
}
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.LitMinimal : null,
// Collections
pragmas = CorePragmas.RaytracingBasic,
defines = supportLighting ? RaytracingIndirectDefines : null,
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);
// 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.CoreUtility);
includes.Add(CoreIncludes.kRaytracingCommon, IncludeLocation.Pregraph);
includes.Add(CoreIncludes.kShaderGraphFunctions, IncludeLocation.Pregraph);
// post graph includes
includes.Add(CoreIncludes.kPassRaytracingIndirect, IncludeLocation.Postgraph);
return includes;
}
}
public static DefineCollection RaytracingIndirectDefines = new DefineCollection
{
{ Defines.shadowLow },
{ Defines.raytracingRaytraced },
{ 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
pragmas = CorePragmas.RaytracingBasic,
defines = supportLighting ? RaytracingVisibilityDefines : null,
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.LitMinimal : null,
// Port Mask
// validVertexBlocks = CoreBlockMasks.Vertex,
// validPixelBlocks = RaytracingForwardFragment,
// Collections
pragmas = CorePragmas.RaytracingBasic,
defines = supportLighting ? RaytracingForwardDefines : null,
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);
}
// 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);
// 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.CoreUtility);
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 },
};
#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.LitMinimal : null,
// Port Mask
// validVertexBlocks = CoreBlockMasks.Vertex,
// validPixelBlocks = RaytracingGBufferFragment,
// Collections
pragmas = CorePragmas.RaytracingBasic,
defines = supportLighting ? RaytracingGBufferDefines : null,
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);
// post graph includes
includes.Add(CoreIncludes.kPassRaytracingGBuffer, IncludeLocation.Postgraph);
return includes;
}
}
public static DefineCollection RaytracingGBufferDefines = new DefineCollection
{
{ Defines.shadowLow },
{ Defines.raytracingRaytraced },
};
#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
pragmas = CorePragmas.RaytracingBasic,
defines = supportLighting ? RaytracingPathTracingDefines : null,
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);
}
// 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);
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.raytracingDefault },
{ CoreKeywordDescriptors.HasLightloop, 1 },
};
#endregion
#region Raytracing Subsurface
public static PassDescriptor GenerateRaytracingSubsurface(bool supportLighting)
{
return new PassDescriptor
{
//Definition
displayName = "SubSurfaceDXR",
referenceName = "SHADERPASS_RAYTRACING_SUB_SURFACE",
lightMode = "SubSurfaceDXR",
useInPreview = false,
requiredFields = supportLighting ? CoreRequiredFields.LitMinimal : null,
// Template
// passTemplatePath = passTemplatePath,
// sharedTemplateDirectories = passTemplateMaterialDirectories,
// //Port mask
// validVertexBlocks = CoreBlockMasks.Vertex,
// validPixelBlocks = LitBlockMasks.FragmentDefault,
//Collections
pragmas = CorePragmas.RaytracingBasic,
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()
{
return new PassDescriptor
{
// Definition
displayName = "FullScreenDebug",
referenceName = "SHADERPASS_FULL_SCREEN_DEBUG",
lightMode = "FullScreenDebug",
useInPreview = false,
// Collections
pragmas = CorePragmas.Basic,
renderStates = FullScreenDebugRenderState,
includes = GenerateIncludes(),
};
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.Shadow, 0} };
public static DefineCollection shadowMedium = new DefineCollection { {CoreKeywordDescriptors.Shadow, 1} };
public static DefineCollection shadowHigh = new DefineCollection { {CoreKeywordDescriptors.Shadow, 2} };
// Raytracing Quality
public static DefineCollection raytracingDefault = new DefineCollection { { RayTracingQualityNode.GetRayTracingQualityKeyword(), 0} };
public static DefineCollection raytracingRaytraced = new DefineCollection { { RayTracingQualityNode.GetRayTracingQualityKeyword(), 1} };
}
#endregion
}
}