How I created animated characters' dynamic shadows in Clone Wars - Jedi Alliance on Nintendo DS
Am I allowed to publish this technique
- my previous employer, Lucasfilm Animation Singapore - Game Department sometimes referred to as Lucasarts Singapore, did not patent this technique.
- my previous lead told me I'm allowed to speak freely about this technique.
- there seems to be some previous art partly covering similar techniques.
How shadows came to life in Clone Wars - Jedi Alliance
Shadows in Jedi Alliance came in thanks to a mix of randomness, luck, and my previous shadow experience.
At first a coworker was to work on the shadow system. He felt sick while writing the technical document and I came in charge. I first started to reorder his document and to give more thorough explication about what could not be made on DS.
Out of frustration about how limited this hardware was compared to a 10 years old Nvidia TNT GPU, I started to think about how I could get rid of the stencil shadowing steps that would not work on DS. And after half an hour the solution was on the paper.
The problem: hardware limitations
Here are the previously existing techniques:
- A circular dark circle under the characters. Very old and simple, ugly, definitely not what we wanted.
- Shadow Maps/Shadow Buffer: render the view from the light into the shadow map, and check for each point of the final image if it's visible or not in the shadow map. Lack of shadow map support, and having only one frame buffer on the DS, plus a high cost in memory, and no depth map comparison per pixel unless we use some alpha test cheating, means it's not possible on the DS.
- Shadow Volumes/Stencil buffer: extrude the volume the character will shadow from its geometry and from the light position. It requires finding the silhouette of the character as seen from the light, expanding it along the light direction, and finding it intersection with the rest of the world. Step 1 and 2 would have to be done on the DS CPU and they would be incredibly slow (not doable in real time in a game). For the last step, the DS has only one bit of Stencil Buffer, which means two intersecting shadow volumes would cancel each other shadows ; for example the shadow of a character's arm would cancel the shadow of his body.
Compute the matrices of the main bones, and use that with some body information to directly generate a low detail shadow volume.
To do so I use a cube of size 1 by 1 by 1, which pivot is in the center of one face. This cube is displayed several time, once per required bone, with a matrix that position its start on the bone and that will scale and orientate it along the light direction, of the size of the body part.
Most of the time, the rotation matrix will be made of the light direction, of the bone direction, and of their cross-product. Scale each component by the length of the shadow volumes, and some information about your bones.
The second stencil pass automatically clear the stencil buffer on the DS. Which means that overlapping/intersecting shadow volumes won't cancel each other.
Screenshots from the game Clone Wars - Jedi Alliance on Nintendo Ds, by Lucasarts/Lucasfilm Animation Singapore - game department.
As you can see, such extruded cubes intersect with the back of the character, which means they'll add shadows on the side which should be lighted. To fix that we can either prevent self-shadowing (easy on the DS: set the character and his shadow volumes to use the same PolyonId), or we can alter the cubes:
The idea is to use a non orthogonal matrix, where the cross product vector is altered to stay vertical, keeping the stretched cubes on the shadowed sided of the character.
Rendering several times the shadows while moving a bit the light source gives soft shadows. On the DS one must also change the PolygonId of each shadow iteration volume or they would not add up.
While this works fine, it consumes too much CPU time and polygons to be afforded in our game on the DS. Still having produced real time soft shadows for animated characters on a Nintendo DS was quite a nice achievement =)
And it's still there in the CW-JA game engine. It could be activated in some cutscenes for example.
This document was written by Sylvain Vignaud in 2008. It was originally published on http://tfpsly.free.fr/english/3d/Shadows_on_ds.html
Web site: http://tfpsly.free.fr