As promised, here is “Part 2” to my post about creation tools! Separating this post from the last still feels a little weird to me, as I actually programmed both parts simultaneously (not literally at the same time… you know what I mean), but I have reasoning which bears the semblance of logic. Since my previous post was mostly about where I’m going with the project (i.e. making a level-editor), I felt I should save what changes I made to the lighting engine for another post, both to maintain focus and to abstain from writing obscenely long blog entries. In the interest of thwarting the sinister forces of irony, let’s get started right away.
For our first course of action, let me show you how lighting has changed since the last update:

The screencaps are ordered from oldest on the top to newest on the bottom.
It’s just like when you see those “XBONE VS. PS4 VS. PC GRAFIX COMPARISON” videos except different.
And now, a bit of history: When I first began working on lighting in this game, I wasn’t even sure that I’d want to keep it. It was actually, more or less, an experiment to help me decide how I wanted the game to look. If you take a peek at Part 10, you can see what it looked like at that time. It was something that could pass as light, if you had an amazing imagination, but it hadn’t achieved the effect I was hoping to make. I thought I could take it further.
So then I made smooth lighting. This time, I blended multiple light values together for each vertex of each cube in order to smooth the lighting out a bit, and I set the light inside of solid blocks to zero to create some sort of artificial ambient occlusion. Then, I thought I could take it further still, so I made the ambient occlusion less intense in brighter areas and more intense in darker areas. Then, I thought I could still take it further… Now I think you get the idea.
There is a fine line between making progress on your game and losing yourself in “feature creep.” Looking back, I realize I have done way more with lighting in this game than I had ever planned out. And yet, I think it was for the best. For me, being a programmer without any sense of art, spending this much time on lighting has helped me to establish some sort of mood for this game – a mood that I plan to expand upon in the future. At the very least, it helps to inspire me and guide me in the right direction if that makes any sense. I want to make a game that, in a certain way, molds itself around the way this lighting works. If the lighting were not to work out the way I wanted it to, I’d have to shoot for a different mood altogether. This is not to say that another mood would be bad or any less valid – just different. In the end, was lighting a valuable pursuit? Am I even done with it yet? I don’t really know, but I feel like, aside from the dev console, I finally have a solid feature in the game that seems to play well with others. Anyway, let’s take a look at how this actually works.
Lighting in this game, prior to this update, was basically “Minecraft light.” The way the light reacted with blocks, how it smoothed, and how ambient occlusion worked in both games were for all intents and purposes identical. In exploring more of this game, however, I noticed some things that needed to change. The first aspect of lighting that had to be fixed was the seams between light emanating from different light sources. This is only really noticeable in instances when you have light sources with very large radii, as in the first screencap in the image above. It’s something that I can’t describe in any way other than “awkward.”
What happens is a “light-emitting” block sends out six “lights” (one for each side) which can each branch in up to six different directions if nothing gets in its way. Each time it moves from one voxel to the next, it decreases in its light value until it eventually hits zero and stops being light anymore. If it comes across a voxel marked “solid” or a voxel with a light value greater than or equal to its own, it stops. This creates the illusion of light which reacts semi-realistically with solid objects. As we’ve seen before, though, it looks rather silly when it runs into other light. It just gets stopped in its tracks like there’s some invisible barrier it cannot surpass. As we all know, light is not territorial in this way in real life. The solution I found was to, instead of cutting light off as it hits another light, add its light value to the value the voxel it is testing already has. Here is my first attempt:
What has happened here? Every time I place another light source, the pattern is completely different. Oh well, maybe I’ll have to steal some of this code if I ever make a noise generator later. I changed around a few lines and then got this:
Now this is interesting. I can count two things going wrong here. The first is the fact that the light levels seem to be restarting every couple of blocks. Logically, the center of this should be insanely bright, while it fades out towards the edges. Instead we get this interesting-yet-not-what-we-want ring pattern. The reason why, I discovered, is again because of the way we’re storing data here. In order to use as little memory as possible, the light value of each voxel is stored in an “unsigned char” datatype, which can hold all integer values between and including 0 and 255. This system works great unless you’re exceeding the upper or lower limits. In this case, we’re telling the program to assign values entirely too large for our unsigned char, for example, the number 1418. The computer realizes that this number is too large to be stored there, so it simply divides 256 from the value and assigns the voxel the remainder: a light value of 138. In other terms:
// this is the value we try to assign to our light int input_val = 1418; // this is the value that is actually assigned unsigned char light_val = input_val % 256;
Interestingly enough, I don’t need to fix this because the solution to the second problem fixes the first one as well. The second problem is quite frankly that we’re even adding these light values together like this at all. If I were add an upper limit to light values in order to fix the first problem, I’d have only solved one problem to cause another. Any area where light would reach this limit would look saturated and washed out. It’s like looking at a picture of trees in the winter in which the sky appears to be a perfectly homogeneous white backdrop. That’s ugly, and we don’t want our lighting to be ugly.
The solution is to never reach that maximum value. In the dark, light should act as normal, but when one light is added to more light, enough to surpass a value of 255 should never be added. I found that implementing a decreasing linear relationship between the “percent of light value to add” to a voxel and the “existing light value” of the voxel seemed to do the trick. This is what I mean:
With this in place, lighting goes from what it looks like in screencap 1 to how it looks in screencap 2. Bam.
Ok, finally we can talk about colored light! But first, the necessary explanation of “why.” If anybody ever asks me why I program something, I simply reply, “It gives me more practice.” If I’m trying to actually make a “finished” product, however, this automated response could land me in a difficult situation where, no matter how much I learn, I’m getting almost nowhere. That is why, in a similar manner to avoiding “feature creep,” I need to focus on only building features that progress the project and postpone superfluous learning for another time and another place. Anyway, that’s not important. I’m just trying to distract you from the fact that I have no solid justification for implementing colored light.
Moving on.
Straight white light is boring right? I mean, I’d be hard-pressed to find it anywhere in real life other than in Dark Souls (manifest in the strange white light constantly emanating from the character). I imagine that’s why it looks so unnatural. So what the heck, let’s see how we could possibly make not-unnatural light work in our game.
Again, in the interest of saving RAM (and hard drive storage when saving levels), I’m not willing to sacrifice the elegance of a single unsigned char for each light value. What this means is that we cannot have more than one color of light at any given time being expressed on our stage (that is, each kind of light can only be one color. Ambient light, for example, could be a different color than our dynamic voxel lighting). Even with this limitation, light can look interesting. Put your mental-image-construction cap on. Ok? Now, close your eyes.
CLOSE YOUR EYES! And perhaps find a friend to read this next paragraph to you.
Ok, now picture a white wall, vast, imposing, blank. There is no light. Now see, there is a torch against the wall and it is burning hot with fire. See how the light starts out bright and then gets dimmer and darker as it fades into the darkness? That’s the effect we’re going for. You should now feel all warm and fuzzy inside.
You may open again. My approach to achieving this effect is to apply a specific color to a specific shade of light. More intensity corresponds to a lighter color, and less intensity corresponds to a darker color. I fiddled with some numbers in the rendering code, and this is what I got:
Those two cubes with a different texture are emitting light, and the environment is reacting by being extremely orange. Also, take a look at that ambient occlusion. It’s disturbing. Not only is it adding instead of subtracting light, but it’s also more intense in brighter areas and less intense in darker areas. This must be fixed.
Luckily for me and for the fate of the game, lighting was just going through a phase at the time. I don’t want to go into too much detail here, but essentially, I had to split up a couple functions and effectively calculate two different colors of light to put them together. I have one set of functions governing the orange light and another set governing ambient occlusion. After the program finds the color of the orange light determined by the gradient I’ve specified, it subtracts the value of the ambient occlusion from each color (RGB) proportional to its existing value. What we end up with looks a little like this:
Well, I’m satisfied… at least for now. Lighting has significantly improved over the last few blog posts, and I hope to put it to rest for as long as I don’t find any problems with it. In the future, I don’t plan to spend so much time on just one feature, but, since this one will be integral to gameplay, I made a little excuse for it.Holy moly! This is the longest post I’ve ever written, coming up on the 2k mark here. Let’s pretend like I never said anything about writing a brief post. See you next time!




![[Portal 2 reference here]. Oh look 3D TEXT!](https://gamecodedecoded.files.wordpress.com/2014/02/pic-68.png?w=520&h=390)


























