Tuesday, February 11, 2014

Implementing Fog of War

Last night I began implementing fog of war for Zyrtuul, and made some decent progress. Tonight I spent a few hours and got it working properly.

My implementation uses render-to-texture functionality, and involves the following steps:

- Create an orthographic camera that renders the scene from a top-down perspective. This camera does not render any of the usual objects. It will only render special objects called 'fog of war revealers'.

- Attach a quad to each unit in the game. This is simply a flat upward-facing rectangle positioned just above each vehicle or building. I call these 'fog of war revealers'.

- Map an image which will control the way fog of war is revealed for units. I initially used a simple black image with a blurred white circle in the middle, but then experimented and am currently using the image below (made it in Photoshop). This simply makes the fog of war boundaries more interesting. Basically, each unit will be surrounded by an area of 'transparency' with the following shape (completely arbitrarily chosen at the moment and definitely subject to change).

- Create a render texture. This is a surface that the fog of war camera will render to. That is, instead of rendering to the screen, it renders to a separate image in memory. Set the fog of war camera to render to this texture.

- The first time the camera renders it clears the image to black. It then disables its clearing behaviour so that for subsequent frames the image is not cleared. This allows the fog of war state to be permanent. If we wanted the fog of war to re-appear at locations where there are no longer any units we would skip this step and have the camera clear the render target to black every frame.

- Set the blend mode of the fog of war revealers to be 'additive'. This means that wherever the unit moves, the image above will be added to the black background. The following is a visualization of what the render texture might look like if there were four units in the scene.

- Render a large plane at the height of the terrain. This will cover the entire scene. This plane will render in both the main view and the minimap view.

- Map the render texture to this plane's material. What we are doing here is having the render texture control the alpha state of this plane. Thus, the white areas will be transparent but the black areas will be opaque.

- Set the depth buffering behaviour of this plane's material to 'no z-test' and 'no z-write'. This will make the plane always render on top of anything (so that we don't have to concern ourselves with situations where objects are above the plane). Also modify the render order of the plane so that it renders after all objects that must be obscured.

Below are some screenshots of the game with fog of war enabled. The turrets do not currently have fog of war revealers attached to them (so they can currently be obscured by fog of war, which I'll fix later).