Multiplicative instead of additive (colored) lighting
Posted: Sat Jan 02, 2016 1:23 am
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.
So far, so good.
Now watch what happens when I use a full-white image, with alpha on the same gradient. (#ffffffff to #00000000):
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):
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:
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:
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:
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%:
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:
For bonus points: Can you tell the original colors of the flasks?
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.
So far, so good.
Now watch what happens when I use a full-white image, with alpha on the same gradient. (#ffffffff to #00000000):
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):
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:
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:
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:
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%:
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:
For bonus points: Can you tell the original colors of the flasks?