Monday, 21 September 2009

Dynamic 2D Soft Shadows

I decided to implement the technique discussed in the gamedev article written by Orangy Tang (See the article here).

My implementation is in Python and requires that you have a graphics card that supports shaders and framebuffer objects, as well as having the PyOpenGL library installed.

Since I'm not trying to write tutorials, I'll just explain a bit what i did differently and what obstacles I encountered.

The article by Mr. Tang uses textures for the penumbrae. Even though this works, I found that the edges from light to dark were too glaring for my liking. This was solved using a shader with a sigmoid function to smooth out the edges. Whilst this method might not be creating very realistic penumbrae, it looks a lot better than the texture!

The light itself is also rendered using a quad and a shader, creating a much smoother appearance than the triangle fan used in the article. This should also, in theory, make it faster since less vertices need to be pushed to the gpu.

Another issue was "popping" of the penumbrae, and I could not make the method in the article work properly. After a bit of discussion with a co-worker, the solution was obvious: Create shadowfins in either direction of the original boundary point where necessary. This in turn creates a very smooth transition between boundary points, taking the light radius into account.

Ok, enough of this chitchat. Here she is in all her glory:

You can add lights with the left mouse button, remove them with the right. The intensity of all the lights can also be changed with the + and - keys.

The implementation is currently rather slow (but hey, I can't give you _everything_ can I?).