May 15 2012

Let’s talk about shadows

Tag: Engine Design,Full Games,MMORPG Tycoontrevor @ 8:16 pm

There are a lot of different ways to create shadows in video games.

When I entered the game industry fifteen years ago, there were two standard ways to draw shadows:  blob shadows and stencil shadows.  (There was a third option as well:  light maps, as popularised by Quake 2.  But I’m not going to cover those since they were used for handling static lighting, not for real-time dynamic effects.)

Blob Shadows

Blob shadows are a very simple concept.  If we have a moving object that we want to have appear to cast a shadow, all we have to do is to draw a sprite on the ground beneath it.  This sprite was typically an indistinct, blurry oval, roughly matching the general size of the object it was “shadowing”.  Its texture is where the term “blob” came from.  In this shot, you can see a robot with a blob shadow.  (That blob shadow is substantially larger than I would ever make it, personally.  At this scale, it’s far too easy to tell that it’s just a simple sprite).

A tricky point about implementing blob shadows is making the shadow appear correctly over a ground surface;  making it draw on top of an undulating terrain is a surprisingly tricky problem.  It’s very easy to end up with a shadow sprite that clips through the ground or floats above it, or is visible through other objects between the shadow and the camera.  Since the shadow is basically just a big flat sprite, you can’t reliably cast the shadow onto an extremely bumpy surface, or onto another object.  You’re basically stuck with just a flat circle on a (more or less) flat ground.

Fifteen years ago, these were the usual way of putting dynamic shadows on movable objects in a game.  As games became more sophisticated, we started finding ways to disguise how simplistic these shadows were.  First by scaling the blob as the character animated (so as the character moved his leg forward, the circular shadow would stretch forward into an oval shape), and then by actually giving each character several different blob shadows, each projected down from a different part of the character’s body.  This made the shadow seem to vaguely move along as the character animated in a much better way than the simple scaling approach.  In Transformers, we gave each enemy robot (I seem to recall) four or five blob shadows, each anchored to a different part of the robot’s body.  When rendered, these separately circular blob shadows appeared to merge together into a single amorphous blob that moved in a way which didn’t draw the player’s attention as being circular and static.

This technique is still around and being used today in new games.  Just a few months ago I implemented it for use in an (unreleased) iPhone racing game, where we used vaguely car-shaped blob shadows under the cars.  With some very sophisticated maths to try to make the shadow mimic the car’s rotation in mid-air, and projecting down onto the race track surface according to an angled light source and angled track.  But fundamentally, if you ignore the fancy math for scaling and orienting it to the ground surface, it was still just a single blob shadow;  just a flat sprite with a pre-drawn texture on it.

I seriously considered using blob shadows for MMORPG Tycoon 2.  It certainly would have been faster to implement than what I’ve actually done.  But all the foliage in the game would have caused problems, since the shadows would have sorted underneath the foliage and been almost invisible in many situations.  (Even in modern games you occasionally see this problem, blob shadows vanishing under ground clutter)

Stencil Shadows

Also called “shadow volumes”, stencil shadows were the high-quality alternative to blob shadows.  They’re not used as much today as they used to be, but it’s still an interesting technique.

The basic idea of stencil shadows is to computationally find the silhouette of an object from the light’s point of view, and then extrude that silhouette through space.  This extruded object is the shadow cast by the object.

You then render this shadow object using a “stencil buffer”, and use the resulting stencil data to determine for each pixel in your screen image whether that pixel is inside or outside of the shadow volume.  I worked on several games which used this sort of system.  Usually this approach was only used for the shadow on the player character, or sometimes large boss enemies;  it was really too CPU intensive for us to be able to afford to do it for all characters on-screen.  And even when we did do it, we would use simplified versions of the visual models;  usually just a series of boxes or elipses roughly approximating the character’s shape.  Finding the silhouette and building renderable extruded geometry every frame was simply too expensive.

Another interesting point is that because of the way that stencil buffers work, the shadow was always hard-edged;  each pixel was either in-shadow or out-of-shadow, so shadows couldn’t feather or soften with distance.

To do this, you had to render the shadow volume with a special shader, and you had to render any object which might receive a shadow with another special shader.  This was always more expensive than normal rendering, so quite a lot of effort often went into determining precisely which triangles might receive a shadow, just for the purposes of figuring out which bits of world geometry needed to have the expensive shaders enabled.

Fun note:  The further your shadow geometry is extruded, the longer it takes to render, both because it touches more pixels, because it will more often have to go through the expensive geometry clipping process, and also because it potentially hits more world geometry, thus requiring more stuff to render using the expensive shadow-receiver shader.  But if your renderable geometry didn’t actually hit a shadow receiver (the ground underneath the character, for example, because the character was high up in the air from a jump or something and the shadow geometry wasn’t extruded far enough downward to reach the ground), then no shadow would be visible at all;  the shadow would appear to suddenly pop into being as soon as the shadow caster moved within range.  Most games tried to hide this pop-in by making the extruded shadow geometry be built like a spike;  smoothly scaling down into a single point — kind of the opposite of the shadow volume being extruded from the torus in the image above.  If you look at games from the early 90s, you’ll occasionally see games which do this;  you can tell because you’ll see that shadows get smaller as objects move away from their cast shadows, instead of getting larger.

To my knowledge, no modern games use stencil shadows any longer.  And that’s mostly because they’ve been completely replaced by the new favoured system(s): shadow maps, which are better in almost every way.

Shadow Maps

Continue reading “Let’s talk about shadows”


May 06 2012

A couple of shadow shots

Tag: Full Games,MMORPG Tycoontrevor @ 10:04 pm

Shadows, now working on both ATI and NVidia chipsets. Have not yet tested on a device using Intel integrated graphics.

Not sure how well these shadows will work in that situation.  But I’ll definitely want to release MS-2 soon, to hear about performance on more machines.  Hopefully in the next few weeks!


May 06 2012

Unexpected behaviour

Tag: Full Games,MMORPG Tycoontrevor @ 5:06 pm

Ladies and gentlemen, cascading shadow maps are working.  (High-resolution shadows up close, low-resolution in the distance.  In this screenshot, all the visible shadows are low-resolution;  the high-res ones are mostly only visible when you’re down near the ground)

This isn’t the best shot of the shadows;  I’ll take another screenshot later tonight which will be a bit more dramatic.  But I was sort of startled to see this a moment ago:  AI developer cursors automatically casting shadows.  I probably should disable that, since they’re not supposed to literally be present inside the game world.  But it’s neat to see the shadows working.

It’s looking like I probably need a third shadow distance.  The close one is really needed for when you’re actually standing on the ground.  But for the shadows visible in the middle-distance here, they look a lot blockier than I’d really like.  So there’s still a bit more work to be done.  But overall, I’m pretty happy with where this is going.


May 06 2012

Progress

Tag: Full Games,MMORPG Tycoontrevor @ 3:52 pm

Still not there, but getting a lot closer.


May 06 2012

Surface acne

Tag: Full Games,MMORPG Tycoontrevor @ 11:24 am

This is what I’m struggling with right now.

In discussions about shadows, these sorts of odd striations and blemishes are generally referred to as “self-shadow surface acne”. They’re commonly caused by math imprecision when a surface (such as here, the mountain) throws a shadow onto itself.  The shadow-caster and the shadow-receiver are so close together (ie: directly on top of one another), that sometimes the math flips their order around.  This results in these interesting stripe patterns.

Hope it doesn’t take me too long to sort them out.  I’d really like to finish shadows today and get back to items.


Next Page »