20 October 2009

Shadowy figures

There are many ways of immersing somebody into the environment of your game. The extra touches of detail that bring a bit more realism (even in cartoony games) like a character shrugging their shoulders while talking instead of just mouthing the words, or the leaves in trees rustling subtly in the wind. Simple textures can be heightened with bump maps (and more fancy effects). Objects can self shadow. Sunlight can temporarily blind the player when moving out of a dark area.

Seeing as I'm trying to make a semi-realistic sort of game, I figured shadows would, you know, be there. Shadows can evoke silent horror by withholding or smudging details. This isn't a horror game, but horror is based on heightening aspects seen in life and sometimes it doesn't even need to heighten life - certain things are pretty terrifying without having multi-limbed giant spiders involved (or even worse, single-limbed, because what freakish creature tore the spider-beasts legs off?). The main character certainly won't be in a happy state in this game. He needs to survive some fairly nasty odds at times. Needing to run away but knowing it could cause a heart attack at just the wrong moment can't be fun (except, hopefully, for the player having to work out the most survivable solution). Shadows can add to this tension. They add dynamic detail to objects and by causing objects to cast shadows said objects are better integrated into the world - not mere floss and background noise, but existent.

So. It was time to make dark what once was light. I needed to know where the hell to start for one thing. It took me a while to work out how to actually make shadows work. Instead of skimming off somebody else's work I figured it shouldn't be too hard to work out how to do myself, plus it would probably be far more fun to do it that way. Turns out it was. It also allowed me to expand upon the original code to make a far more visually appealing and functional shadow system later on. After I had done the initial shadow prototype, I went and actually did some research on the subject. Most articles involved themselves with 3D shadow projection which is quite different to 2D projection (being that it is significantly more complex). But I managed to find a particularly noteworthy article on 2D shadow projection.*

The above was one of the initial drafts at a shadow engine. The first one actually just used a single box which is not all that exciting to play with. The engine is limited in that it can't work with concave shapes (a shape that has part of it "hollowed out"). This is mostly because the calculations become quite a bit more complex, especially when self-shadowing is needed. So I cheated. The left had shape above actually consists of two convex shapes. You may have to click the flash movie to activate it. Twiddle the mouse around to move the light source. You'll note that it glitches out when moving the light into one of the shadow objects (so don't do that) or if you move the light source very close to one of the shadow casters (don't do that either, please).

The early engine is actually a shadow casting system as opposed to a light casting one. The difference is minor and actually took me a bit to properly conceptualise. Basically in the above, the light is not really doing anything. It isn't light the scene, rather the casting objects (casters) are darkening the scene. Light casting starts with a completely dark scene and then casts light (with shadows being an absence of light like in that place wherein you reside: real life). A friend of mine suggested I do the whole light casting thing instead and I went ahead and listened to him. It meant a complete overhaul (more a starting from scratch) of the shadow code and the result was much improved (perhaps also due to the fact that I understood more what I wanted to do with the shadows). I'll discuss and show that demo in a later post.

At some point I thought doing shadows with fuzzy edges (the penumbra part of the light for all you technophiles) would be fun and I had a quick hack of it underway using the glow filter in Flash instead of an actual calculation to speed it up.



Sadly, I think that unless I bake the shadows into the level (pre-calculate the shadows so that they are part of the level and can't change during gameplay) this approach would be too costly in CPU usage. Filter effects in Flash are notoriously slow.


* this way, if you're interested: http://www.gamedev.net/reference/programming/features/2dsoftshadow/. The article references OpenGL but many of the concepts can be carried through on other systems.

No comments:

Post a Comment