[TUTORIAL] Fog Of War

Meh, i commented clientmessage in cpp file and now it doesnt crash. also changed fowmanager.h -

so now i can register my actor via bp. But anyways i got whole map dark. What can be wrong?

Hi,

Is it all dark in the editor? Or just when you’re in-game? There are quite a few places where it can fail…

  1. Make sure that the blueprint actor inheriting from FogOfWarManager is located at [0, 0, 0].
  2. Make sure that all the actors registered to the FogOfWarManager are not of the collision channel type ECC_WorldStatic.
  3. Make sure that all the blueprints are identical to the ones in the main post.
  4. The project is depending (roughly) on a scale of 100UU = 100cm, if your scale is way off the effect might not be rendered at all.
  5. If you debug the event graph in your blueprint inheriting from FogOfWarManager in the section “Set blending factor between FOW-textures”, the value “FOWTexture Blend” should increase from 0.0->1.0 a few times every second.
  6. While debugging the C++ source make sure your actors are correctly registered by checking that the field TArray<AActor*> FowActors is non-empty. You could also debug FogOfWarWorker’s method void AFogOfWarWorker::UpdateFowTexture() and watch the set TSet<FVector2D> texelsToBlur; If this collection is empty at the end of the method, no texels has been selected for unfogging and blurring.

If everything else fails you could always upload your project and PM me the link, and I can take a look at it.

Cheers,

Yeah, its all dark when i start game, in editor also dark, but its k, as i understand.

  1. its located at 0 0 0
  2. I`ve checked with print string, actor successfully added to fog of war manager
  3. bp is ok
  4. i dont know where must i set scale and how to understand what scale do i need? i have a landscape
  5. Its changing one time and then its always 1.0
  1. Already checked, the are registred. texelstoblur wasnt checked by me.

Yeah, i found mismatch in my bp, fixed it. Now whole map is opened, when i register actor =/

Okay, if the FowTexture blend is never reset to zero, that’s an indication that the Event OnFow Texture Updated is never firing. This event should be firing a few times every second. If you look at the blueprint surrounded by the comment “Update FOWTextures” in the first post this block of the blueprint should reset the FOWTextureBlend to 0.0. I had another user with the same problem, and for some reason the event was renamed to “OnFow Texture Updated_copy” or something like that, thus it was never “found” by the C++. You could try deleting that particular event node and drag it into the blueprint again and then hook it up again as depicted in the first post.

Cheers,

Okay, that’s an improvement :slight_smile: Do you have anything to block the Line of sight inside the level with collision channel World_Static? Also scale matters here. The sight range is by default 900 UU (unreal units) which should correspond to 9 meters. If your scaling differs that could impact the sight range.

Im spamming too much, ive fixed everything.
I have only 2 questions now.

  1. How to ‘open’ whole map, so i dont need to discover it?
  2. How to fix this? I dont need pawns to affect sight, so they musnt block vision.

  1. Locate the lines in FogOfWarManager
    TextureData.Init(FColor(0, 0, 0, 255), arraySize);
    LastFrameTextureData.Init(FColor(0, 0, 0, 255), arraySize);

Change the zeroes to e.g. 127

  1. Right now the trace traces the collision channel World_Static. If your Pawns are blocking World_Static they will block vision. You could change the tracing channel (ECC_WorldStatic) in the line in FogOfWarWorker.cpp:
    if (!Manager->GetWorld()->LineTraceTest(position, currentWorldSpacePos, ECC_WorldStatic, queryParams))
    You will probably want to make a custom collision channel for your pawns. You can read more about collision filtering here: Collision Filtering - Unreal Engine

Cheers,

  1. well, this didnt work. Half of map is like not in fog of war, and nearest area to character still black. I want all map to be ‘discovered’, but in fog of war =/

Yes, sorry about that. I was at work and couldn’t test it properly. First of all init the TextureData to 100 like this
TextureData.Init(FColor(100, 100, 100, 255), arraySize);
LastFrameTextureData.Init(FColor(100, 100, 100, 255), arraySize);

Also the UnfoggedData-array has to be intialized like this:
UnfoggedData.Init(true, arraySize);

This is pretty awesome. I have it mostly implemented in 4.9 but I am having some weirdness. I get the result in the screen shot below. When I move the actors around it reveals but the positions don’t seem entirely accurate and the positions that the units start in will never get revealed. I selected the actors to show as a reference. I have nothing in the level except for those actors, a floor, skylight, and navmesh bounds.

If I take one unit and walk around I get this:

I am registering the actors like this:



         for (FConstPawnIterator Iterator = GetWorld()->GetPawnIterator(); Iterator; ++Iterator)
	{
		ARTS_BaseUnit* TestChar = Cast<ARTS_BaseUnit>(*Iterator);
		if (TestChar != NULL) 
		{
			RegisterFowActor(TestChar);
		}
	}


Heoki,
Is your LevelInfo-actor located at [0,0,0]?

//

Yep, I also tried moving it around in the level which seemed to have no affect. It works and follows the character but it seems like the closer I get to the map edges the more offset towards the center of the map it gets.

-edit-
I played around with how positions are calculated and noticed that if I set my Samples Per Meter to 4 it seems like it’s right on the nose but any higher or lower and it gets offset like in the images for a small map. I have a map that is easily 4x as big and I can’t get the brightened area to fall on the actual actors.

-edit2-
I fixed it I believe. I was registering the actor too many times. I updated the register actor function to use addunique for now.

-edit3-
Yep, this is working great. I hooked in the sight range to key off of a sight radius attribute to determine how far a specific unit can see. Thanks for this tutorial. I am going to learn a lot from this.

-edit4-
I had another question and I don’t want to double post. Is there a way to always show certain actors in the darkness? For instance a target indicator for a location given to a group of RTS units.

-edit5-
Turns out there is a way. You can set actors to use a custom depth in the rendering settings and update the material so that it ignores them. I found the answer here: Can you post process just some actors? - Rendering - Epic Developer Community Forums

Here’s a screenshot of the updates I made to the material supplied:

I ran into couple other issues I am trying to solve hopefully I can get some advice.

  1. When an actor is removed from the registered actors list, what would be a good way to clean up the section it was in.
  2. When making the undiscovered areas less than pitch black you can see a sort of black square shape in the fog where the blurring happens if blurring is enabled.
    too-dark-min.PNG

I will edit this post if I find a solution.

-edit-
Looks like for number 1 I just needed to unregister the actor from the fow manager and it fogged back up. It doesn’t seem to work for me 100% of the time but I might be missing something.

Heoki,

You keep answering you own questions so it’s a bit hard to follow :slight_smile: As for question 1 you should only have to unregister the actor. If it doesn’t work 100% of the time maybe you’ve registered the actor several times or something? It might also be something funny in the code, I can take a look into it if it’s still an issue. As for question 2 I don’t think I’ve ever tried having a non-black fog, so I’ve never run into the issue. There may be something off with either the blur offset in the software blurring or in the hardware blurring. The HW-blurring in the PP-material is kind of hard to read and it should probably be changed to something like this. You could try turning off the HW-blur to identify where the issue is. If the error is in the software blur, I’d have to look at the code a bit since it’s almost a year since I wrote it.

Regarding scale, there are two values influencing the size of the fog area. One is samples per meter in the FogOfWarManager.h. The other one is in the parameter collection and it’s a scalar value named “Size” which is the fog size. The parameters has to add up, so for Samples per meter = 2, Size should be 512 to fit a 1024-texture. I know it’s confusing and badly designed, just never got around to change it properly. If you want to you could make a blueprint that actually changes the parameters in the Material parameter collection (named FOW parameters) values based on the parameters from the code. If you map is fairly large say (2x2km), the values should be something like Samples per meter = 0.5 and Size = 2048. That would decrease the accuracy of the fog, but I had some major hiccups when using a texture size above 1024.

Hope that clarifies things a bit,

Thanks, that helps a lot. Setting the Samples per meter to 4 solves the issue for my maps so I am not worried about that but I am happy you wrote and explanation because I really want to make a better effort to understand it.

The problem with the area not refogging 100% of the time was that I wasn’t unregistering the actor in the right spot so sometimes it would get destroyed before it called the unregister function I added.

I couldn’t figure out the blurring issue with fog that isn’t pitch black so I unchecked the blur checkbox on the levelinfo actor for now since it doesn’t look too bad.

-edit-
Sorry for all the edits. I just wanted to share what I found with anyone else who has the same issues without polluting your thread too much. :slight_smile:

Hello! Fog of war was working nice, but then i updated to win 10 and ur system cause huge fps drop… What is problem, do u have any ideas?

i’ve managed that it lags in this part of the code…

It triggers if bIsDoneBlending==true, and then it lags. If i disconnect in blueprint setting this bool to true - its not lags. Then i thought, that its an OnFowTextureUpdated lag, so i connected setting bool in bp and disconnecting everything from event ‘OnFowTextureUpdated’, but it still lags. So i made a conclusion, that this part of code making system lag, but i dont understand, why it lags on win 10!

Hi ,

The UpdateTextureRegions-method is the part of the code that flushes data to the textures on the GPU. I have no idea why that would be slower on Win10, but it could have something to do with the Win10 DX11-driver. I’ve upgraded to Win10 myself (and my current Geforce driver is 359.06), though I don’t experience any lag. On the other hand I don’t have any FPS-statistics from Win7 to compare my current numbers to… Sorry that I can’t be of any more help.

Cheers,

maybe its caused by dx12, because i have it, not 11