Added stencil setup in UTSAPI;
Changed hair shadow length from screen space to world space;
This commit is contained in:
@@ -4,24 +4,57 @@ using static Misaki.HdrpToon.UTSPropertyName;
|
||||
|
||||
namespace Misaki.HdrpToon
|
||||
{
|
||||
internal enum RenderPriority
|
||||
{
|
||||
Opaque = RenderQueue.Geometry,
|
||||
OpaqueDecal = RenderQueue.Geometry + 225, // Opaque Decal mean Opaque that can receive decal
|
||||
OpaqueAlphaTest = RenderQueue.AlphaTest,
|
||||
OpaqueDecalAlphaTest = RenderQueue.AlphaTest + 25,
|
||||
// Warning: we must not change Geometry last value to stay compatible with occlusion
|
||||
OpaqueLast = RenderQueue.GeometryLast,
|
||||
|
||||
AfterPostprocessOpaque = RenderQueue.GeometryLast + 1,
|
||||
AfterPostprocessOpaqueAlphaTest = RenderQueue.GeometryLast + 10,
|
||||
|
||||
TransparentFirst = RenderQueue.Transparent - 100,
|
||||
Transparent = RenderQueue.Transparent,
|
||||
TransparentLast = RenderQueue.Transparent + 100,
|
||||
}
|
||||
|
||||
internal enum StencilUsage
|
||||
{
|
||||
Clear = 0,
|
||||
|
||||
// Note: first bit is free and can still be used by both phases.
|
||||
|
||||
// --- Following bits are used before transparent rendering ---
|
||||
IsUnlit = (1 << 0), // Unlit materials (shader and shader graph) except for the shadow matte
|
||||
RequiresDeferredLighting = (1 << 1),
|
||||
SubsurfaceScattering = (1 << 2), // SSS, Split Lighting
|
||||
TraceReflectionRay = (1 << 3), // SSR or RTR - slot is reuse in transparent
|
||||
Decals = (1 << 4), // Use to tag when an Opaque Decal is render into DBuffer
|
||||
ObjectMotionVector = (1 << 5), // Animated object (for motion blur, SSR, SSAO, TAA)
|
||||
|
||||
// --- Stencil is cleared after opaque rendering has finished ---
|
||||
|
||||
// --- Following bits are used exclusively for what happens after opaque ---
|
||||
WaterExclusion = (1 << 0), // Prevents water surface from being rendered.
|
||||
ExcludeFromTUAndAA = (1 << 1), // Disable Temporal Upscaling and Antialiasing for certain objects
|
||||
DistortionVectors = (1 << 2), // Distortion pass - reset after distortion pass, shared with SMAA
|
||||
SMAA = (1 << 2), // Subpixel Morphological Antialiasing
|
||||
// Reserved TraceReflectionRay = (1 << 3) for transparent SSR or RTR
|
||||
Refractive = (1 << 4), // Indicates there's a refractive object
|
||||
WaterSurface = (1 << 5), // Reserved for water surface usage (If update the value of 'STENCILUSAGE_WATER_SURFACE' in LensFlareCommon.hlsl)
|
||||
|
||||
// --- Following are user bits, we don't touch them inside HDRP and is up to the user to handle them ---
|
||||
UserBit0 = (1 << 6),
|
||||
UserBit1 = (1 << 7),
|
||||
|
||||
HDRPReservedBits = 255 & ~(UserBit0 | UserBit1),
|
||||
}
|
||||
|
||||
internal class UTSAPI
|
||||
{
|
||||
private enum RenderPriority
|
||||
{
|
||||
Opaque = RenderQueue.Geometry,
|
||||
OpaqueDecal = RenderQueue.Geometry + 225, // Opaque Decal mean Opaque that can receive decal
|
||||
OpaqueAlphaTest = RenderQueue.AlphaTest,
|
||||
OpaqueDecalAlphaTest = RenderQueue.AlphaTest + 25,
|
||||
// Warning: we must not change Geometry last value to stay compatible with occlusion
|
||||
OpaqueLast = RenderQueue.GeometryLast,
|
||||
|
||||
AfterPostprocessOpaque = RenderQueue.GeometryLast + 1,
|
||||
AfterPostprocessOpaqueAlphaTest = RenderQueue.GeometryLast + 10,
|
||||
|
||||
TransparentFirst = RenderQueue.Transparent - 100,
|
||||
Transparent = RenderQueue.Transparent,
|
||||
TransparentLast = RenderQueue.Transparent + 100,
|
||||
}
|
||||
|
||||
public static void SetupPass(Material material)
|
||||
{
|
||||
@@ -39,6 +72,80 @@ namespace Misaki.HdrpToon
|
||||
CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable);
|
||||
}
|
||||
|
||||
static public void ComputeStencilProperties(bool receivesLighting, bool forwardOnly, bool receivesSSR, bool useSplitLighting, bool hasRefraction, bool excludeFromTUAndAA,
|
||||
out int stencilRef, out int stencilWriteMask, out int stencilRefDepth, out int stencilWriteMaskDepth, out int stencilRefGBuffer, out int stencilWriteMaskGBuffer, out int stencilRefMV, out int stencilWriteMaskMV)
|
||||
{
|
||||
// Stencil usage rules:
|
||||
// TraceReflectionRay need to be tagged during depth prepass
|
||||
// RequiresDeferredLighting need to be tagged during GBuffer
|
||||
// SubsurfaceScattering need to be tagged during either GBuffer or Forward pass
|
||||
// ObjectMotionVectors need to be tagged in velocity pass.
|
||||
// As motion vectors pass can be use as a replacement of depth prepass it also need to have TraceReflectionRay
|
||||
// As GBuffer pass can have no depth prepass, it also need to have TraceReflectionRay
|
||||
// Object motion vectors is always render after a full depth buffer (if there is no depth prepass for GBuffer all object motion vectors are render after GBuffer)
|
||||
// so we have a guarantee than when we write object motion vectors no other object will be draw on top (and so would have require to overwrite motion vectors).
|
||||
// Final combination is:
|
||||
// Prepass: TraceReflectionRay
|
||||
// Motion vectors: TraceReflectionRay, ObjectVelocity
|
||||
// GBuffer: LightingMask, ObjectVelocity
|
||||
// Forward: LightingMask
|
||||
|
||||
stencilRef = (int)StencilUsage.Clear; // Forward case
|
||||
stencilWriteMask = (int)StencilUsage.RequiresDeferredLighting | (int)StencilUsage.SubsurfaceScattering;
|
||||
stencilRefDepth = 0;
|
||||
stencilWriteMaskDepth = 0;
|
||||
stencilRefGBuffer = (int)StencilUsage.RequiresDeferredLighting;
|
||||
stencilWriteMaskGBuffer = (int)StencilUsage.RequiresDeferredLighting | (int)StencilUsage.SubsurfaceScattering;
|
||||
stencilRefMV = (int)StencilUsage.ObjectMotionVector;
|
||||
stencilWriteMaskMV = (int)StencilUsage.ObjectMotionVector;
|
||||
|
||||
// ForwardOnly materials with motion vectors are rendered after GBuffer, so we need to clear the deferred bit in the stencil
|
||||
if (forwardOnly)
|
||||
stencilWriteMaskMV |= (int)StencilUsage.RequiresDeferredLighting;
|
||||
|
||||
if (useSplitLighting)
|
||||
{
|
||||
stencilRefGBuffer |= (int)StencilUsage.SubsurfaceScattering;
|
||||
stencilRef |= (int)StencilUsage.SubsurfaceScattering;
|
||||
}
|
||||
|
||||
if (receivesSSR)
|
||||
{
|
||||
stencilRefDepth |= (int)StencilUsage.TraceReflectionRay;
|
||||
stencilRefGBuffer |= (int)StencilUsage.TraceReflectionRay;
|
||||
stencilRefMV |= (int)StencilUsage.TraceReflectionRay;
|
||||
}
|
||||
|
||||
stencilWriteMaskDepth |= (int)StencilUsage.TraceReflectionRay;
|
||||
stencilWriteMaskGBuffer |= (int)StencilUsage.TraceReflectionRay;
|
||||
stencilWriteMaskMV |= (int)StencilUsage.TraceReflectionRay;
|
||||
|
||||
if (hasRefraction)
|
||||
{
|
||||
stencilRefDepth |= (int)StencilUsage.Refractive;
|
||||
stencilWriteMaskDepth |= (int)StencilUsage.Refractive;
|
||||
}
|
||||
|
||||
if (!receivesLighting)
|
||||
{
|
||||
stencilRefDepth |= (int)StencilUsage.IsUnlit;
|
||||
stencilWriteMaskDepth |= (int)StencilUsage.IsUnlit;
|
||||
stencilRefMV |= (int)StencilUsage.IsUnlit;
|
||||
}
|
||||
|
||||
if (excludeFromTUAndAA)
|
||||
{
|
||||
stencilRefDepth |= (int)StencilUsage.ExcludeFromTUAndAA;
|
||||
stencilRef |= (int)StencilUsage.ExcludeFromTUAndAA;
|
||||
stencilWriteMask |= (int)StencilUsage.ExcludeFromTUAndAA;
|
||||
stencilWriteMaskDepth |= (int)StencilUsage.ExcludeFromTUAndAA;
|
||||
}
|
||||
|
||||
stencilWriteMaskDepth |= (int)StencilUsage.IsUnlit;
|
||||
stencilWriteMaskGBuffer |= (int)StencilUsage.IsUnlit;
|
||||
stencilWriteMaskMV |= (int)StencilUsage.IsUnlit;
|
||||
}
|
||||
|
||||
public static void SetupProperties(Material material)
|
||||
{
|
||||
var surfaceType = (SurfaceType)material.GetInteger(SurfaceOptions.SURFACE_TYPE);
|
||||
@@ -119,15 +226,32 @@ namespace Misaki.HdrpToon
|
||||
|
||||
if (isBackFaceEnable)
|
||||
{
|
||||
material.SetInt(InternalProperties.CULL_MODE_FORWARD, (int)CullMode.Back);
|
||||
material.SetInteger(InternalProperties.CULL_MODE_FORWARD, (int)CullMode.Back);
|
||||
}
|
||||
else
|
||||
{
|
||||
material.SetInteger(InternalProperties.CULL_MODE_FORWARD, (int)(doubleSidedEnable ? CullMode.Off : cullMode));
|
||||
}
|
||||
|
||||
// TODO: Setup stencil value. Currently it produce noticeable jittering when surface type is transparent.
|
||||
// This is caused by taa, _StencilWriteMask need to include StencilUsage.ExcludeFromTUAndAA when surface type is transparent.
|
||||
// Stencil
|
||||
ComputeStencilProperties(true, true, true, false, false, false,
|
||||
out var stencilRef, out var stencilWriteMask, out var stencilRefDepth, out var stencilWriteMaskDepth,
|
||||
out var stencilRefGBuffer, out var stencilWriteMaskGBuffer, out var stencilRefMV, out var stencilWriteMaskMV);
|
||||
|
||||
material.SetInteger(InternalProperties.STENCIL_REF, stencilRef);
|
||||
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK, stencilWriteMask);
|
||||
|
||||
material.SetInteger(InternalProperties.STENCIL_REF_DEPTH, stencilRefDepth);
|
||||
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK_DEPTH, stencilWriteMaskDepth);
|
||||
|
||||
material.SetInteger(InternalProperties.STENCIL_REF_G_BUFFER, stencilRefGBuffer);
|
||||
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK_G_BUFFER, stencilWriteMaskGBuffer);
|
||||
|
||||
material.SetInteger(InternalProperties.STENCIL_REF_DISTORTION_VEC, (int)StencilUsage.DistortionVectors);
|
||||
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK_DISTORTION_VEC, (int)StencilUsage.DistortionVectors);
|
||||
|
||||
material.SetInteger(InternalProperties.STENCIL_REF_MV, stencilRefMV);
|
||||
material.SetInteger(InternalProperties.STENCIL_WRITE_MASK_MV, stencilWriteMaskMV);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user