Anyone got any good information on this? I've been looking for how to implement it in 3D with a terrain system such as JME's, but have been drawing blanks.
Before I started with JMonkeyEngine I was trying JPCT. The author of that engine wrote a game called Paradroidz which has a sort of fog of war.
Jim
Bumping this topic as I am now in the same boat as thzero.
I've been trying to think of ways to implement Fog of War while using TerrainPage/TerrainBlock for the map. My initial idea was using a StencilState for a collection of "Tiles" represented by a TerrainBlock, but I am unsure if I'm moving down the right path.
What I currently have:
- A battle map that contains a TerrainBlock
- A battle map that maintains a collection of Tiles
- A Tile is simply an object that contains metadata on a logical space on the battle map
- The TerrainBlock is textured such that it literally looks like it is tiled, like a checkerboard
FoW would be easier to implement if each of my Tiles were Quads and individually textured, but I would much rather use TerrainBlock for my battle maps.
Does anyone have an idea on how this can be implemented?
Thanks for the quick responses.
Will it always have a fixed camera position - eg top down like a strategy command and conquer style
Nope. The camera can move around. I have my own input handler, but I might start using lex's StrategicHandler.
If you're referring to the Warcraft III- or Starcraft-style fog of war, which obscures everything you haven't actually been to, I'm not quite sure what you should do.
Yep, this is exactly the type of Fog of War I'm referring to. I want unexplored territory to be near black, explored but currently out-of-view territory to be dim, and in-view territory to be at full brightness. I also want the transition of an in-view region with a previously visited region to have a gradual transition.
Another idea I had was to create an image, colored black, the same size as my battlemap. Thus, if my battlemap was 32x32 tiles, I could make an image that is 32x32 pixels. One pixel of this image would relate directly to 1 tile of the battlemap. I could create a Quad the same size of the battlemap, layer it on top of map, and texture it with my "fog of war image" (without wrapping). The player's avatar has a viewing array which defines how the alpha value of the FoW image should be modified. This way, as the avatar moves around the map and changes facing, the alpha values of the FoW image will change. Once a pixel in this image has had its alpha value changed from 1, it wouldn't ever go back, to maintain the dimness. I can't think of any reason why this wouldn't work, so I think I'm gonna give this a try.
I'm certainly open to any more suggestions.
The problem I would have thought, with using a quad to obscure the scene, is where would you position it if you have a free moving camera? Have it low down to the map, and you restrict how high anything can go (aircraft, hills etc.). Have it high up, and you restrict the camera from being able to move close to the scene.
I can't see a decent compromise which would allow high buildings and hills, while allowing the camera to get close to the action.
I haven't thought this idea through but perhaps you could:
- Maintain a grid representing the fog of war. Three possible values - visible, discovered, undiscovered.
- Whole grid corresponds to whole map, but the resolution does not need to match. You can set it to however detailed you want the fog of war.
- Each frame, replace all visible values with discovered, then refresh the visible area.
- For each corner of the visibe area, calculate it's map coordinate.
- Create a pass, or even a fragment shader, which interpolates these values to gete the map coordinate for each pixel, finds the corresponding fog grid value, and adjusts brightness accordingly.
Might not be feasible, have not ever worked on such a thing!
Well actually that's gonna have problems with high terrain also… probably can work around it though.
How about you don't even load the tiles into rendering while they're undiscovered. Load the ones immediately around the player, and then use a fogstate.
That means wherever the player hasn't been, the tile won't be loaded, and it will be black. Wherever the player has been, the tile will have been loaded, and the fog state will obscure stuff far away from the player.
Sound good?
The problem I would have thought, with using a quad to obscure the scene, is where would you position it if you have a free moving camera? Have it low down to the map, and you restrict how high anything can go (aircraft, hills etc.). Have it high up, and you restrict the camera from being able to move close to the scene.
Good point about the terrain. In my current prototype, my battlemap is perfectly flat, but the goal is to use whatever I come up with on my other project where the battlemap will certainly have hills and valleys.
How about you don't even load the tiles into rendering while they're undiscovered. Load the ones immediately around the player, and then use a fogstate.
That means wherever the player hasn't been, the tile won't be loaded, and it will be black. Wherever the player has been, the tile will have been loaded, and the fog state will obscure stuff far away from the player.
Sound good?
I'm not sure how I'd accomplish this. A Tile isn't a TriMesh but is abstract in the sense that it only contains metadata about a space on the battlemap. The battlemap is really a TerrainBlock that is textured with a wrapping texture to appear as though it has been tiled. Is there a way I can force certain areas of a TerrainBlock to not render?
Also, traditionally in RTS games, fog of war is implemented such that you can still see regions that you've already explored but they appear faded. In these areas, you can't see enemy units. You can see only static structures. So like Alric mentioned, I need some way to represent 3 states graphically: visible, discovered, undiscovered.
Then again, perhaps the traditional implementation of Fog of War only really makes sense for 2d games. Being in 3d, maybe I should equip the front of the avatar with a spotlight so the player can really only ever see whatever the spotlight is illuminating.
I've read a ton of posts (e.g., on gamedev.net, javagaming.org) and haven't come up with anything substantial to use. Most examples assume a 2d game.
Another idea is to subclass TerrainBlock and build in the support for fog of war. This way, I can directly affect the rendering of the terrain and apply the appropriate mask to the pixels.
Still thinking hard....
Oh, I thought your terrain engine worked like mine. How do you load your terrain? Heightmap? Model? Random?
Anyway, just an addition to the idea of extending the TerrainBlock class is perhaps extending the FogState class? Perhaps have a FogOfWarState class which is a combination of a regular FogState and a special FogState with a density of 1 and a color of black, and make it cover the entire map, then have the player get rid of the FogState as they move around (somehow…)
I haven't studied the FogState class in-depth enough to give you any actual code ideas, just throwing some ideas out there that you might be able to make happen.
Right it's a lot more to think about with a true 3D environment…
Can't really use fog as in a RTS you spend most of the time looking straight at the terrain - and chances are some far off terrain is visible while some closer terrain is not. But then you can't really use an alpha mapped quad because you spend some of the time close up to the scenery. I'm thinking of something like Act of War.
Should be easy enough for units, as you can easily calculate a grid position for them and check if they should be visible or not… and it's probably not important for them to fade out.
Terrain seems trickier though (probably just missing something obvious) - even with tiles it would be a low resolution effect compared to what people expect in a RTS.
I suppose you could write some sort of "z-buffer" style mask which stores the grid position of the parent object of each pixel, it just seems overcomplicated.
Will it always have a fixed camera position - eg top down like a strategy command and conquer style
If it is fixed, you could just float some clouded tile higher than the terrain tile to obscure it
thzero said:
Anyone got any good information on this? I've been looking for how to implement it in 3D with a terrain system such as JME's, but have been drawing blanks.
Yeah this is pretty vague.. Literally fog of war is caused by gunsmoke and cannons--you can create fogstates and make them very dense if you'd like, adjusting the start and end points of the fog (start is where you begin to see it and end is where it completely obscures everything).
If you're referring to the Warcraft III- or Starcraft-style fog of war, which obscures everything you haven't actually been to, I'm not quite sure what you should do.
Even in 3d, its only a little more complex than a top down RTS
If you think of it as a matrix of blocks …
No matter where the camera is, you just need a render trick. It may be that you want to render a big grey smoke thing which goes up as high as it can, or a block that encapsulates only the highest mountains, it may be that you just dont want to render the terrain block at all ( easy to do ) .
First work out how it could look - then work out what you want it to look like
Wow, you guys are quick.
Oh, I thought your terrain engine worked like mine. How do you load your terrain? Heightmap? Model? Random?
I load it via Heightmap. Right now, for my prototype the heightmap values are all 0.
Anyway, just an addition to the idea of extending the TerrainBlock class is perhaps extending the FogState class?
Yeah, that's an idea. I'm not too familiar with the FogState class, but maybe I should play around with that.
Terrain seems trickier though (probably just missing something obvious) - even with tiles it would be a low resolution effect compared to what people expect in a RTS.
Totally agree. There has to be a way to pull this off in a really slick way as I certainly have to meet that expectation.
I suppose you could write some sort of "z-buffer" style mask which stores the grid position of the parent object of each pixel, it just seems overcomplicated.
Seems like this route might work if I were to go along with the idea of making my own special Terrain class.
I'm thinking that the only way a slick 3d FoW implementation could be done is by accessing/modifying the pixels directly. Layering a Quad over the terrain is an attempt to "fake it" and would only work if the camera couldn't change its viewing angle. So I guess that option is out.
No matter where the camera is, you just need a render trick. It may be that you want to render a big grey smoke thing which goes up as high as it can, or a block that encapsulates only the highest mountains, it may be that you just dont want to render the terrain block at all ( easy to do )
This suggestion even implies that I must be able to affect the direct rendering of the terrain. I think I'm going to look further into the TerrainBlock class and see if I can create a customized version that will work.
Pandaemonium said:
This suggestion even implies that I must be able to affect the direct rendering of the terrain. I think I'm going to look further into the TerrainBlock class and see if I can create a customized version that will work.
Check to see if you can manually set a few Terrain blocks as cull always,
theprism said:
Check to see if you can manually set a few Terrain blocks as cull always,
This is a good idea, if he was using > 1 TerrainBlock. Sounds like he's using 1 TerrainBlock to me, is that correct?
If you found a way to chop up heightmaps you could take your heightmap and put it on like 16x16 tiles and load tons of TerrainPage / TerrainBlock in, set them all to cull_always, and then in your update method you could switch every tile in a certain distance to cull_back and use a fogstate to obscure stuff far away.
That's really exactly what I suggested earlier, but this is probably a better solution because it allows you to load the entire world @ a loading screen instead of having a little lag every time the person crosses tiles....
This is a good idea, if he was using > 1 TerrainBlock. Sounds like he's using 1 TerrainBlock to me, is that correct?
Yes, I'm only using 1 TerrainBlock.
I also do use a FogState to obscure areas of the terrain that are far away.
It seems that my options at this point are:
- Use TerrainPage with lots of TerrainBlocks. Try manually setting the culling of the blocks to simulate FoW. Alternatively with this option, would I be able to have 1 FogState for each TerrainBlock? Would this kill performance?
- Create a new type of TerrainBlock that has FoW functionality built in by directly modifying how each pixel is rendered.
I'll need to research both of these options to see which one will be the most viable.
Upon further research into this issue, I found that one of the "correct" ways of implementing Fog of War into a 3d environment is to create a pixel or vertex shader. I have never worked with anything like this, so I'm going to put this on the back burner for now and move onto other aspects of my game (like AI). Besides, I don't really want to obscure anything while I test enemy movement so I can ensure my enemies are moving as they're suppose to.
If anyone has experience writing shaders in jME, I'd be interested to know what pitfalls there are, things to consider, etc.
I can't claim to have a lot of experience writing shaders, or to have written one like this - but I feel like it would be quite simple with that approach, as you still have the data in three dimensions.
Maintain the map of visibility as a texture.
Have the vertex shader work out the position of the vertex in that map with a simple function (pos/mapScale).
Values will be interpolated for you, the fragment shader can easily get it's visibility
Shade fragment accordingly.
I wanted to chime in on this a bit as I will have to attend this point myself in the future.
I assume you will have multiplay in your strategy game? If you will, then you might want to consider this - you do not want to give your clients data about the objects that are out of the player's field of view anyway… What if the client gets hacked? They could make a game where all the objects that have not been discovered or are out of the view range are still rendered, giving them an advantage.
To me it seems that the best way would be to control all this on the server side and only send the correct data to the client - load the terrain tiles (or whatever - I am not using terrain myself ) only when the player enters the area (or the neighboring area)… and only send unit data for regions that are within the players viewrange. And on the client side just handle the 'not available information' - what to render if there is no map data available.
Good info on the thread though… will probably use some of the tricks mentioned here in some places…