Fog of War Ideas
by A F · in Torque 3D Professional · 06/23/2011 (8:40 pm) · 13 replies
I'm trying to implement an RTS prototype in T3D, I've changed the camera and only render objects that are within a teams visual range, but I would like to make a Fog of War type overlay so you can actually see your teams visual range on the screen.
Something like this looks nice: http://www.garagegames.com/community/forums/viewthread/73924
but I couldn't find the resource if it was made.
I've tried a few things already, any ideas or thoughts would be appreciated.
Something like this looks nice: http://www.garagegames.com/community/forums/viewthread/73924
but I couldn't find the resource if it was made.
I've tried a few things already, any ideas or thoughts would be appreciated.
#2
06/24/2011 (3:24 pm)
search for "orcs versus martians" ... it's TGE and had a decent 3D fog of war. The dev's name elludes me right now ...
#3
The orcs versus martians game is a good example of warcraft 3 type Fog of War and something similar may be what I end up doing.
06/26/2011 (8:14 pm)
Thanks for the responses guys.The orcs versus martians game is a good example of warcraft 3 type Fog of War and something similar may be what I end up doing.
#4
06/27/2011 (11:11 am)
Yeah we have done it as well, although I am not sure if I could publicly release any of the code. I could probably give you some general places in T3D to look at and the way in which we did it at a concept level. We have it on the terrain as well as objects in the world and can turn it off per object.
#6
I can show you the images I was able to get released for my senior project (I may remove these at some point if I need more Dropbox space):



This is just for the terrain texture.
Here is the object demo:

There is a huge set of settings such texture resolution, enabled, invert, center position, area size (bigger numbers with a lower resolution means less fog detail), fog min/max (0-100 completely black vs completely transparent), default fov (used to calculate how much each object could see and how big of a drawn circle), radius scale, radius fade size (to blend between visible and not visible circles drawn), fade cycle (every this amount of time it fades back to black), initial fade cycle (after this period of time it fades a big amount), fade amount, initial fade amount, apply convolution blur to circles, show area (if this is on then you can see the square texture, if off then it makes everything else outside the texture just black.
I will ask about a video, cause seeing it real time is much more impressive, but that is the way it goes when your being paid to do software for a company working on research they don't want out.
06/27/2011 (3:12 pm)
@Steve Not sure if I can do that cause all the stuff we work on is for Boeing so there is a lot of tape to go through when releasing stuff like that. I really want to do a couple blogs to show our stuff off at some point.I can show you the images I was able to get released for my senior project (I may remove these at some point if I need more Dropbox space):



This is just for the terrain texture.
Here is the object demo:

There is a huge set of settings such texture resolution, enabled, invert, center position, area size (bigger numbers with a lower resolution means less fog detail), fog min/max (0-100 completely black vs completely transparent), default fov (used to calculate how much each object could see and how big of a drawn circle), radius scale, radius fade size (to blend between visible and not visible circles drawn), fade cycle (every this amount of time it fades back to black), initial fade cycle (after this period of time it fades a big amount), fade amount, initial fade amount, apply convolution blur to circles, show area (if this is on then you can see the square texture, if off then it makes everything else outside the texture just black.
I will ask about a video, cause seeing it real time is much more impressive, but that is the way it goes when your being paid to do software for a company working on research they don't want out.
#7
06/27/2011 (3:25 pm)
If I get a chance to post video I will, it will probably also be on our site: www.esalstudios.org/ under Gallery or Projects. Most of those videos are pretty old from when we where using TGE (also had fog of war back then as well, had to re-write it for T3D).
#8
Any general files to look at would be greatly appreciated.
07/26/2011 (10:42 pm)
Thanks for the response Nathan, the half "shadowing' on the rock and tree look really impressive. Any general files to look at would be greatly appreciated.
#9
If you want object support (guessing so) in materialFeatureType.h you will want to add a new material feature type. Then in
void ProcessedShaderMaterial::_determineFeatures(... you will want to add the feature we put it below the MFT_Using Instancing.
There will be several values you will need to pass to the shader. We used shader const. They where set in void ProcessedShaderMaterial::_setShaderConstants(
so one thing for instance was the area in processedShaderMaterial.h we added:
GFXShaderConstHandle* mFogOfWarOneOverArea;
along with some others to hold the start position of the fog of war area
and the texture itself.
08/04/2011 (3:55 pm)
Just as a fair warning we didn't write it to take advantage of multi-platform support so there may be some DirectX specific code only. Also hopefully at some point I can get some time to write up a proper resource for this, but for now I am going to do a comment search and spit out the places we put code and a bit about each spot.If you want object support (guessing so) in materialFeatureType.h you will want to add a new material feature type. Then in
void ProcessedShaderMaterial::_determineFeatures(... you will want to add the feature we put it below the MFT_Using Instancing.
There will be several values you will need to pass to the shader. We used shader const. They where set in void ProcessedShaderMaterial::_setShaderConstants(
so one thing for instance was the area in processedShaderMaterial.h we added:
GFXShaderConstHandle* mFogOfWarOneOverArea;
along with some others to hold the start position of the fog of war area
and the texture itself.
#10
You will also need to set up a new texture type so add that to TexType. It is necessary to set texture type so that the Fog of War texture is processed in ProcessedShaderMaterial::setTextureStages().
08/04/2011 (4:01 pm)
We wanted the ability to turn it on and off on individual objects so in sceneData, MeshRenderInst, TSRenderState, and tsStatic we added a fogable variable. This value is transferred down the render pipeline in several spots. In void TSStatic::prepRenderImage( you will need to pass it to the render state. In void TSMesh::innerRender( you will need to pass it to the mesh render instance from the render state. And in void RenderBinManager::setupSGData( you will need to pass it from the scene data from the mesh render instance. You will want to set up a shader const handle for fog of war this also contains a GFXShaderConstHandle* to for fogable. Then in the set consts for that handle you will pass it from the scene data to your shader const ptr. You will also need to do some small setup in init and the ctor. Along with your shader const handles class you will want to create a ShaderFeatureHLSL and all of this will be in the shaderGenHLSL folder. This is where the brunt of the work using all your values will be done. Basically though you will get your fog of war texture, get it's cordinates (area and position), check if the object is fogable and based on all of that get the color from the fog texture using the world coordinates and modify the output color of that pixel on the object.You will also need to set up a new texture type so add that to TexType. It is necessary to set texture type so that the Fog of War texture is processed in ProcessedShaderMaterial::setTextureStages().
#11
Next in void GFXTextureManager::kill() below the call to mCubemapTable.clear() you will want to add a call to your system to Deallocates Fog of War memory to make sure the fog texture handle and other Fog of War memory is deallocated before the application shuts down.
08/04/2011 (4:02 pm)
Now on to the terrain. We created a TerrainFeatHLSL in terrFeatureHLSL. In the processvert you will need to generate the incoming texture var, passed the texture coord to the pixel shader, gets the object to world transform and adds the world coordinate offset. In the processPix you will need to grab connector texcoord register, if it's a prepass then do nothing more; Otherwise get the fog of war texture, create the fog of war color get the start position offset and area. Then get the pixel color and based on the texture addressing mode (clamp or wrap depending on what you want to do where there isn't a texture) and modify the output color with the fog of war color. You will also need to declare a terrFeatureType that will be added in bool TerrainCellMaterial::_createPass. In bool TerrainCellMaterial::setupPass you will want to check if your fog of war texture consts is valid then check if Fog of War is initialized (fog texture exists), then sampler is set to the fog texture. It is also necessary for a valid texture addressing mode (clamp, wrap, etc...) to be supported for the fog texture to be rendered. The check for the initialization is if your fog of war class has everything set up. So the main texter, the fade value, the circles... If that is all ok then you will set the texture in the const to the one in your fog of war class (the one you will be editing). In void TerrainBlock::_renderBlock you will want to call the texture update function in your fog of war class.Next in void GFXTextureManager::kill() below the call to mCubemapTable.clear() you will want to add a call to your system to Deallocates Fog of War memory to make sure the fog texture handle and other Fog of War memory is deallocated before the application shuts down.
#12
Also some place you will want to call a general update ever so often that tells the entire texture to fade a bit (so it fades over time).
Lastly you will need to create the main fog of war class that handles it all. All your perimeters like the field of view, the milliseconds to fade, the texture resolution, area size, start position.... It will also hold a pointer to the actual fog of war texture to be used, a faded image that will be used as the initial fade (we had a fade that happened on the last drawn spot after a period of time), an array of fog of war circles that where drawn (for fading), and an array of initial fade circles. You will want to create a initialization method to initialize the texture and same for De-allocating the memory (arrays, texture...). All of this will be static cause you only need one. The texture is of type GFXTexHandle* . When you are actually editing the texture you will want to make sure and lock the texture area you are editing and use dMemset initialization and memcpy editing the actual circles in. This is for speed. That is why instead of actually editing a series of pixels around an area we actually store an array of values to be written (much like other textures) then copy them to the actual texture. Hopefully that make sense. Think of it like using a cookie cutter. So when you have a new field of view for a unit you will create a ptr to some circle data (like the cookie cutter) and store it in your array to be used.
I think that should be enough to get you started. Sorry for this probably being really sloppy and possibly confusing, i just don't have much time to make a good post. Also I may have missed something, but it's probably better than nothing.
08/04/2011 (4:03 pm)
Then in your code for the class that will be affecting the fog (unit that moves around exposing things) you will need to make some calls to the fog of war class. For instance when the unit moves you will want to call the draw circle function in your fog class that will simply take a point and draw a circle on the texture it holds.Also some place you will want to call a general update ever so often that tells the entire texture to fade a bit (so it fades over time).
Lastly you will need to create the main fog of war class that handles it all. All your perimeters like the field of view, the milliseconds to fade, the texture resolution, area size, start position.... It will also hold a pointer to the actual fog of war texture to be used, a faded image that will be used as the initial fade (we had a fade that happened on the last drawn spot after a period of time), an array of fog of war circles that where drawn (for fading), and an array of initial fade circles. You will want to create a initialization method to initialize the texture and same for De-allocating the memory (arrays, texture...). All of this will be static cause you only need one. The texture is of type GFXTexHandle* . When you are actually editing the texture you will want to make sure and lock the texture area you are editing and use dMemset initialization and memcpy editing the actual circles in. This is for speed. That is why instead of actually editing a series of pixels around an area we actually store an array of values to be written (much like other textures) then copy them to the actual texture. Hopefully that make sense. Think of it like using a cookie cutter. So when you have a new field of view for a unit you will create a ptr to some circle data (like the cookie cutter) and store it in your array to be used.
I think that should be enough to get you started. Sorry for this probably being really sloppy and possibly confusing, i just don't have much time to make a good post. Also I may have missed something, but it's probably better than nothing.
Torque 3D Owner Christopher Tauscher
Default Studio