Dynamic Lighting

by Forum_account
Dynamic Lighting
An easy way to add dynamic lighting to your game.
Something I've experimented with (with good results): You can use step_x and step_y to offset the center coordinates for taking distances from when computing luminosity. By offsetting the center coordinates by decimals based on the step_x and step_y, you can have lighting that moves per pixel. This can also be used to sort of tween the lighting between tiles when the parent atom is stepping.

However, you also need to stop rounding all of the luminosity computations to ints; You need the float numbers when you're dealing with this. Instead, only round when you're picking out an icon_state from the shadow icon.

You'd also need to modify atom.light() to accommodate for decimal coordinates.
I'll see how it goes playing with pixel movement. If I can delay the lighting update like you said and have it moving 8 pixels at a time it should appear much smoother. If it doesn't, then I'll have to wait until I make a game that would need stationary dynamic lights. Right now all I'd be using it for would be to add new types of maps to my current project which would be dark and require the player to be near something to see it, which I'm hoping will add onto the fun and challenge of certain maps.
You can use step_x and step_y to offset the center coordinates for taking distances from when computing luminosity. By offsetting the center coordinates by decimals based on the step_x and step_y, you can have lighting that moves per pixel

I'll have to try that, but that also means that lighting is updated much more often. Also, the lighting will still look tile-based, it'll just update more often. I expect this would look significantly better when you have more shades to work with.
D4RK3 54B3R wrote:
However, you also need to stop rounding all of the luminosity computations to ints; You need the float numbers when you're dealing with this. Instead, only round when you're picking out an icon_state from the shadow icon.

You'd also need to modify atom.light() to accommodate for decimal coordinates.

I just posted an update that made these two changes. There were a few other changes too:

• Changed the way dynamic lighting is initialized, instead of calling new() to initialize it, you call init() and pass init the icon file to use. You call the same init() proc to initialize a z level - you can pass any number of z levels as arguments or pass nothing to make it initialize all z levels.
• Changed the /light_source object to just be /light
• Previously, each light_source object had a loop that executed every tick, this loop was moved to be a single global loop in the /Lighting object for performance reasons.
• Shading objects can now have decimal lum values (ex: 3.5) and will automatically be rounded to the nearest integer.
• Added some detail to the icons used in the demo and created a separate icon file with simpler graphics. Switch between the two icon files in demo\demo.dm to see how much better the lighting effects look when the turfs have more detailed icons.
• Added the light.intensity var which can be used to control the intensity of a light.
• Changed the default light.lum() proc to take into account the radius and intensity vars, the default provides a circular area of light with a value equal to the intensity var at the center and fading to zero at the edges.
• Updated each demo to have verbs for increasing and decreasing the light's intensity.
I'm excited about the intensity variable. When using a higher amount of states for lighting, hardly any of the lit areas around you or a lamp is fully lit. In fact the lit up areas seem like they are darkened too. Maybe playing with the intensity, you could make much better use of the higher amount of states since it'll be smoother and still have the light intensity of the lower quality lighting.
Some sets of values for radius and intensity look better than others, but you can play around with the verbs in the demos to see which values work best.
I've been playing around with it. Have you figured out a smoother way for the light to move? I'd like to use a step_size of 8 but the lighting changes are very choppy at that setting..
As long as it works decently that's the next thing I'll add to it.
I just posted an update that adds this. By default the light source's position will be based on the loc, step_x, and step_y of the object it's attached to. This means that the illumination will be re-computed every time the step_x/y change. This looks better but will have a negative impact on performance - with a step size of 8 you're updating the lighting every step instead of every 4th step.

With a small number of moving light sources this won't be a problem, but if you want to disable it you just have to do this:

lighting.pixel_movement = 0


I also changed the way the light.intensity var is used - its value is now on the 0...1 scale so that an intensity of 1 will make the center of the lighted area be at maximum brightness, regardless of the number of shades of lighting there are. This way you can change to an icon with more shades and the lighting should look similar, no matter what intensity values you use.
Very nice update! With this I should be able to easily use it in my project =D. I'll only have a few stationary lights and one light attached to the player, that shouldn't cause any cpu issues with pixel movement.
It's strange... With a radius of 10 and intensity of 1, moving around seems to make the light around you look very odd, like there's other circles to your cardinal directions radius/2 tiles away that grow or shrink depending on which direction you're going. This is most noticeable when using pixel movement; when gliding, the circles don't change size, but they're still there. Is this a glitch in calculation?
I see that but I'm not sure why that happens. I'll look into it more later.
I've noticed that when using smaller step sizes, the shape of the light around you changes every step which has an odd effect when running especially since its in a discernible pattern. Its not possible to have the circle of light around you appear the same every time is it?(like it does when using a step size of 32)

I have a bad feeling its not possible since the icon generator would have to be customized to generate the lighting effects based on the step size as well.
There's one illumination value per tile, so drawing a circle of light is like using a paint program to draw a circle that's 9 pixels wide - you can make something that looks round, but you can't move it half a pixel in one direction.

To improve how the lighting looks you can use smaller tiles. If every tile was 16x16 it'd look more detailed, but the problem is you'd need to double the radius of each light to make it light up the same area. This means that more tiles have to be updated and will make performance become an issue sooner.
Not to mention, the algorithm used by Forum_account is O(n^3), which effectively means that doubling the radius results in 8x as many operations per call.
D4RK3 54B3R wrote:
Not to mention, the algorithm used by Forum_account is O(n^3)

huh? (edit: to elaborate, what's "n"?)
Page: 1 2