for the last week or so I have been completely stuck on trying to implement efficient lighting. I've been researching and experimenting and I've looked everywhere that I have been capable of finding, and I just cannot figure it out. So, now I'm posting here, with the hope that someone can maybe help me. I'm trying to make a 2D tile-based game, similar to Terraria, and I'm trying to avoid Terraria's style of tile-based lighting and go for something smoother, like Starbound (here), except with more visual shadows. I have successfully implemented something to what I would like to see, but, sadly, it's incredibly inefficient. This is what I've tried so far:
Tiled based lighting that is put in a lightmap as a single grayscale pixel and is then scaled up and (with a shader?) smoothed out so that it looks non-tiled. This approach is similar to what I've seen (here), but is done in xna and I'm not sure if there is a BlendState equivalent thing. I also had never done anything with shaders and my attempt at smoothing out the tiles ended after I could only smooth them horizontally or vertically (not in a circle as it should be).
Raycasting and drawing each pixel with a certain alpha value for the distance it is away from the light source. This approach is the one that worked, but was inefficient. The first problem I encountered with this is that raycasting with around 360 rays per point light missed a bunch of pixels. I solved this by then using a shader to make a black pixel within the radius of a light the proper color if it was next to at least two non-black pixels, so that it wasn't a shadow. This worked, but sadly, it was far too inefficient, dropping about 300 FPS per light. But did bring me close to what I want, and I would post a picture, but sadly I'm limited to two links :(
and now I'm here, quite unsure of what to do next, are either of these two approaches that I've done before usable? Is there an even better route to take?
Thank you for taking the time to read my problem and hopefully help me out :)
P.S. I've heard of Box2D, and I really don't want to use it, mainly because this is a learning experience for me and I don't learn too much by using someone else's code.
Edit: I'm completely new to libGDX and OpenGL in general, and I know that there's a way to create a mesh using vertices and I was wondering if that might be the key, if I create a mesh from the raycasts' end points and somehow, using a shader, create an alpha gradient on the mesh? I really don't know how to create a mesh nor do I know how to create a gradient on a weirdly shaped object.
Edit3: It works! For the most part, thank you for the help Felsir, but, of course, there are still problems, I've gotten the actual lighting to work, and it's actually MORE than efficient since I don't have to draw the tiles that are not lit up by light, but the problem is, well, darkening the rest of the screen, especially since there will be multiple lights. My first thought would be to not draw the tiles within the radius of the light, but since it creates triangles and not perfect squares like it's supposed to, this happens:
As you can see, it doesn't blacken out the tiles near the edges, and creates some other problems. My other idea was to make a shader that goes through the whole screen and uses a sampler so that if the alpha value is 0, set it black, but, obviously, this doesn't work since the screen doesn't have alpha values other than 1. My last idea would be to make a mesh that's inverted from the light, but that becomes absurdly complicated with multiple lights and probably inefficient, is there any way I can black out the non-lit screen?
Edit4: So, it's still not working, I've gotten the light to work, now I need the absence of light to work, and it's not. My new idea is if I can render all the tiles, then render a black mesh over the screen with an alpha value of one, I'm wondering if it's possible, using blendFuncs and blendEquations, to subtract the alpha of the black mesh from the mesh of the light. So the darkness is rendered, then the light afterwards, and I don't know if there's a way just to remove some of the alpha from some of the pixels that are overlapping using blend funcs. I really really need to get this or something to work, I want to complete my lighting. I decided to go through every single combination of blends functions, srcs, and dsts, since I know so little about how they work, and nothing worked, I'm probably doing something wrong, please help.