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

[2D SHADER] Unlock Dynamic 2D Fog of War Power

Solution

graphicsshadersrenderinglightingpost processing

Unity 2021.x - Unity 6.3.x

Published Sun, Mar 15

Issue

 The challenge involves implementing a dynamic fog of war mechanic in 2D environments where a dark overlay progressively reveals world areas. The primary difficulty lies in selectively modifying a RenderTexture in real-time to create transparent holes based on entity positions while maintaining performance and avoiding texture read/write feedback loops.

Explanation
  1. A RenderTexture is created to serve as the persistent visibility mask for the scene.
  2. The RenderTexture is assigned to a RawImage component located on a Canvas set to Screen Space - Camera.
  3. A custom Material using a subtraction or reveal shader is assigned to the RawImage to handle color and alpha blending.
  4. Entity world positions are converted into normalized UV coordinates by mapping the Transform position to the defined map dimensions.
  5. Normalized coordinates and the reveal radius are passed to your shader using Material.SetVector and Material.SetFloat.
  6. Graphics.Blit is executed to update the RenderTexture, utilizing a temporary buffer to prevent sampling conflicts during the read-write process.

The system operates by continuously clearing or modifying alpha values on the RenderTexture at entity coordinates. By using this persistent buffer, revealed areas remain visible as the player explores the environment.

Additional Tips

  • A lower resolution RenderTexture should be used to minimize GPU memory usage and naturally soften reveal edges.
  • Bilinear filtering must be enabled on the RenderTexture settings to ensure smooth transitions between revealed and hidden areas.
  • The Canvas sorting order should be configured to render above the game world but below the primary UI HUD elements.

TL;DR

Dynamic masking is achieved by rendering reveal shapes onto a RenderTexture via Graphics.Blit. This mask is applied to a full-screen RawImage component, where a custom shader manages the blending logic to punch holes through the fog based on world-space coordinates provided by your script.


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.