UnityRef is currently in early development. Some features may be incomplete and/or not functioning.

UNITYREF

Your Pit Stop For Solving ANYTHING in Unity

graphics

[URP] Fix Custom Toon Shader Dithering Ghosting Artifacts

Solution

graphicsshaderslighting

Unity 2021.x - Unity 6.3.x

Published 14 days ago

Issue

 A custom toon shader incorporating multi-light response and dithered shadow attenuation exhibits an issue where fully dithered objects leave behind unlit transparent versions, creating ghosting artifacts. This behavior manifests specifically when attempting to include shadow casting from other objects, leading to incorrect transparency and visual glitches where the geometry remains partially visible instead of discarding fragments.

Explanation

The integration of custom lighting within a ShaderGraph or HLSL shader can alter the default behavior of alpha clipping, leading to transparency issues when dithering is applied. To resolve this, the AlphaClipThreshold logic must be configured to correctly interact with the dithered noise pattern. 1. In the ShaderGraph settings or your HLSL Properties block, ensure that AlphaClipThreshold is enabled and set to a value greater than 0. 2. Use a Dither node (or a custom Bayer matrix function) to generate a screen-space pattern. 3. Subtract your desired opacity or shadow attenuation from this dither pattern. 4. Output the result into the AlphaClipThreshold port of the Fragment stack. 5. Ensure the SurfaceType is set to Opaque while Alpha Clipping is active to prevent sorting issues associated with Transparent render queues.

This approach ensures that the GPU invokes the discard instruction on fragments that fall below the threshold, preventing the ‘unlit’ ghosting effect where the mesh is still technically being drawn with zero light.

Additional Tips:

  • Check that your ShadowCaster pass also implements the same dithering logic to avoid shadow-only ghosting.
  • Verify that ZWrite is set to On to ensure the depth buffer is correctly populated for dithered surfaces.
  • If using Unity 6, leverage the ScreenSpaceDither node for more stable temporal results in the AlphaClipThreshold.

TL;DR

To eliminate dithering ghosting, the shader must synchronize the AlphaClipThreshold with a screen-space dither pattern. If using ShaderGraph, ensure the Alpha Clipping logic is explicitly driven by the combined value of your opacity and shadow attenuation to force a hard discard on the GPU.


Related Posts Haven't quite found a solution to your problem? We think these posts might help you.

Content inspired by a Unity discussion post.