Jump to content

Multiple blendModes / 'Fog of War' question


pixelburp
 Share

Recommended Posts

 

First time poster, long time lurker.

short version: is it possible to chain, or merge the blendModes of multiple display objects?
 
Say:
  1. I have Phaser.Image() with blendMode to MULTIPLY, its contents varying rgb() values to either hide or partially-hide what's beneath
  2.  Above it could be another display object, also set to MULTIPLY, but with rgb(255, 255, 255) - AND - the blendMode chains with the Phaser.Image() so this object is transparent

It doesn't feel possible, but I'm not 100% sure, or what a good alternative might be. I'm not even sure I'm explaining this correctly.

Why? Well. I'm trying to build a functioning, dynamic 'Fog of War', as seen in RTS games. Ideally I want something like in 'Starcraft', where areas on the map can be:
  • Hidden / unexplored
  • Already explored, but outside any 'unit' radius of visibility
  • Currently without the visibility of a player sprite
 
Yes, in principle this is fairly easily done with a grid of squared tiles, but I want to do something a little ... rounder and more dynamic, like proper 'blobs' of fog rolling back and forth rather than arbitrary square tiles flicking ON/OFF. It seems like something you could do with WebGL Stencil Buffers but ATM that feels beyond my capabilities.
 
So my initial idea was to have a Phaser.Image(), blendMode set to MULTIPLY, within it a BitMapData() grid of circular 'tiles', the fill() different shades of white-black depending on hidden/explored/visible.
 
It's a bit crude & performance isn't great once a lot of player sprites start moving on the map; I'm experimenting on ways to improve speed & one idea was if it was possible to chain blendModes so the bigger fog grid didn't have to make so many re-renders.
 
Hopefully that makes sense?
Link to comment
Share on other sites

I was able to accomplish this using a bitmap data object:

https://www.youtube.com/watch?v=_MQiuKvkB_I&feature=youtu.be&t=45

Step 1:

Create a BMD that is the size of the window.

Step 2: 

Fill the BMD with black (rgb 0,0,0), then clear the BMD on every game loop

Step 3: 

After the clear on each game loop, draw to the BMD using destination out. Use a brush that has black pixels in the areas you want to make transparent (i.e. the areas where the unit line of sight is) and transparent pixels in the areas you want to keep filled with black. e.g.: http://i.imgur.com/AsbhpGl.png 

Step 4:

Adjust alpha of BMD sprite to control how dark the fog of war is. 

 

Drawing to a BDM on every loop has performance implications which can be mitigated by how you implement things. If you want better performance, I suggest using a render textures or something tile-based (like you suggested). I for one plan to revisit fog of war for better performance later on. Because while this method works and looks great, it is not optimal for performance.  

Link to comment
Share on other sites

Great, that's interesting @feudalwars thanks for the tips.

So am I right in thinking your suggestion is more of a binary "you either see it or don't" mechanic, right? I wonder then how to create the same vision 'blob', only with 3 states of visibility: black => half-opacity => visible, which has been where the performance started to drag.

I thought of keeping a cache of sprites' movements, so that I could set the 'last' location as half-opacity once you left the radius, but that because expensive even to render those cached areas.

The renderTexture suggestion sounds interesting - would it be more performant than using Phaser.Image() <= Phaser.BitMapData() ?

Link to comment
Share on other sites

  • 3 years later...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...