Tuesday 19 March 2013

Lighting in Games

Today I'm going to go over some aspects of my game's graphics! Last blog was all about other games that are so fancy with their graphics so today I'll bring it down to a student level. I'll go over some of the concepts I've learned in class as well as the implementation of lighting in my studio's game so far.

Now lighting is a simple and complex entity of games, it all depends on how you plan on doing lights in your game. The development of lights in a game can be as simple as not even programming any of it and simply faking it all with textures having lighting baked onto them. This is quick and easy but not very effective. The reason for that is because all of the lighting must be static as well as your objects in the scene. Baking textures with fake lights is very computationally efficient, however it shouldn't comprise your entire lighting. A step up from light baking, is programming lighting on the CPU. It is a bad way to do lighting because the game is limited to very few lights before the computer starts to cry and frame rate tanks. Now to take lighting to the next level, one would move the computation of lighting to the GPU and calculate it within their shaders.

To write lighting in shaders can be approached in many different ways. In our tutorials we learned how to compute lighting on a per vertex basis. What that means is that in our vertex shader, we calculate the color of the vertices based on a few different parameters such as ambiance, diffuse, and shininess. Now this is an ok method of doing lighting in game but there are better ways. The best example of better is moving these calculations of lighting over to the fragment shader and doing lighting on a per pixel basis rather than per vertex. This will give far better quality lighting as each pixel is being computed to have the perfect color rather than linearly interpolating the color in between the vertices. Here below is a perfect example of the difference between the two:
On the left is lighting calculated on a per vertex basis and on the right we have lighting done on a per fragment basis. This method is useful because it is dynamic and fast. However, with this method it is fast with a limit of lights. Trying to do more than a dozen lights will again cause the game to lag hard trying to keep up with all the computation. There is a way to have all the lights one desires, do not stress. This can be done with a method of deferred rendering, a topic which deserves it's own post.

So much more can be said about lighting, but I will end the theory on a mathematical note. I will briefly discuss how light is calculated in real life and how it is done in games. So for real life, its a very accurate approximation that incorporates all aspects of lighting such as the relativity of other objects in the scene and how they absorb/reflect light and so on. In short, this is the equation for real life lighting:
Now I'm going to be honest, I'm not too sure whats going on in this equation but that's because I make games so I approximate. Now we want to focus on the ambient, diffuse, and specular of lights. 

Ambient refers to the intensity of light in a scene so it can be mathematically described as: Intensity = K * IlluminationAmbient. Having K being a value between 0 and 1.

Now for diffuse lighting we look at Lambert's Laws and specifically the law where if the rays meet the surface at an angle, then the illuminance is proportional to the cosine of the angle with the normal. We can take this an form an equation: I = KdIpcosx. Kd is diffuse lighting constant (0..1). Ip is the intensity of the point light source. x is angle between light source and Normal. Now we know that the dot product is proportional to cosine theta. We must also incorporate the distance of the light to the surface point we are lighting. This distance would be squared and divided by the above equation but we could end up with a division by zero error so we can add tuning parameters which will give us a final equation of:
Specular lighting is calculated similar to diffuse lighting but the angle we are interested in is the angle from viewer and the reflected ray.So this equation has instead of the dot product of the normal and light source, the dot product of the reflected ray and the viewer squared similar to this:
Now to sum things up, we literally sum up the three equations and we have lighting in games. This theory was longer than I thought it would be, so in my next blog you will see more lighting but strictly for Studio 8's Bullet Devil.

No comments:

Post a Comment