Shadows, Smoke and Mirrors – Part One
I remember the first time I started looking into shadows. It was back when I first started working with 3D graphics and I had this naive idea that 3D graphics were so awesome because they were simulating nature. Learning about real time shadow rendering techniques quickly killed that idea. Learning about other aspects of real time 3D rendering like geometry and lighting I suspended the realization that it is all just smoke and mirrors, by imagining that if my computer were just faster, I might be able to take into account enough detail to actually be simulating how light works, rather than just making a nice picture with a pseudo-approximation of how light works. But when it comes to shadows, that rationalisation rolls over and dies. The methods used to create the appearance of shadows in real time rendering (and as far as I’ve researched, in offline rendering as well) are far removed from the real world physics that create shadows.
The root cause of this divergence with real physics is the discreet, compartmentalised way that a 3D scene is processed during rendering. In the scene, each 3D mesh is a separate object; its geometry is isolated from other geometry in the scene. This makes sense, because it allows each mesh to be moved around the scene easily, independent of the other geometry. If the whole scene were not compartmentalised in this fashion, every time an object moved relative to the rest of the scene, every vertex belonging to that object would need to be found, identified as belonging to the geometry to be moved, and then moved. When meshes potentially have tens of thousands of verticies, it is clear that such an approach is, A Very Bad Idea. Even if t
he entire 3D scene was just one large collection of verticies and not subdivided into discreet objects, rendering lighting techniques work by processing their lighting algorithm on each point that will be visible in the final image (each pixel essentially.) At each point the lighting algorithm considers things like, the position and attributes (like colour) of lights that affect the point in question by calculating the relative spatial relationship between the point in question and the light. The final colour of the pixel is a combination of the lighting contribution and other things like textures depending on other rendering techniques being used. Lighting is essentially computed “backwards” from the way it works in the real world. Photons don’t fly through the scene lighting whatever they hit, each point on a mesh is checked and a lighting contribution is calculated by checking the angle and distance back to a nearby light.
Since lighting is calculated for each point on a mesh in isolation from the rest of the scene, there is no elegant way to draw shadows, since shadows are possibly cast by any other geometry in the scene, and the lighting algorithm is only aware of the point it is operating on and the scene’s lights.
A wide array of techniques has been developed to get around this issue. Many are capable of rendering believable shadows for a limited range of scenes or for certain kinds of lights, however, none are capable of rendering believable shadows for every possible scene and every type of light.
In the next entry of Shadows, Smoke and Mirrors I’ll discuss a few of the more common real time rendering shadow techniques.

Tags: 3D Graphics, Lighting, Shadow Techniques, Shadows







July 9th, 2008 at 1:47 am
P.S. I realise the clouds look a little funny in the first picture in this post, I’ve been playing with the technique to get some more realism and contour in the centers of the clouds during the daytime. As you can see, I haven’t quite got it yet, as the centers of the clouds look especially flat in that screenshot.