Skip to content

Fix depth offset and transparent motion vector for unlit transparent #896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public override void GetFields(ref TargetFieldContext context)
context.AddField(HDFields.Eye, eyeData.materialType == EyeData.MaterialType.Eye);
context.AddField(HDFields.EyeCinematic, eyeData.materialType == EyeData.MaterialType.EyeCinematic);
context.AddField(HDFields.SubsurfaceScattering, eyeData.subsurfaceScattering && systemData.surfaceType != SurfaceType.Transparent);
context.AddField(HDFields.DoAlphaTest, systemData.alphaTest && context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold));
}

public override void GetActiveBlocks(ref TargetActiveBlockContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public override void GetFields(ref TargetFieldContext context)
context.AddField(HDFields.Silk, fabricData.materialType == FabricData.MaterialType.Silk);
context.AddField(HDFields.SubsurfaceScattering, fabricData.subsurfaceScattering && systemData.surfaceType != SurfaceType.Transparent);
context.AddField(HDFields.Transmission, fabricData.transmission);
context.AddField(HDFields.DoAlphaTest, systemData.alphaTest && context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold));
context.AddField(HDFields.EnergyConservingSpecular, fabricData.energyConservingSpecular);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,6 @@ public override void GetFields(ref TargetFieldContext context)
context.AddField(HDFields.UseLightFacingNormal, hairData.useLightFacingNormal);
context.AddField(HDFields.Transmittance, descs.Contains(HDBlockFields.SurfaceDescription.Transmittance) && context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.Transmittance));

// All the DoAlphaXXX field drive the generation of which code to use for alpha test in the template
// Do alpha test only if we aren't using the TestShadow one
context.AddField(HDFields.DoAlphaTest, systemData.alphaTest && (context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold) &&
!(builtinData.alphaTestShadow && context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow))));

// Misc
context.AddField(HDFields.SpecularAA, lightingData.specularAA &&
context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.SpecularAAThreshold) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,6 @@ public override void GetFields(ref TargetFieldContext context)
context.AddField(HDFields.RefractionSphere, hasRefraction && litData.refractionModel == ScreenSpaceRefraction.RefractionModel.Sphere);
context.AddField(HDFields.RefractionThin, hasRefraction && litData.refractionModel == ScreenSpaceRefraction.RefractionModel.Thin);

// AlphaTest
// All the DoAlphaXXX field drive the generation of which code to use for alpha test in the template
// Do alpha test only if we aren't using the TestShadow one
context.AddField(HDFields.DoAlphaTest, systemData.alphaTest && (context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold) &&
!(builtinData.alphaTestShadow && context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow))));

// Misc

context.AddField(HDFields.EnergyConservingSpecular, litData.energyConservingSpecular);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,19 +213,34 @@ public override void GetFields(ref TargetFieldContext context)
context.AddField(Fields.BlendAlpha, systemData.surfaceType != SurfaceType.Opaque && systemData.blendMode == BlendMode.Alpha);
context.AddField(Fields.BlendPremultiply, systemData.surfaceType != SurfaceType.Opaque && systemData.blendMode == BlendMode.Premultiply);

// We always generate the keyword ALPHATEST_ON
context.AddField(Fields.AlphaTest, systemData.alphaTest
&& (context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold)
|| context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow)
|| context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass)
|| context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPostpass)));

// Double Sided
context.AddField(HDFields.DoubleSided, systemData.doubleSidedMode != DoubleSidedMode.Disabled);
context.AddField(HDFields.DoubleSided, systemData.doubleSidedMode != DoubleSidedMode.Disabled);

// We always generate the keyword ALPHATEST_ON. All the variant of AlphaClip (shadow, pre/postpass) are only available if alpha test is on.
context.AddField(Fields.AlphaTest, systemData.alphaTest
&& (context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold)
|| context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow)
|| context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass)
|| context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPostpass)));

// All the DoAlphaXXX field drive the generation of which code to use for alpha test in the template
// Regular alpha test is only done if artist haven't ask to use the specific alpha test shadow one
bool isShadowPass = context.pass.lightMode == "ShadowCaster";
bool isTransparentDepthPrepass = context.pass.lightMode == "TransparentDepthPrepass";
bool isTransparentDepthPostpass = context.pass.lightMode == "TransparentDepthPostpass";
context.AddField(HDFields.DoAlphaTest, systemData.alphaTest && (context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold) &&
!(isShadowPass && builtinData.alphaTestShadow && context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow))
));

// Shadow use the specific alpha test only if user have ask to override it
context.AddField(HDFields.DoAlphaTestShadow, systemData.alphaTest && builtinData.alphaTestShadow && isShadowPass &&
context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow));
// Pre/post pass always use the specific alpha test provided for those pass
context.AddField(HDFields.DoAlphaTestPrepass, systemData.alphaTest && systemData.alphaTestDepthPrepass && isTransparentDepthPrepass &&
context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass));
context.AddField(HDFields.DoAlphaTestPostpass, systemData.alphaTest && systemData.alphaTestDepthPostpass && isTransparentDepthPostpass &&
context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPostpass));

context.AddField(HDFields.DoAlphaTestPrepass, systemData.alphaTest && systemData.alphaTestDepthPrepass && context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass));
context.AddField(HDFields.DoAlphaTestPostpass, systemData.alphaTest && systemData.alphaTestDepthPostpass && context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPostpass));
context.AddField(HDFields.DoAlphaTestShadow, systemData.alphaTest && builtinData.alphaTestShadow && context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow));

context.AddField(HDFields.TransparentDepthPrePass, systemData.surfaceType != SurfaceType.Opaque && systemData.alphaTestDepthPrepass);
context.AddField(HDFields.TransparentDepthPostPass, systemData.surfaceType != SurfaceType.Opaque && systemData.alphaTestDepthPostpass);
Expand Down Expand Up @@ -269,14 +284,11 @@ public override void GetActiveBlocks(ref TargetActiveBlockContext context)

// Alpha Test
context.AddBlock(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPrepass,
systemData.surfaceType == SurfaceType.Transparent && systemData.alphaTest && systemData.alphaTestDepthPrepass
&& (context.pass != null && context.pass.Value.lightMode == "TransparentDepthPrepass"));
systemData.surfaceType == SurfaceType.Transparent && systemData.alphaTest && systemData.alphaTestDepthPrepass);
context.AddBlock(HDBlockFields.SurfaceDescription.AlphaClipThresholdDepthPostpass,
systemData.surfaceType == SurfaceType.Transparent && systemData.alphaTest && systemData.alphaTestDepthPostpass
&& (context.pass != null && context.pass.Value.lightMode == "TransparentDepthPostpass"));
systemData.surfaceType == SurfaceType.Transparent && systemData.alphaTest && systemData.alphaTestDepthPostpass);
context.AddBlock(HDBlockFields.SurfaceDescription.AlphaClipThresholdShadow,
systemData.alphaTest && builtinData.alphaTestShadow
&& (context.pass != null && context.pass.Value.lightMode == "ShadowCaster"));
systemData.alphaTest && builtinData.alphaTestShadow);

// Misc
context.AddBlock(HDBlockFields.SurfaceDescription.DepthOffset, builtinData.depthOffset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Pass

// Specific Material Define
$include("ShaderPassDefine.template.hlsl")
// Caution: we can use the define SHADER_UNLIT onlit after the above Material include as it is the Unlit template who define it

#ifndef DEBUG_DISPLAY
// In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)
Expand Down Expand Up @@ -265,14 +266,14 @@ Pass

void GetSurfaceAndBuiltinData(FragInputs fragInputs, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData RAY_TRACING_OPTIONAL_PARAMETERS)
{
#ifndef SHADER_UNLIT
// Don't dither if displaced tessellation (we're fading out the displacement instead to match the next LOD)
#if !defined(SHADER_STAGE_RAY_TRACING) && !defined(_TESSELLATION_DISPLACEMENT)
#ifdef LOD_FADE_CROSSFADE // enable dithering LOD transition if user select CrossFade transition in LOD group
LODDitheringTransition(ComputeFadeMaskSeed(V, posInput.positionSS), unity_LODFade.x);
#endif
#endif

#ifndef SHADER_UNLIT
#ifdef _DOUBLESIDED_ON
float3 doubleSidedConstants = _DoubleSidedConstants.xyz;
#else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ public override void GetFields(ref TargetFieldContext context)
stackLitData.dualSpecularLobeParametrization == StackLit.DualSpecularLobeParametrization.HazyGloss);

// Misc
context.AddField(HDFields.DoAlphaTest, systemData.alphaTest && context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold));
context.AddField(HDFields.EnergyConservingSpecular, stackLitData.energyConservingSpecular);
context.AddField(HDFields.Tangent, descs.Contains(HDBlockFields.SurfaceDescription.Tangent) &&
context.pass.validPixelBlocks.Contains(HDBlockFields.SurfaceDescription.Tangent));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,15 @@ public override void GetFields(ref TargetFieldContext context)
base.GetFields(ref context);

// Unlit specific properties
context.AddField(HDFields.EnableShadowMatte, unlitData.enableShadowMatte);
context.AddField(HDFields.DoAlphaTest, systemData.alphaTest && context.pass.validPixelBlocks.Contains(BlockFields.SurfaceDescription.AlphaClipThreshold));
context.AddField(HDFields.EnableShadowMatte, unlitData.enableShadowMatte);
}

public override void GetActiveBlocks(ref TargetActiveBlockContext context)
{
base.GetActiveBlocks(ref context);

// Unlit specific blocks
context.AddBlock(HDBlockFields.SurfaceDescription.ShadowTint, unlitData.enableShadowMatte);
context.AddBlock(HDBlockFields.SurfaceDescription.ShadowTint, unlitData.enableShadowMatte);
}

protected override void AddInspectorPropertyBlocks(SubTargetPropertiesGUI blockList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@
#error SHADERPASS_is_not_correctly_define
#endif

#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/MotionVectorVertexShaderCommon.hlsl"

PackedVaryingsType Vert(AttributesMesh inputMesh, AttributesPass inputPass)
{
VaryingsType varyingsType;
varyingsType.vmesh = VertMesh(inputMesh);
return MotionVectorVS(varyingsType, inputMesh, inputPass);
}

#ifdef TESSELLATION_ON

PackedVaryingsToPS VertTesselation(VaryingsToDS input)
{
VaryingsToPS output;
output.vmesh = VertMeshTesselation(input.vmesh);
MotionVectorPositionZBias(output);

output.vpass.positionCS = input.vpass.positionCS;
output.vpass.previousPositionCS = input.vpass.previousPositionCS;

return PackVaryingsToPS(output);
}

#endif // TESSELLATION_ON

#else // _WRITE_TRANSPARENT_MOTION_VECTOR

#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl"

PackedVaryingsType Vert(AttributesMesh inputMesh)
Expand All @@ -20,17 +48,40 @@ PackedVaryingsToPS VertTesselation(VaryingsToDS input)
return PackVaryingsToPS(output);
}

#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/TessellationShare.hlsl"

#endif // TESSELLATION_ON

void Frag(PackedVaryingsToPS packedInput,
out float4 outResult : SV_Target0
#endif // _WRITE_TRANSPARENT_MOTION_VECTOR

#ifdef TESSELLATION_ON
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/TessellationShare.hlsl"
#endif

#ifdef UNITY_VIRTUAL_TEXTURING
,out float4 outVTFeedback : SV_Target1
#define VT_BUFFER_TARGET SV_Target1
#define EXTRA_BUFFER_TARGET SV_Target2
#else
#define EXTRA_BUFFER_TARGET SV_Target1
#endif

void Frag(PackedVaryingsToPS packedInput,
out float4 outColor : SV_Target0
#ifdef UNITY_VIRTUAL_TEXTURING
,out float4 outVTFeedback : VT_BUFFER_TARGET
#endif
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
, out float4 outMotionVec : EXTRA_BUFFER_TARGET
#endif
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
// Init outMotionVector here to solve compiler warning (potentially unitialized variable)
// It is init to the value of forceNoMotion (with 2.0)
outMotionVec = float4(2.0, 0.0, 0.0, 0.0);
#endif

UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);

Expand All @@ -52,8 +103,8 @@ void Frag(PackedVaryingsToPS packedInput,
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(input.positionSS.xy, surfaceData);

// Note: we must not access bsdfData in shader pass, but for unlit we make an exception and assume it should have a color field
float4 outColor = ApplyBlendMode(bsdfData.color + builtinData.emissiveColor * GetCurrentExposureMultiplier(), builtinData.opacity);
outColor = EvaluateAtmosphericScattering(posInput, V, outColor);
float4 outResult = ApplyBlendMode(bsdfData.color + builtinData.emissiveColor * GetCurrentExposureMultiplier(), builtinData.opacity);
outResult = EvaluateAtmosphericScattering(posInput, V, outResult);

#ifdef DEBUG_DISPLAY
// Same code in ShaderPassForward.shader
Expand Down Expand Up @@ -86,19 +137,35 @@ void Frag(PackedVaryingsToPS packedInput,
if (!needLinearToSRGB)
result = SRGBToLinear(max(0, result));

outColor = float4(result, 1.0);
outResult = float4(result, 1.0);
}
}

if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_TRANSPARENCY_OVERDRAW)
{
float4 result = _DebugTransparencyOverdrawWeight * float4(TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_COST, TRANSPARENCY_OVERDRAW_A);
outColor = result;
outResult = result;
}

#endif

outResult = outColor;
outColor = outResult;

#ifdef _WRITE_TRANSPARENT_MOTION_VECTOR
VaryingsPassToPS inputPass = UnpackVaryingsPassToPS(packedInput.vpass);
bool forceNoMotion = any(unity_MotionVectorsParams.yw == 0.0);
// outMotionVec is already initialize at the value of forceNoMotion (see above)
if (!forceNoMotion)
{
float2 motionVec = CalculateMotionVector(inputPass.positionCS, inputPass.previousPositionCS);
EncodeMotionVector(motionVec * 0.5, outMotionVec);
outMotionVec.zw = 1.0;
}
#endif

#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif

#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
Expand Down