how can you draw similarly to the light_manager

Started by Porksteak, June 01, 2018, 05:43:21 AM

Previous topic - Next topic
How can you make a drawable while using the light manager? Basically what I want to do is have a dark room, and rather than lighting a torch making the room lit, it would make a circle of light surrounding the torch. How can I do this?

1) With shaders, when Solarus v1.6 is released,
or
2) With a black surface that has a (semi)transparent circle in the middle.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Light manager? Is that script someone wrote?

What you want to use is blend modes, specifically the multiply blend mode.

If you think of black as a value of 0 and white as a value of 1, if you multiply any color by black it becomes black and if you multiply by white it is unchanged. Shades of grey will thus darken the image where the closer to black it is the darker it will get.

So then start with a black surface (or perhaps dark grey if you still want the darkened part of the room to be slightly visible). Next you'll want to draw white circles wherever a torch is visible. You have two options here:

  • You could create a png image of that circle where white pixels are the brightest part, then on the edges have a gradient where the white pixels become more transparent, with fully transparent being the darkest spot. Now all you have to do is draw this circular image in normal blend mode on top of your black surface wherever a torch is present. If two torches are near each other then the transparent pixels from each circle will overlap making it brighter in that spot than if there were only one torch.
  • The second option is to create an image of the circle where white pixels are the brightest part, then on the edges have a gradient where the pixels become grey as you want it to become darker, and eventually black at the darkest point. This image would not use any transparency. Similarly to before you will draw the circle on the black surface wherever you have a torch, but this time use the add blend mode, so where grey pixels overlap they will become more white (brighter).

Then all you have to do is draw that black surface with white circles overlaid on top of the game's surface, and be sure to use the multiply blend mode. Regardless of which option you used above, the result will be the black surface will have black pixels at the darkest spots, white pixels at the brightest spots and shades of grey in between. The best option would be creating a menu to draw the black surface on top of the game surface.

The tricky part is updating the image as the player moves. Once again you have two options:

  • The easier method is to size your black surface to be the size of the map. Then you only have to draw the white circles once when the map is loaded and then you can simply draw the a sub-region of the black surface that is visible on the player's screen over the game surface every frame. If your light sources are dynamic (either they move locations or turn on/off) then you will have to redraw the white circles on the black surface whenever one of these changes occur. The method is better if the lighting is not dynamic or at least doesn't change very often.
  • If you have lots of dynamic light sources (or for example you want to draw a light source at the player's position), then it is probably better to size the black surface to match the size of the game screen and then you'll have to redraw each light source every frame, but you only have to draw the light sources that actually appear on screen.

Yeah, I forgot option "3) Using blend modes."

It is not announced yet, but std::gregwar (who is developping shaders) made some experimental shaders allowing several dynamic light sources with shadows on the hero (and other entities). It works also with moving light sources, and looked awesomly awesome. Those shaders will be usable with Solarus v1.6 when he shares the code.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."