1
\$\begingroup\$

I've asked a question how to implement Fog Of War(FOW) with shaders. Well I've got this working. I use the vertex color to identify the alpha of a single vertex.

I guess the most of you know what the FOW of Age of Empires was like, anyway I'll shortly explain it:

You have a map. Everything is unexplored(solid black / 100% transparency) at the beginning. When your NPC's / other game units explore the world (by moving around mostly) they unshadow the map. That means. Everything in a specific radius (viewrange) around a NPC is visible (0%transparency). Anything that is out of viewrange but already explored is visible but shadowed (50% transparency).

So yeah, AoE had relatively huge maps. Requirements was something around 100mhz etc. So it should be relatively easy to implement something to solve this problem - actually.

Okay. I'm currently adding planes above my world and set the color per vertex. Why do I use many planes ? Unity has a vertex limit of 65.000 per mesh. According to the size of my tiles and the size of my map I need more than one plane. So I actually need a lot of planes. This is obviously pita for my FPS.

Well so my question is, what are simple (in sense of performance) techniques to implement a FOW shader?


Okay some simplified code what I'm doin so far:

// Setup
for (int x = 0; x < (Map.Dimension/planeSize); x++) {
    for (int z = 0; z < (Map.Dimension/planeSize); z++) {
         CreateMeshAt(x*planeSize, 3, z*planeSize)
    }
}

// Explore (is called from NPCs when walking for example)
for (int x = ((int) from.x - radius); x < from.x + radius; x ++) {
    for (int z = ((int) from.z - radius); z < from.z + radius; z ++) {
        if (from.Distance(x, 1, z) > radius) continue;
        _transparency[x/tileSize, z/tileSize] = 0.5f;
    }
}


// Update
foreach(GameObject plane in planes){
    foreach(Vector3 vertex in vertices){
       Vector3 worldPos = GetWorldPos(vertex);
       vertex.Color = new Color(0,0,0, _transparency[worldPos.x/tileSize, worldPos.z/tileSize]);
    }
}

My shader just sets the transparency of the vertex now, which comes from the vertex color channel

\$\endgroup\$
  • 1
    \$\begingroup\$ You will end up stuck one way or another(may it be fog of war or other effect) if you will to draw all vertices/tiles/objects on map. Draw only what you need. I suggest you take a look at frustum culling as it may be very easy to implement for RTS (fixed camera angle, no horizon) and will pay off in long term. \$\endgroup\$ – wondra Aug 24 '14 at 20:17
  • \$\begingroup\$ I meant, split the world into chunks and test for intersection with frustum. Also fog of war doesnt have to be the same resolution as map and doesnt have to be computed anywhere else then on viewed area. \$\endgroup\$ – wondra Aug 24 '14 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.