Naive Lighting Gradients

A while ago, I was working on a game and wanted to implement efficient 2d environmental lighting (think day and night cycles rather than shading sprites differently depending on the lighting). This method does not work very well, but this might be a useful write up because it failed.

The extremely naive approach to lighting that doesn't work

In Garry's Mod, people used to make "night vision" by placing a green overlay over the screen. This is not very effective because it doesn't actually illuminate the area. All it did was give things a green tint and would not actually help you see better in the dark.

The naive approach

We can achieve simple illumination by cutting a hole in the darkness.

https://i.imgur.com/Bqq2eC7.png

This works. If the darkness was pitch black, you would be able to see in the lit area.

Making it actually look like a light

This works but it looks pretty ugly and would be unacceptable to use in a game as it is.

My first attempt to pretty this up was to make a gradient with a constant transparency that faded to black.

https://i.imgur.com/aaBtbPQ.png

This looks a bit better, but no matter the color of the light, it would be overwhelmingly blinding. The fundamental problem is that having to use a constant transparency sucks.

Making it actually look like a light, attempt 2

Instead of a gradient that faded to black, why not make a gradient for the darkness itself? I made a gradient for transparency that would be colored to match the darkness to provide a smooth transition.

https://i.imgur.com/UrBSIsS.png

Much better. However, we can't color this as is. If the darkness gradient was colored to a different color, there would once again be a sudden transition between the end of the lit area and the darkness.

Adding color

The groundwork for adding color exists, thankfully. Whereas for the darkness, one would want it to be stronger at the edges and non-existant at the center of the lit area, we would want the opposite for the color of the light. So, we can just invert the aforementioned gradient, tack it on, and color it.

https://i.imgur.com/VGH0oEX.png

I think it looks kinda nice personally. Not amazing and there aren't any shadows cast by the fire or anything, but oh well.

Of course, it also works in pitch darkness.

https://i.imgur.com/B0XMnZt.png

Why this doesn't work

Okay great. So what exactly is wrong with this? It would not be impossible to implement shadows and stop it from going through walls through the use of stencils or something.

The problem is if you have another light source overlap. Everything just breaks because the gradients just add together. The result is particularly offensive with the darkness gradient, as you end up with extreme darkness at the intersection of lights. This was a while ago so I do not have pictures for this, so just believe me when I say it was horrendous.

What's a better way?

This post was adapted from a Discord chat log I had with a friend. I turned it into a blog post to make it easy to share with others. It did not cover a better way, so I'll leave that for next time.