Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Fog of war (URP) on large maps without tanking performance

Discussion in 'Scripting' started by Foxhound634, Jun 12, 2023.

  1. Foxhound634

    Foxhound634

    Joined:
    Mar 31, 2021
    Posts:
    2
    Hi there

    I have an isometric strategy game that needs a fog of war system. It needs to be URP compatible, and it needs to work on (very) large maps with decent performance.

    We followed this tutorial, which worked well before converting to URP https://andrewhungblog.wordpress.com/2018/06/23/implementing-fog-of-war-in-unity/

    But now the performance is utterly tanking, around 1-2 fps. So how do we make a system that fulfills all these criteria?

    EDIT: My bad, the performance thing was from something unrelated.

    The actual problem is that on a terrain with multiple texture layers, Unity will only render on the first four and not the rest, and we use A LOT of layers. But even then it might not cover the map in 'darkness', it just seems to make objects darker while still being able to see what the object is based on the shape.
     
    Last edited: Jun 12, 2023
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    I've checked that tutorial. For the first look that solution performance is not relied to the map size, more to the units count. That tutorial is about generating a mesh for the visible area of every single unit, rendering it to the texture and then bluring the edges.
    You shoudl check the profiler for what;s really kills your performance. Have you looked into that?
     
    angrypenguin likes this.
  3. Foxhound634

    Foxhound634

    Joined:
    Mar 31, 2021
    Posts:
    2
    My bad, the performance thing was from something unrelated.

    The actual problem is that on a terrain with multiple texture layers, Unity will only render on the first four and not the rest, and we use A LOT of layers. But even then it might not cover the map in 'darkness', it just seems to make objects darker while still being able to see what the object is based on the shape.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Fog of war visuals should only be created / updated for the portion of the world you can see, eg, what fits on screen.

    No sense making a massive chunk of geometry every frame that you can only see a tiny part of.

    FOW is also difficult to get right with perspective cameras, for obvious reasons.
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,503
    I'd consider a couple of approaches here.

    1. Post process effect.
    Render a texture surrounding the current camera view with your visibility data. Then, in a post-process effect, convert each pixel's world-space position into that texture's local space, and look up whether or not it should be visible. Interpolate the pixel between its original colour and whatever fogged-out colour / pattern / effect you want.

    2. Build it into shaders.
    Again, render your visibility texture for the area surrounding the camera. Create a custom version of the URP Lit shader, terrain shader, and whatever others you're using, which does the interpolation from the above approach in-place. Use a shader include file, of course, rather than repeating the code!

    This is more work because:
    • you need to manually integrate it into whatever shaders you're using; and
    • if you update Unity or 3rd party assets with shaders, you'll potentially need to re-integrate it.

    The benefit is that it doesn't involve having the GPU apply "normal" shading to pixels and then come back later to overwrite it, it just picks and uses the correct shading in the first place.

    3. Investigate a deferred approach.
    I'm no expert on this stuff, but I suspect that you could do something like a "visibility pre-pass", and then use that to render normal materials everywhere they're visible, then the fog effect everywhere else and blended along the edges, without having to modify the other shaders.

    This is a design issue. A few approaches to consider:
    • Lock the camera angle such that players can't see silhouettes where they're an issue.
    • If an object should not be visible at all, then don't draw it at all.
    • Use vertex shaders to modify the shape, e.g. shrink or warp them.
    • Use stipple alpha to fade it out.
    Lots of layers is a good way to tank performance, for sure. I'd suggest looking into other terrain shaders. I've had good experience with MicroSplat. My understanding is that while it allows you to paint as many layers as you want, it samples and blends between the top 3, so you get the look of lots of layers without the GPU-crippling cost.