[URP] Reveal Sprites Only Within Occluded Light Cones
Solution
Unity 2022.3.x - Unity 6.3.x
Published Wed, Mar 25
A common challenge in top-down projects involves rendering enemies visible only when illuminated by your light cone. Surrounding ambient light must not affect visibility, and enemies should not be seen through ShadowCaster2D obstructions. Implementing this via simple distance-based shaders fails because it ignores environmental occlusion, while standard Light2D blending doesn't support an 'invisible unless lit' state without affecting the entire scene's global illumination.
To implement selective visibility that respects occlusion, you must leverage the Stencil buffer to create a mask where your light hits.
- Create a new Stencil-aware shader for your enemy sprites.
- Add a Stencil block to your shader that checks for a specific Ref value (e.g., 1).
- Set the Comp parameter to Equal so the sprite only renders where the buffer matches.
- Configure a
ScriptableRenderFeatureto draw your vision cone geometry into the Stencil buffer before enemies are rendered. - Ensure ShadowCaster2D components are on the correct layers to block the Stencil-writing pass, effectively creating a visibility shadow.
Additional Tips:
- Ensure the Stencil reference value in your shader matches the value written by your
ScriptableRenderFeature. - Use Sorting Layers to guarantee the visibility mask is drawn to the buffer before the enemy
SpriteRenderercomponents. - If using
ShaderGraph, you can enable Stencil overrides in the Graph Settings to avoid writing custom HLSL code.
TL;DR
Utilize Stencil buffers to mask enemy sprites based on your Light2D volume, ensuring they remain hidden when outside the cone or behind obstacles.
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.