Page 1 of 4

[Coders needed] Colored light sources

Posted: Mon Apr 15, 2013 18:20
by MirceaKitsune
I've always wanted the ability to specify colored lights in Minetest. Someone already did that long ago, but the code is gone and likely wouldn't integrate with the latest source. This is unrelated to the discussion of hardware lighting, and is about achieving colored light sources with the existing voxel lighting.

Today I spent several hours trying to figure out how this could be done, hoping I could implement it myself. The lighting code is huger than I thought however (and IMO than necessary), and I could barely figure out half of what would need to be done. I won't be able to do this alone, at least not without some clear explanations. So here's what I figured out, for everyone else who wants this feature and wishes to help:

________________________________

First of all, we'd need a new Lua parameter which can be used to define the color of a light separately from its intensity, as well as different code functions for that. For the torch, light emission is defined in the following line of init.lua: light_source = LIGHT_MAX-1. My idea was to add something of the type light_color = { r = 0, g = 0.5, b = 1 } where each parameter multiplies light on that color channel. It would not interfere with light intensity, and if not set all values would be initialized as 1 (unchanged from how lights work now).

That's the easy part, but now comes the first problem: Light RGB needs to be calculated for each node (face or vertice). So for example, if you place a red torch then a green torch two nodes away, the node in between should be yellow. Torches already have a distance and intensity, so I assume it would need to be calculated in the same spot (only for 3 values instead of 1). Where would that be though?

Second problem is storing light colors. Light intensity is stored in param1 for nodes, which can hold a single value but uses bits (which I'm very bad at understanding). I assume that currently it uses 1 bit for intensity. In this case it would need to store 4 bits in total (Intensity, Red, Green, Blue). I did however find the functions where the work needs to be done: mapnode.cpp lines 47 and 66 (MapNode::setLight and MapNode::getLight). Problem is that from what I saw, param1 is saved and wrote in a million places, and I have no idea in how many areas it would need to be adapted.

Third concern is how to actually apply the colored lighting. This one I managed to figure out however; Light colors are already used to make moonlight blue. When shaders are disabled, that's done in mapblock_mesh line 337 (static void finalColorBlend). When shaders are enabled, it's in test_shader_1 file opengl_vertex.glsl. Note that light intensity is parsed as a fake SColor... where the Red means sun light, Green means moon light, Blue means light sources. They're just intensities though... hacky way if you ask me. The blue channel is what we care about.

________________________________

Those are the things I investigated so far. Adding the Lua functions and changing the shader and finalColorBlend are things I can do, but I don't know the rest. If anyone else wants this feature and is willing to code that part, I would be grateful. This has already been done once, and if someone could find the old code it might be very useful. Let me know what you think.

Posted: Mon Apr 15, 2013 19:01
by mauvebic
Consider the video and code are gone, i guess we'd have to start from scratch.

1st question, how / where is lighting done in the engine sources?

Posted: Mon Apr 15, 2013 19:43
by MirceaKitsune
mauvebic wrote:Consider the video and code are gone, i guess we'd have to start from scratch.

1st question, how / where is lighting done in the engine sources?
Yep... unless someone finds the old code it needs to be redone from zero. Even if they do find the old code, that's from before the Lua API and shaders even existed, so barely anything could be integrated. It would still help a lot in pointing out what we should do however.

And like I said, this is what I know about lighting: Light is currently stored in param1 for each node, and is a value that ranges between 1 and 15 if I'm correct. I don't know where the light calculations are done exactly since the lighting code is very large. Base idea is that we'd need to do the same thing the lighting code already does, only for 3 or 4 values instead of 1. Coding the feature itself shouldn't be that hard, but it needs a lot of digging and some more in-depth understandings than what I have.

Posted: Mon Apr 15, 2013 19:52
by sfan5
There was some code (by kahrl I think), but it seems like its gone.
Adding colored lightning would probably break the map format as we need a param3/bigger param1 for storing the color value.

Posted: Mon Apr 15, 2013 19:56
by MirceaKitsune
sfan5 wrote:There was some code (by kahrl I think), but it seems like its gone.
Adding colored lightning would probably break the map format as we need a param3/bigger param1 for storing the color value.
Storing would indeed be the biggest issue. A param3 would be a bad idea for this IMHO, but a bigger param1 using extra bits should be the way.

I'm not sure if "break" is the correct word. If I understand right changes were done to the map format over time, and the engine can stay compatible with previous formats. At worst it would require creating a new world for colored lighting to show, and placing torches on old worlds would just discard the color parameter. In case it can't automatically upgrade the format of old worlds that is.

Posted: Mon Apr 15, 2013 20:27
by MirceaKitsune
Sorry for the double post, but I wanted to add something I was discussing on IRC: The best approach to storing light value for color lights would be switching param1 to allow 16 * 3 values instead of just 16. Currently it has 4 bits, which store a light intensity between 0 and 16. We don't need to store intensity separately, nor do we need too much accuracy for light colors. So give it 12 bits and store 16 for Red, 16 for Green, 16 for Blue.

I had an experience with bits long ago, but totally forgot the formula. But it's a common programming technique from what I know, so someone better at that can probably figure it out.

Posted: Mon Apr 15, 2013 21:35
by mauvebic
this is what i got so far hacking away at source:

Image
Image
Image

Posted: Mon Apr 15, 2013 21:40
by Traxie21
Looks nice!

Posted: Tue Apr 16, 2013 00:32
by VanessaE
The new light values should be stored as a new variable/field in the map data and in the network protocol (extensions of which are forward-compatible now, if done right), not as part of some existing field. If this means extending the map format as well, so be it - it's not like there's this huge number of map files being shared (though there are a fair number), and everyone will eventually end up running colored-light-compatible code anyway.

Besides, we're only talking about 3 signed bytes per node (there's no real reason to use more). It's not like it's going to bloat out the size of the map.

Posted: Tue Apr 16, 2013 01:56
by mauvebic
Im gonna keep hacking away at source but obviously anything I come up with is gonna be crap and un-pullable, though im hoping we can find a solution that pleases (mostly) everyone. I definitely think such a feature would help spur new mod development, which has been (imo) a little dry lately.

Posted: Tue Apr 16, 2013 17:31
by MirceaKitsune
Hybrid Dog wrote:I inverted the light (light.cpp)
Nice screenshots! Inverting the light in a single line of code won't work of course, but it's nice to get a taste of how this would look like if fully done.

Posted: Tue Apr 16, 2013 20:35
by mauvebic
inadvertently created a lavalamp-esque effect:
Image

yellow-colored lighting, though only shows during the day:
Image

proper (though hard-coded) green-tinted light:
Image

further tweaking along the lines of the above modifications:
Image
Image

Posted: Wed Apr 17, 2013 00:10
by 12Me21
It seems like torch light is yellow and sunlight is blue in default minetest, is that actually true or is it just an optical illusion?

Posted: Wed Apr 17, 2013 00:15
by MirceaKitsune
Yes... now that's getting there :) Sadly the problem will come at param1 and storing the colors in mapgen... not sure what can be done there. Especially after discussing with hmmmm on IRC yesterday about this...

Posted: Wed Apr 17, 2013 00:41
by rarkenin
12Me21 wrote:It seems like torch light is yellow and sunlight is blue in default minetest, is that actually true or is it just an optical illusion?
The code actually does this somewhat due to LIGHT_SUN being special in regards to other light values.

Posted: Wed Apr 17, 2013 01:15
by mauvebic
Image
MirceaKitsune wrote: not sure what can be done there. Especially after discussing with hmmmm on IRC yesterday about this...
That's fine. Though, im running out of interesting things to build with the features at hand.

Posted: Thu Apr 18, 2013 19:56
by Inocudom
This is very exciting news. Just think of the level of beauty that will be added to the game. Keep up the testing and the efforts. Do not let this idea sink into the abyss and be forgotten.

Posted: Fri Apr 19, 2013 00:02
by mauvebic
Inocudom wrote:This is very exciting news. Just think of the level of beauty that will be added to the game. Keep up the testing and the efforts. Do not let this idea sink into the abyss and be forgotten.
There's not much more i can do - every time we try to discuss how to implement it, hmmm comes along with his sunny disposition and pretty much kills the discussion. I don't need to put up with that nor do i want to impede on anyone's territory, so i've simply filled out a ticket on github requesting the feature and i'm leaving it at that.

Posted: Fri Apr 19, 2013 12:01
by Traxie21
/ignore hmmm

Posted: Sat Apr 20, 2013 00:12
by mauvebic
Traxie21 wrote:/ignore hmmm
Well he's got his finger on the button and there's nothing i can do to force it :p And i dont wanna waste time putting together a pull just to get the prestidigitator treatment.

Posted: Sat Apr 20, 2013 00:48
by Traxie21
Why is he in "command" then? Isn't this "community-based?"

Posted: Sat Apr 20, 2013 01:01
by mauvebic
I don't pretend to know exactly how the core dev team is organized, all i know is he said it would never get pulled.

Posted: Sat Apr 20, 2013 01:36
by Traxie21
:I

Posted: Sat Apr 20, 2013 01:36
by Psychotic
mauvebic, just do what i do to people who make me depressed, and silently,but dont say this out loud in chat, to kindly go f**k themselves if they make you sad, that is some very beautiful work you did, and dont let captain asshat (hmmmm) tell you any different.

And if he bans me, so what? This is a COMMUNITY BASED GAME. Not a game for some idiot with a god complex to stomp down any hopes of adding creativity, unlike a certain games community *cough*minecraft*cough*

Posted: Sat Apr 20, 2013 01:40
by mauvebic
Psychotic wrote:mauvebic, just do what i do to people who make me depressed, and silently,but dont say this out loud in chat, to kindly go f**k themselves if they make you sad, that is some very beautiful work you did, and dont let captain asshat (hmmmm) tell you any different.

And if he bans me, so what? This is a COMMUNITY BASED GAME. Not a game for some idiot with a god complex to stomp down any hopes of adding creativity, unlike a certain games community *cough*minecraft*cough*
Sad? no, but if the goal was to discourage participation, then yeah, that worked.

Look, the issue ticket is up, if you really want it, go +1, if enough people ask for it, it will eventually get done.