Okay, I'm creating a RTS game and want to implement an AgeOfEmpires-like Fog Of War(FOW). That means a tile(or pixel) can be:

  • 0% transparent (unexplored)
  • 50% transparent black (explored but not in viewrange)
  • 100% transparent(explored and in viewrange)

RTS means I'll have many explorers (NPCs, buildings, ...). Okay, so I have an 2d array of bytes byte[,] explored. The byte value correlates the transparency.

The question is, how do I pass this array to my shader? Well I think it is not possible to pass an entire array. So: what technique shall I use to let my shader know if a pixel/tile is visible or not?

  • 1
    \$\begingroup\$ Note that fair fog of war shows what player last saw in explored area. If player explored a forest and went away, he should still see a forest even if it is chopped long ago. \$\endgroup\$ – Kromster Aug 24 '14 at 5:45

Yes it is possible. And it is called texture.
Textures are not just pictures - it can be any kind of data*.
Another option would per-vertex data - if you dont mind smooth border between (un)explored. Or just as other post suggested - pass it as per-tile uniform.

* Ofcourse, you need to stay in reasonable array size, defined by maximum texture size. Also note that editing such texture would mean sending it all over again, which could be slow.

  • \$\begingroup\$ Thanks for your answer. I guess 256^2 (or more) tiles are a bit too much for a texture based solution :) Hmm.. Reading through the Unity Shader Documentation I'm not sure if I can pass a uniform per-tile. Well, seems like I would have to get deeper into this topic. \$\endgroup\$ – Cambrano Aug 23 '14 at 23:43
  • \$\begingroup\$ You don't necessarily have smooth borders between explored and unexplored. It depends on the way your vertices are laid out. And you don't even have to re-send the texture. You could simply update it with another shader by rendering to it. \$\endgroup\$ – Tara Aug 23 '14 at 23:46
  • \$\begingroup\$ For example GTX 760 supports textures up to 16384pix big in any dimension (16k*16k). At least 512 should be ok on any device(at least my phone managed it), if the texture would not suffice, you would have to use more of them. As for per-tile, just render tiles one by one, setting uniform(s) before each individual call. The cleanest solution would probably be per-vertex though as you can render it in one call and you are not limited by the texture size. \$\endgroup\$ – wondra Aug 23 '14 at 23:57
  • \$\begingroup\$ Unfortunately I don't have access to draw-calls in unity. \$\endgroup\$ – Cambrano Aug 23 '14 at 23:58
  • \$\begingroup\$ Sorry, I do not know much about unity - I can only help you with theory. Well... you dont need draw calls for the 2nd solution, do you? Per-vertex data could be allowed, since how you you supply coords, normals, etc.. Note that even for texture solution you need to pass/calculate UV somehow. \$\endgroup\$ – wondra Aug 24 '14 at 0:10

I'd simply provide a uniform per tile. For example a simple float that indicates the transparency.
Before you render the tile, you simply set the uniform. If that's not possible, try using vertex attributes (also using a simple float).

  • \$\begingroup\$ When I get it right this would be kinda awful since I would have to declare (map.width/tilesize) * (map.height/tilesize) uniforms in my shader? Also this would make it annoying to have custom map sizes. Well I'm a shader nobbie and most likely I've get it wrong :/ \$\endgroup\$ – Cambrano Aug 23 '14 at 23:11
  • \$\begingroup\$ No, that's not correct. You have a single uniform in your shader. For example "uniform float transparency;". I suggest you to learn how to work with shaders, before trying to implement this. Once you learned how they work, you'll answer your question easily by yourself. :D \$\endgroup\$ – Tara Aug 23 '14 at 23:16

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.