Help with light effects

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
jdoolin
Prole
Posts: 31
Joined: Sat Nov 18, 2017 7:40 pm

Help with light effects

I could use some help from those more experienced with graphics than myself.

I've been busy working on a strategy RPG along the lines of Shining Force on for the Genesis. I've been having more fun programming than I have in a long time. I've been programming for 20 years but I'm relatively new to game programming. Still, I've learned lots and I've come a long way. Anyway, I have an effect I would like to implement. Perhaps I can say it best with an example.

I have a town map (learning to use Tiled, and I have purchased some wonderful graphics assets). In this town, there may be fireplaces, braziers, torches, lanterns or other sources of light. During the day, I would like my map to render normally. But during night, I would like it to look dark and with those light sources making those local regions brighter.

I realize there are complex lighting engines out there but I'm not so sure I need that much. I think I just want things to look brighter wherever there is a light source. Maybe do some things like fireflies too. I'm really not sure where to start. I'm great at reading documentation and figuring out examples, however. So I don't necessarily need a thorough explanation if there are good examples to look at.

I'm not opposed to fancier lighting solutions either, if they aren't much work. But any help or guidance would be very much appreciated.

By the way, here is a screenshot of something like what I'm looking for:

randomnovice
Party member
Posts: 109
Joined: Sat May 09, 2015 9:15 pm

Re: Help with light effects

If you've been programming for 20 years I'm not sure I can be of much help...!
But I'll try anyway and feel free to disregard

If this is tile based, do you currently have a love.draw function that simply loops through the tiles based upon (some sort of map?) to draw and presents them to the screen?

DYNAMIC LIGHTING OPTION
If you do, I guess we'd be writing a function called "lighting" or whatever that returns a value for Red, Green, Blue (and if you like alpha).
This function might only be called in the "daytime" so you'll need some sort of hour reference in your game.
And I suppose we would pass into the function the coordinate reference for the tile (x, y).
And alongside that we're going to need a way to know what is a "light source" (and if you like, how much light it gives off / what colour).

So the function would test how far it is away from various light sources it is and return a figure for RGB that would present the tile at a certain brightness.

Questions that might be helpful:
- Do you want to set a minimum value for Red, Green and Blue based upon the type of map? (e.g. some maps could have a default blue eerieness or a green forest darkness?).
- Do you want to distinguish between different light sources in terms of strength and colour?
- What sort of maths function will give the best "smooth transition" of lighting (how far it reaches/how quickly diminishes)?

STATIC LIGHTING OPTION
Another way to go if the lighting isn't going to change (i.e. the player doesn't carry torches or move lights) is you could run this function when the map loads and store the values in a table. So the lighting values stay constant.

Just thoughts

zorg
Party member
Posts: 3055
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Help with light effects

Use shaders, i'm guessing you know how to.
Sort tiles based on their y position (and possibly their height value as well)
Batch draw them onto separate canvases, apply lightning onto those from back to front (draw with shader active, supplying it coords for light spots or something), combine (draw) canvases onto screen from back to front.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

grump
Party member
Posts: 678
Joined: Sat Jul 22, 2017 7:43 pm

Re: Help with light effects

Start with an empty screen that is a single, dark color. That is your ambient light, or base brightness of your world at the current time.

Next, loop over all the light sources that affect what is currently shown on the screen. Draw those lights using an additive blend mode. You now have a lightmap that contains all the lighting information required for the current scene.

The last step is to render your actual graphics. In the case of non-overlapping tiles, you can simply render them on top of the lightmap using a multiplying/modulating blend mode. For more complex scenes, render them onto a separate canvas, then draw that canvas with the 'multiply' blend mode.

The result will look like your example image.

zorg
Party member
Posts: 3055
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Help with light effects

grump wrote:
Sat Apr 07, 2018 8:21 am
...

The result will look like your example image.
How would your pseudocode deal with the tile "edges" that aren't illuminated because the lightsource isn't top-down and 360° ?
lightedges.png (27.06 KiB) Viewed 2993 times
I'd at least add that the code should "erase" the added illuminance from the lightmap by clearing areas of specific tiles to the ambient light that shouldn't be logically illuminated.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

grump
Party member
Posts: 678
Joined: Sat Jul 22, 2017 7:43 pm

Re: Help with light effects

zorg wrote:
Sat Apr 07, 2018 9:08 am
How would your pseudocode deal with the tile "edges" that aren't illuminated because the lightsource isn't top-down and 360° ?
I'm not sure I understand what you mean. The light sources can be any shape you want. The windows in the example picture would cast spot lights, not spherical lights. And you can of course incorporate a shadows/ambient occlusion pass.

Edit: There's also additional static lighting baked into the sprites in the example pic, obviously. You can't use my simple approach to dynamically illuminate the bushes and the trees the way they are in the example, you would need to use normal maps for that.

jdoolin
Prole
Posts: 31
Joined: Sat Nov 18, 2017 7:40 pm

Re: Help with light effects

First of all, it was awesome to wake up to five replies to my thread. I love how helpful this community is. Maybe I can pay it forward some day. So thanks for all of the suggestions and advice.
grump wrote:
Sat Apr 07, 2018 8:21 am
Start with an empty screen that is a single, dark color. That is your ambient light, or base brightness of your world at the current time.

Next, loop over all the light sources that affect what is currently shown on the screen. Draw those lights using an additive blend mode. You now have a lightmap that contains all the lighting information required for the current scene.

The last step is to render your actual graphics. In the case of non-overlapping tiles, you can simply render them on top of the lightmap using a multiplying/modulating blend mode. For more complex scenes, render them onto a separate canvas, then draw that canvas with the 'multiply' blend mode.

The result will look like your example image.
Ok, I think I understand everything you're suggesting here, with one exception. What do you mean by "Draw those lights"? That's one of the parts I'm not sure how to do. The rest makes sense, but I'll write some code to see if I have a grasp. If the rest is correct, how do I implement the draw function for light sources? Do I need some sort of image that uses a radial gradient and transparency that I could draw to an x/y coordinate and scale it properly?

I'm using STI and Tiled for map rendering, so I think it would be easy enough to define light sources by adding properties to tiles.

Code: Select all

function Map:draw()
love.graphics.setColor(50, 50, 50, 255) -- single dark color
love.graphics.rectangle("fill", 0, 0, screenWidth, screenHeight)
for _, lightSource in ipairs(self:getLightSources()) do
lightSource:draw()
end
love.graphics.blendMode("multiply")
self:drawCanvas() -- assumes the map is drawn to a Canvas
love.graphics.blendMode("alpha")
end

zorg wrote:
Sat Apr 07, 2018 8:12 am
Use shaders, i'm guessing you know how to.
Sort tiles based on their y position (and possibly their height value as well)
Batch draw them onto separate canvases, apply lightning onto those from back to front (draw with shader active, supplying it coords for light spots or something), combine (draw) canvases onto screen from back to front.
I haven't used Shaders yet, no. That's the sort of thing I'm new to. Anything regarding graphical effects like Shaders and Particles... that's all new to me.

grump
Party member
Posts: 678
Joined: Sat Jul 22, 2017 7:43 pm

Re: Help with light effects

jdoolin wrote:
Sat Apr 07, 2018 3:10 pm
What do you mean by "Draw those lights"? That's one of the parts I'm not sure how to do. The rest makes sense, but I'll write some code to see if I have a grasp. If the rest is correct, how do I implement the draw function for light sources? Do I need some sort of image that uses a radial gradient and transparency that I could draw to an x/y coordinate and scale it properly?
You can basically use whatever works for you as the graphics for each light source. Radial gradients work great as point lights. Trapezoids with linear gradients make good spot lights. Transparency is not required for the lights, only color is relevant. You could do without using textures at all by using shaders for different kinds of lights. Normal maps can be used to add realistic illumination and bump mapping, assuming you don't have pre-baked light in your sprites. It all depends on what you want to achieve.

Lighting like in your example can be done with carefully placed quads and trapezoids (for the windows), although moving them around dynamically can become tricky - see zorg's objection. I'd suggest starting with simple point lights and work from there.

There's a number of ready-to-use libraries available that implement light/shadows in LÖVE that look quite good and can save you a lot of time and headaches. They probably also use more sophisticated techniques to render light sources. I can't recommend one since I've never used them, but searching the forums should yield some threads.

drunken_munki
Party member
Posts: 134
Joined: Tue Mar 29, 2011 11:05 pm

Re: Help with light effects

I mocked up a test lighting setup that I use in my own game, this is a really really really noddy example that creates lights as a set of pre-baked gradient ellipises into a canvas. You could try to edit this and use any 'light' image you like or indeed use a custom built gradient function to draw any shapes you like instead of these images.

The main purpose of this example is to demonstate basic shaders with a light canvas, a global daylight value from 0 to 1 and local 'lights' can have diferent colours.

Image1.png (522.34 KiB) Viewed 2844 times
Attachments
light_test.love

jdoolin
Prole
Posts: 31
Joined: Sat Nov 18, 2017 7:40 pm

Re: Help with light effects

@drunken_munki

Thanks a lot for that example. That's perfect. I'm not sure I'll get to a point where I'll want more than that, but if I do this will be a terrific starting point.

You also gave me the nudge to upgrade to 0.11 and refactor my code. So thanks for that too.

Who is online

Users browsing this forum: No registered users and 60 guests