Cudabear Posted September 17, 2015 Share Posted September 17, 2015 Hi everyone, I noticed Phaser doesn't really have lighting effects, making it difficult to add that extra layer of polish onto your game. With some research I found illuminated.js, which has the capability for making pretty solid lighting effects using 2D canvas. Problem is, this is a low-level library that draws directly to the canvas, meaning the effects you create can't be managed with Phaser's sprite system. To solve this problem I've created a library to interface betwen illuminated.js and Phaser, allowing you to create illuminated lamp objects that are wrapped as Phaser sprites, allowing you to manage them as such. Currently the project has it's first release, so be aware there might be bugs and missing optimizations. Look in the build folder for a minified version, if you so desire. The whole file is pretty small so it's not really necessary. Check it out here. Right now, this is how you use phaser-illuminated.js: //defined global game object (the phaser game instance) game; create: function(){ //initialize the library. This adds the necessary functions to all Phaser classes. game.plugins.add(Phaser.Plugin.PhaserIlluminated); //illuminated objects are added via this addition to the game.add instance. //these functions return Phaser.Sprite objects that can be used as such //config object is the same as illuminated lamps take, to customize all parameters //you can use myLamp1.getLamp() to get the illuminated lamp object myLamp1 = game.add.illuminated.lamp(200, 200 /*,{ illuminated lamp config object }*/); //add an opaque object. parameters are (x, y, width, height). //this is not a phaser.sprite object because it's not actually drawn, //except by the lamp. //It's an illuminated.polygonObject instance myObj = game.add.illuminated.rectangleObject(420, 210, 40, 30); //lighting is done on a per-lamp basis, so each lamp sprite has a lighting object under it //that you can create and add PolygonObjects to. myObjs = [myObj]; myLamp2.createLighting(myObjs); //darkmask is a sprite but takes up the entire game screen, IE WxH. //it cookie-cutters out existing lamp implementations. //it needs a reference to all lamp sprites, but these can be added later myLamps = [myLamp]; myMask = game.add.illuminated.darkMask(myLamps/*, color*/); //myMask.addLampSprite(myLamp2); <-- alternative to adding at construction time } update: function(){ //all illuminated Sprite objects have this refresh function, which redraws them //this will need to be called each time a lamp moves, or changes a parameter //if the lamp is not changed, don't call this because it's pretty expensive. myLamp.refresh(); myMask.refresh(); } render: function(){} All illuminated objects are rendered on cached bitmap data so as long as you don't refresh them too often the performance should be as good as normal sprites. Refreshing them is pretty expensive, because they're several layers of bitmapdata deep to get all the drawing done. Looking to improve this in future iterations. I also plan to add some utility functions in the future, like the ability to auto-generate Opaque objects from tilemaps Let me know if you have any feedback or would like to contribute. Thanks! ~Cudabear abshinri, Clowerweb, stupot and 5 others 8 Link to comment Share on other sites More sharing options...
MichaelD Posted September 17, 2015 Share Posted September 17, 2015 You might also want to check this excellent program: https://www.codeandweb.com/spriteilluminator Link to comment Share on other sites More sharing options...
Cudabear Posted September 18, 2015 Author Share Posted September 18, 2015 You might also want to check this excellent program: https://www.codeandweb.com/spriteilluminatorThanks for the suggestion! The use of this tool could go hand-in-hand with the capabilities of illuminated.js. Link to comment Share on other sites More sharing options...
NateTheGreatt Posted September 18, 2015 Share Posted September 18, 2015 This is awesome! Thanks man, I will experiment with this. Link to comment Share on other sites More sharing options...
jdnichollsc Posted September 19, 2015 Share Posted September 19, 2015 You might also want to check this excellent program: https://www.codeandweb.com/spriteilluminator Can you use Sprite Illuminator with Phaser? Regards Link to comment Share on other sites More sharing options...
MichaelD Posted September 19, 2015 Share Posted September 19, 2015 Trying to figure that out myself as well... I know it can be used with Pixi.js jdnichollsc 1 Link to comment Share on other sites More sharing options...
Cudabear Posted September 21, 2015 Author Share Posted September 21, 2015 Hey, everyone! I was able to add utility function for parsing tile maps and creating OpaqueObjects where solid tiles exist. You use it like this: sightBlockers = phaserIlluminated.createOpaqueObjectsFromSolidTiles(collisionLayer);Where collisionLayer is the layer you want to pars for solid tiles, and sightBlockers is the returned array of illuminated OpaqueObjects. Here's an example of the plugin in action so far: BEFORE: AFTER: The effects are added in about 10 minutes, using less than 10 lines of code! The main points are I added a DarkMask, a lamp connected to the position of the sprite, and used the utility function to create the lighting based on the tilemap's solid tiles.Any other ideas for useful functions? I'm going to add another utilty function for creating OpaqueObjects from sprite's bounding box, both individual sprites and groups. After that though, I'm not sure what could be useful.~Cudabear MichaelD, gaelbeltran and Skeptron 3 Link to comment Share on other sites More sharing options...
Skeptron Posted September 21, 2015 Share Posted September 21, 2015 @Cudabear Could you size the impact on the performances? It looks awesome, wonder if it's viable in a real game. jdnichollsc 1 Link to comment Share on other sites More sharing options...
Cudabear Posted September 21, 2015 Author Share Posted September 21, 2015 @Cudabear Could you size the impact on the performances? It looks awesome, wonder if it's viable in a real game.The only case that it really gets slow (and I mean really gets slow) is when you have a lamp with lighting that's moving every frame and needs the refresh() called every frame as well. Drawing the lighting is super expensive, and I'm looking for a way to improve it... it'll be hard to without modifying what's inside illuminated.js. In my personal experience, 5 or so lamps with lighting handled this way produced frame drops. Stationary lamps or lamps without lighting, however, are very quick. Keep in mind, these are drawn on bitmapdata that's used as textures for sprites, so they're only drawn once and then moved around like normal sprites. Realistically, once the overhead is complete, lamps without lighting are as fast as regular sprites.It should be noted the gif above with one lamp and lighting updates on it (on a tilemap with around 3,000 opaque object tiles) didn't produce any frame drops, though I didn't test on weaker devices. Skeptron 1 Link to comment Share on other sites More sharing options...
AndreasLoew Posted October 30, 2015 Share Posted October 30, 2015 Just read about this thread in the current newsletter. Sounds really interesting. Getting the whole thing to work with SpriteIlluminator should not be too complicated - as long as you render on WebGL. The dynamic lighting requires a specialized shader.We've already done it with PixiJS - at least in a small demo... If anybody is interested we are happy to help to get the project started. jdnichollsc and MichaelD 2 Link to comment Share on other sites More sharing options...
Clowerweb Posted November 5, 2015 Share Posted November 5, 2015 Just read about this thread in the current newsletter. Sounds really interesting. Getting the whole thing to work with SpriteIlluminator should not be too complicated - as long as you render on WebGL. The dynamic lighting requires a specialized shader.We've already done it with PixiJS - at least in a small demo... If anybody is interested we are happy to help to get the project started. I'd be very interested, as my game requires something similar to this: http://gamemechanicexplorer.com/#raycasting-4 and this: http://www.goodboydigital.com/pixijs/examples/20/. I see they've already implemented something similar to what I'm looking for in Phaser 3, but that's still a long way from release (see the "depth" demo here: http://labs.phaser.io/phaser3/v08/src/). Here's another very good example: http://mattdesl.github.io/kami-demos/release/normals-pixel.html. So basically, dynamic lighting, shadows and normal mapping in 2D would be excellent. I've been so frustrated with trying to get various non-Phaser-related libraries to work in Phaser that I've almost given up and switched to Unity or something else, but I'd much rather stick with Phaser since I have a good amount of development time already into the game and a large codebase built in it. The problem is that one of the core game mechanics in this game will rely on light and shadows (normal mapping is secondary, but would be great for adding polish to the look and feel of the effects). Looking at the Pixi demos, I had erroneously assumed that this would be do-able in Phaser when I began development of my game, only to discover later that Phaser uses Pixi 2, and the normal mapping feature is only available in Pixi 3. That error has put me in a bad situation. While Phaser 3 already has the ability to do everything I need, its release is still about 6 months away (according to Rich's most recent estimate, spring 2016), and I don't want to put further development of my game on hold until then, let alone the fact that the entire codebase would need to be rewritten for Phaser 3 anyway. Ugh. I really hope enough of us are interested in a feature like this to get a plugin working in Phaser 2. I'll contribute whatever I can to help get started. Link to comment Share on other sites More sharing options...
Cudabear Posted November 10, 2015 Author Share Posted November 10, 2015 To Clowerweb and AndreasLeow,The SpriteIlluminator stuff is a bit out of my comfort zone, so I'm not entirely sure how to integrate it with the PhaserIlluminated plugin. I do know PhaserIlluminated works just fine WebGL already (though it is really just using Canvas2D on the backend, drawn onto a bitmap data) so there shouldn't be any potential conflicts. Right now, the main problem with the plugin is performance. To be honest, I don't think Illuminated.js was ever really built for real-time dynamic lighting. As I've said before, the performance hits come in when you've got more than a handful of lights moving around a map full of opaque objects. In games with lighting systems, this is more than a typical use case. Maybe we'd have to rewrite some of Illuminated.js for increased performance?As for additional new features, there's been nothing that struck me other than auto-generating opaque objects based on the solid tiles of a tilemap layer. I'm open for suggestions on new features to add, though. Link to comment Share on other sites More sharing options...
Kyle709 Posted March 23, 2016 Share Posted March 23, 2016 Awesome work! Im trying to create a moving circular shadow however it doesn't seem that the diskObject can be moved? Just adjusting the center or x and y values does not seem to have any effect. Is moving opaque objects possible? Link to comment Share on other sites More sharing options...
Cudabear Posted April 13, 2016 Author Share Posted April 13, 2016 Hi Kyle, Sorry for the delayed response. Are you calling .refresh() on your lamps that have that lighting? This should update the opaque object's drawn position. Ideally, only do this when the position changes, as it's quite expensive. I'd like to make this operation cheaper, but that's something I've yet to figure out. Link to comment Share on other sites More sharing options...
Wahooiy Posted May 5, 2016 Share Posted May 5, 2016 Hello, I was wondering if it's possible to dynamically add a lamp? I was being naive and tried to just simply remake the dark mask when I added a light, but this doesn't work. You can see my attempt at: http://www.pixelshader.co.uk/illuminate/ - Run right, press E on the torch and it doesn't work as expected. Thanks for any help Link to comment Share on other sites More sharing options...
Cudabear Posted May 13, 2016 Author Share Posted May 13, 2016 Hey Wahooiy, Looking at your example, things seem to be working. The main problem I see is your player's light source is no longer respected after lighting the lamp. When you remake the DarkMask, are you sure you're readding the player's original lamp to it again? Link to comment Share on other sites More sharing options...
c4n4r Posted October 16, 2016 Share Posted October 16, 2016 Hey guys! Someone already tried to use your lib withtypescript? I'm trying to setup it but no way... Thx! Link to comment Share on other sites More sharing options...
Recommended Posts