Page 1 of 1

Multiplicative instead of additive (colored) lighting

Posted: Sat Jan 02, 2016 1:23 am
by aib
Hi folks!

First time posting here. In fact, first time posting in *any forum* in ages so please be constructive with your criticism.

Please note that since this is a public forum browsed by many, I will add technical explanations in the hope that it might interest some people. The game developers and other technical- (or design-)oriented people probably already know this stuff; I am not trying to insult them.

I've noticed that the game uses additive blending when rendering lights. My suggestion is to switch to multiplicative blending, which should make colored lighting much better.

First, let me talk about my experiment:
I replaced the "player flashlight" light image. Below is an all-black image, alpha channel on a gradient so it's fading from full black (#ff000000) to full transparency (#00000000), used as a full-intensity "oriented" light source.
Image
So far, so good.

Now watch what happens when I use a full-white image, with alpha on the same gradient. (#ffffffff to #00000000):
Image
Top section looks like a glare, which is a nice twist, but note that the image has lost a lot of its contrast.

The problem is much more apparent when I switch to a full-red image, same alpha gradient. (#ffff0000 to #00000000):
Image
The iron ore and the solar panels are red+white, the earth is orange. With an actual colorized light sprite (say, that of the lamp), it feels as if the lamp is overlaying a pink circle on the screen and/or blurring its surroundings.

At this point, I started playing around on GIMP to see if I could duplicate the problem. The images below this point are "GIMPed". They are not actual screenshots, but the results of me playing around with the first screenshot above.

Below is me trying to duplicate the game engine's effect, by taking the red light sprite (#ffff0000 to #00000000) and blending it on top of the screenshot in "additive" mode:
Image
Not exactly the same, slightly less contrast.

Basically, what's happening here is the engine is adding the colors.
White (1, 1, 1) plus Red (1, 0, 0) is (2, 1, 1), clamped to (1, 1, 1), White
Black (0, 0, 0) plus Red (1, 0, 0) is (1, 0, 0), Red
Gray (.5, .5, .5) plus Red (1, 0, 0) is (1.5, .5, .5), clamped to (1, .5, .5), Pink

The problem is that real life physics don't work that way and human colour vision has evolved to assess real life.

White (1, 1, 1) objects reflect all visible light and in the presence of Red (1, 0, 0) [and absence of Green and Blue] light, appear Red (1, 0, 0).
Black (0, 0, 0) objects do not reflect light at all and should remain Black.
Dark (.2, .2, .2) objects reflect very little light and in Red (1, 0, 0) lighting should appear Dark Red (.2, 0, 0).

That's multiplicative blending for you! Here, using the same sprite as above:
Image
Since we're multiplying by Red (1, 0, 0), this is effectively the red channel of the image. Blacks stay black, whites turn red and we still have contrast, albeit this time between black and red. Note that blue and green objects would turn black/dark here, just as they would in real life.

In multiplicative blending, the identity element is White (1, 1, 1) since we'd be multiplying every color by 1. Here I blended a white~transparent sprite, the white counterpart of the original lighting sprite. Nothing changed:
Image
In fact, I may have switched this image and the original screenshot around in the imgur album. I have no easy way of telling them apart!

Note that the "white light" sprite in multiplicative blending would actually be white, marginally less confusing than the current black ones.

And finally, here is how a proper "red light" might look. I used a gradient fading from #ffff6060 to #00ff6060, so it is a "pink" tinted color (1, .375, .375), allowing objects to retain their red color and dimming green/blue by about 65%:
Image

Here is how it might look if implemented. I used light-medium.png, fiddled with the borders so I could translate to screenshot coordinates, reverted, took a screenshot and applied "pink" (#ff6060), retaining the original "black-at-center-fading-to-transparency-as-we-move-out" alpha gradient:
Image

For bonus points: Can you tell the original colors of the flasks?

Re: Multiplicative instead of additive (colored) lighting

Posted: Sat Jan 02, 2016 2:59 am
by mophydeen
blue red
green purple

Re: Multiplicative instead of additive (colored) lighting

Posted: Sat Jan 02, 2016 10:54 am
by vanatteveldt
Screenshots look great, but my intuition would be that to really up the graphics they should move to some sort of real 3d renderer with dynamic lighting, also solving the perspective problem and allowing more dynamic zooming / rotating etc. IANAGD (Game Developer), but I would think that in 2015 there should be good more-or-less-free engines out there, no? Is there any communication from the devs on their decision to use the retro-2D look? (I mean: is it a conscious decision, or just something that was easiest when they started out, and has been on the to-do list ever since?)

Also:
aib wrote: First time posting here. In fact, first time posting in *any forum* in ages so please be constructive with your criticism.
Welcome to the internet :). May all your posts be as constructive as your first!

Re: Multiplicative instead of additive (colored) lighting

Posted: Sat Jan 02, 2016 11:41 am
by sillyfly
I must admit, I came here expecting to find pretty much a rant about how they're "doing it all wrong", but after reading your nice review and seeing the examples, I must admit I'm convinced - what you suggest seems like a better option.
Still, I personally don't find it too important, so I don't really care if they never implement it. I have no idea how difficult it may be, or what performance implications this change may have, so if the devs say it's hard to implement or would make the game slower my vote would be to keep things as they are. If it's just a matter of changing one line of code though it's probably worth it :)


As for 2d/3d rendering - AFAIK Factorio started with a 2D engine (Allegro) because that's what Kovarex was familiar with at the time, and by now the project is too big to change things. But they did hint at times about a possibility of a future sequel ("Factorio 2") being re-made in 3D.

Re: Multiplicative instead of additive (colored) lighting

Posted: Sat Jan 02, 2016 12:41 pm
by aib
sillyfly wrote:I have no idea how difficult it may be, or what performance implications this change may have, so if the devs say it's hard to implement or would make the game slower my vote would be to keep things as they are.
Oh, definitely. In fact, this was just me getting bored on new year's day and playing around and wanting to document what I did. Indie game devs should be accustomed to weird/stupid/unimplementable suggestions, anyway, so no harm done, yes?

I don't know how hard it would be to implement, obviously. Last time I checked out Allegro, it was a DOS library :) If the engine sources were available, I'd take a crack at it myself.

[Technical stuff deleted] I can't seem to be able to stop myself. Maybe I should start writing articles instead of forum posts.

Re: Multiplicative instead of additive (colored) lighting

Posted: Tue Jan 05, 2016 7:44 pm
by MrFaul
Oh nice one I think that will be implemented in some sort soon because they want to give us more options to do with the circuit network :-D
Colored lights are good to begin with.

Re: Multiplicative instead of additive (colored) lighting

Posted: Fri Jan 15, 2016 3:34 pm
by TuckJohn
Would this, if implemented, cause more lag the the current "additive" model?

Re: Multiplicative instead of additive (colored) lighting

Posted: Fri Jan 15, 2016 5:59 pm
by ratchetfreak
TuckJohn wrote:Would this, if implemented, cause more lag the the current "additive" model?
That's just a multiply instead of an add on a device optimized for it

Re: Multiplicative instead of additive (colored) lighting

Posted: Fri Jan 15, 2016 10:12 pm
by bobucles
Computers are kind of made to do math so it'll be fine.

Re: Multiplicative instead of additive (colored) lighting

Posted: Mon Jan 18, 2016 10:49 am
by bobingabout
Even on a computer in this day and age... Add and subtract instructions are very cheap. Multiplication can take upto 20 times as long to perform. Divide, well... Lets just say I'd rather multiply by 0.5 than divide by 2, but that only works if you're using floating point numbers, not integers.

Re: Multiplicative instead of additive (colored) lighting

Posted: Mon Jan 18, 2016 8:56 pm
by ratchetfreak
bobingabout wrote:Even on a computer in this day and age... Add and subtract instructions are very cheap. Multiplication can take upto 20 times as long to perform. Divide, well... Lets just say I'd rather multiply by 0.5 than divide by 2, but that only works if you're using floating point numbers, not integers.
multiply is much closer to adding and subtracting these days, blame the specialized hardware for that

Re: Multiplicative instead of additive (colored) lighting

Posted: Thu Jan 21, 2016 1:12 am
by bobucles
Lighting operations only matter for the immediate visible area around the player, so the computational requirements are fairly fixed regardless of map complexity. Besides, isn't this the kind of work that gets thrown off to the GPU? It shouldn't matter that much or at all on the CPU side of things.