I recently implemented some nice-looking dynamic 2d shadows, here's how I did it!

Posted by purenickery on May 21st, 2016

Alright pals let's go over how to do these shadows. In my post about the lighting, I went over the process to give each pixel a 3d coordinate so I'm not going to go over that part again here. Now, I can create a separate frame-buffer to store all the shadow data and reference that on each pixel to find out if it's in shadow.

Based on the time of day, each pixel will look down at the shadow map based on the z height of the pixel. As you can see in the image, the line on the left comes from an area on the tree in shadow, but the line on the right comes from an area on the tree in the light, but they both map to an area on the shadow-map. When I draw the shadow-map, the G channel is used for the darkness of the shadow, and the R channel is used for the height of the pixel that casts the shadow. When each pixel checks the shadow-map to see if it is in shadow, if the pixel drawn on the shadow-map was cast by a pixel with a lower z value, then it isn't actually in shadow. This will guarantee not only that high objects are not in shadow when flying over trees, it also puts half of each tree in shadow based on where the light is coming from.

In this image, you can see the two lines are coming from different sides of the tree, but the line on the right maps to the shadow cast by the other tree. Since the height of the other tree is higher than the pixel, it gets put in the shadow of the tree to the right. In order to make sure all the shadows align correctly and that higher shadows are drawn on top of lower shadows, we just have to draw the shadows from left to right instead of top to bottom. All together a scene looks like this now!

And you get this nice effect when walking under the trees





I also have a few other wonderful updates for things we've been working on. Namely, the world editor! Here's a few previews of what's possible now: