Let there be light!
Last week I explored lights in Phaser 3 (and also pathfinding, leaving that for the next post). There is built in support for adding forward rendered lights and I started with trying those out. Examples of them in use can be found in the labs section for Phaser 3, check em out! Lots of stuff in the labs are interesting/fun to toy with.
When using the lights you use normal maps for the textures, a great tool for this is SpriteIlluminator from CodeAndWeb. They also create TexturePacker, which I already use for packing the art into atlases. With TexturePacker you can easily pack the normal maps with the rest of the art, it also creates a default normal map, giving you the option to quickly test lights without having to craft the actual normal maps.
There is a short and effective tutorial on how to bring it all together here.
With these resources it was little effort to try it all out quickly. Unfortunately it turned out that there is a bug with the rendering on mobile phones, it will only render one light! This is a known bug and at the moment with no time frame of fixing. The performance seemed OK, but it would require planning to properly make use of the few lights you might have visible at once. I estimate perhaps five lights might be doable if you want to support mobile phones that are not too powerful. There was a deferred rendering path in the works but, due to some issues and what not around that time, it seems the work got halted.
I began exploring alternative options for creating lights as the bug with mobiles made the regular lights of no use to me. I decided to go for using a black image that I apply an alpha masks to, "carving" out the light in the dark so to speak.
You can only apply one mask to an image, if you need more you have to render to a texture and then use that texture. I was unable to find documentation on exactly how this worked, so I ended up with a somewhat crude solution, but performance is excellent. By using particles I can emit a single particle for each light I want to make, this particle is used as the mask and that way I have one mask but it consists of as many emitters as I want to use. The down side of using a particle is that I need to emit at a rate of 1 per frame and let it live 1 frame (or in my case 2 frames with a fade to avoid flicker), this because otherwise the light would lag behind when moving around. If the position is static you emit with longer life and not so often, using the emitter itself to create effects such as the light from a fire.
This can be accomplished with a moving light as well, but you would have to create several frames of texture and the emitter would randomly pick a texture to use. Doing some tests this actually worked nicely, I decided that if I should need it, this technique would be doable. You would have to limit the usage a bit, as too many lights with this technique will hurt performance, but no where near how it was using forward rendered lights.
A final limitation of using the masks is that there is no color for the light, it is only pure "white". But again, a solution here is to actually just create one more particle and not use it as a mask, and that particle can be colored and the combination creates an acceptable colored light.
The black image I apply the masks to is actually white, but I tint it to black as this gives the option to tint the image to any color you like. Want the dark to have a tone of red? No problem! Use it to make something that appears to be fog? No problem!
Very happy with the end result, in particulate with the performance. With a nice helper function, it is a mere createFakeLight and voila you have something that appears to be a light in the game.
Thanks for reading!