   Fog of War in 3D RTS
  I''m looking at adding Fog of War to my 3D RTS.  I''m brainstorming ideas for implementing FOW and would like some opinions.  My engine renders the terrain in large "patches" which are created at map load time.  These patches (made up of vertex buffers) are not being locked each frame and are just rendered using simple frustum culling.  My problem is not with which squares should be darkened (in fog) but how to actually make particular squares dark.My ideas so far are:1.  Use vertex fogging to create fog on the parts of the terrain that are not visible.  This would force me to lock the vertex buffer however.2.  Render a darker square over each of the tiles that are in fog.  To do this I would create a dynamic vertex buffer and each time the fog changes remake this vertex buffer.  I would create one large vertex buffer to go over the whole of the visible terrain to cut down on the amount of times I need to lock.3.  Use vertex colours to darken the squares that are in fog.  This would again force me to lock the vertex buffer.While I am using Direct3D for my game, I''ve put this thread in this forum as the implementation is fairly generic.  If anyone has any suggestions that would be greatly appreciated.Doolwind   ---------------------------------------------------------Who of you by worrying can add a single hour to his life.Matthew 6:27 
  i vote for #3 its the way it was implemented in command and conquer generals, and worked well, also, youd need to not render any vehicles in that area... ;  Have you considered using a vertex shader? You could render all the non-fogged tiles first, then install the shader and render the other tiles. The shader could darken the tiles without you ever needing to lock the buffer. ;quote:Original post by superpig  Have you considered using a vertex shader? You could render all the non-fogged tiles first, then install the shader and render the other tiles. The shader could darken the tiles without you ever needing to lock the buffer.   I had thought of this, however how does the vertex shader know which tiles to render light and which dark.  Do you mean:1. Send only the light tiles down the pipeline and then only the dark ones (changing shaders between each call). If so, how will I only send down parts of the vertex buffer that need to be drawn in either light or dark?2. Send ALL of the tiles both times and the two different vertex shaders can decide which ones they will render.  This was my original idea, and perhaps setting some vertex shader constants I could tell whether to render each triangle light or dark.Thanks for the feedback,Doolwind   ---------------------------------------------------------Who of you by worrying can add a single hour to his life.Matthew 6:27 ;  Why not have a 16x16 (or 32x32, or whichever looks nice but is still fast enough) grid, screen-aligned, and each frame or five cast a ray through each vertex of the grid. Test for in-sight-ness at each square on the terrain, and set that vertex alpha to 0 or 1 based on it. Possibly run a low-pass filter over the values to make them look less obviously square, and then set the grid to black and blend it over the screen.That nicely takes care of the visibility problem for the terrain, and also stops one of my personal pet hates, the horrible ''enemy unit appears in middle of screen'' thing. That carrier (or battleship, or guardian) would appear slowly on the edge of the screen as nature intended, instead of just popping into view fully formed.Plus you don''t have to touch any vertex buffer apart from the mask, so it''ll be fast. ;  Make a 256x256 single channel image (boolean values)at the beginning of every frame, clear it to all 0 (false)As an entity is updated (think()) its xz coords corrospond to UV coords for your image.Using a subtex2d call, place a bitmap over that location in memory. This bitmap will be all 1's. Thus marking that area "visible"Pass the bit texture to the vertex shader, use the UV coords like any other texture.A bit of overhead from the subtex2d call, but I suppose if you lowered the resolution of your fog image (256->64) a per-pixel adjustment wouldn't be that bad.~Main   ==Colt "MainRoach" McAnlisProgrammerwww.badheat.com/sinewave   [edited by - duhroach on February 17, 2004 5:38:51 PM];quote:Original post by Doolwind  1. Send only the light tiles down the pipeline and then only the dark ones (changing shaders between each call). If so, how will I only send down parts of the vertex buffer that need to be drawn in either light or dark?2. Send ALL of the tiles both times and the two different vertex shaders can decide which ones they will render.  This was my original idea, and perhaps setting some vertex shader constants I could tell whether to render each triangle light or dark.Either of those would work, but I think that either way you''re going to need to know which tiles the fog is on (and ideally the information should not be part of the vertex structure).Initially I thought you could just keep a list of visible tiles, but then I realise that doesn''t apply terribly well to an environment in which that list will change extensively (as you move units around). Perhaps a quadtree for your tiles? If any child of a node is flagged ''unfogged,'' you flag that node ''fogged'' as well. You could then add tiles to either a ''fogged'' or ''unfogged'' list as you go along (finding a fogged non-leaf node means all tiles that are children (direct or indirect) of that node get added to the fogged list without even needing to be checked); when you''re done you just render all the tiles in the unfogged list without the shader, and then all the tiles in the fogged list with the shader. You also get the advantages of using the quadtree for culling; there''s no point even processing nodes that are offscreen.I don''t know how fast that would be, you''d have to profile it, but I''d imagine that it would be hard to get much faster without touching either vertex shader constants or the contents of the vertex buffer. Besides, if you''re going to be using a quadtree for culling, then the structure''s in place anyway... you just add tiles to one of two render lists, instead of just one.   Richard "Superpig" Fine    Smoother than a greased baby[TBRF|GP&T|Enginuity1|Enginuity2|Enginuity3|Enginuity4|Enginuity5];  Thanks for the replies,I''m going to experiment with each of the ways that seem feasible, I''ve begun doing so with setting vertex colours.  I''ve done a simple test and it works a lot better than I was expecting with a fps drop from about 55 to 52 on my machine.  My knowledge of vertex shaders is somewhat limited, however this will be a perfect opportunity to try them out.  Thanks for the feedback superpig, I''ll profile each of the technique''s I try and post the results here.  Doolwind   ---------------------------------------------------------Who of you by worrying can add a single hour to his life.Matthew 6:27 