Friday, September 09, 2005

DIM Shadows

Jeff implemented my idea of using two Diffuse Irradiance Maps (DIM) on objects, one for lit areas and one for shadows, and it totally owns!

First a bit about diffuse irradiance maps: A DIM is a type of environment map that stores precomputed diffuse lighting information from a reflection map (also referred to as a Light Probe in this case). Every pixel in the light probe is considered to be a separate, directional light source pointing to the center. This allows for arbitrarily complex lighting conditions to be defined by, say, a panoramic photograph such as the ones Paul Debevec makes. However every point on the surface of a model would need to consider every pixel in the light probe as a light source, or at least every pixel within the hemisphere about the normal of the surface, which is not feasible in real-time by any means (at least not by brute force). Instead a DIM is calculated through a process of Diffuse Convolution. For any normal N, lighting contributions from all pixels in the light probe (really just the ones in the hemisphere around N) are summed up and stored in a new environment map called a DIM. This way any point on the surface of a model can look up the sum of all the light sources from the DIM on the fly using it's normal.

So Josh, Mark, and I went out into a prairie, took a fairly high-resolution HDR panorama and generated two DIMs from it using Debevec's HDRShop.

Light probe of a prairie


Sunlight DIM of prairie


Shadow DIM of a prairie

The light probe had to be scaled down quite a bit because diffuse convolution is O(N^2). HDRShop will tell you just how ridiculously long a full-res convolution will take before it starts (and ten thousand seconds is a lot longer than it sounds). Our 12.6 megapixel images would get done in 229 million seconds or just under 7.25 years. We ended up generating 360 by 180 pixel DIMs which ended up taking about half an hour to compute.

The sunlight DIM was computed from the original light probe normally. The shadow DIM was computed from a light probe where the sun was edited out in Photoshop. This simulates an object blocking out all the light eminating from the pixels that define the sun in the reflection map and only leaves the lighting the object would receive from ambient sources like the sky. Finally in the program itself, we compute shadows with shadow volumes or shadow mapping based on a rough estimate of the sun direction in the light probe. Fragments that end up in shadow get drawn with the shadow DIM, fragments in the light with the sunlight DIM.

The results are amazing. Here are some screenshots of Jeff's SpeedTree shadow-mapping demo:


Friday, September 02, 2005

Tool Development

glitch-art: "A Snail in Peril"

We had a heated discussion this morning about level editing and art tools. The question was do we create our own level editing tools from scratch or write Maya plugins to do everything from material management to entity placement and scripting within the Maya interface and export it all from there. It's actually not a decision to be taken lightly.

Of course being programmers, our gut response was "Maya sucks, lets write everything from scratch", but what a daunting task when you think about it! Not only does Maya have a huge set of standardized modeling tools they've worked on for years, it also features all those little things you tend to take for granted in an application. Things like copy/paste, undo, marquee selection, the list goes on. It's all necessary for a pleasing working environment. I remember we had a level editor for a school project called Metropolis that could save but not load files; let that one sink in for a moment. We ended up having a machine constantly running with the map editor open because you couldn't save your progress and load it up later. Once you started you couldn't stop! Incomplete tools are extremely frustrating to work with and will drive your artists up the wall when deadlines loom.

On the other hand, working with an API for a 500-pound gorilla like Maya sucks hard. It sucks because Maya is not a simple tool. You get dropped into this massive code-base that has been in development for over a decade and you start sifting through it with a flashlight. You may spend days just reading documentation in hopes of stumbling on a way to get at some crucial piece of information like material IDs. Often you'll find N different ways to almost do what you need. Plugin writing is an extremely slow and daunting development process and the API will fight you every step of the way. And the result is usually a crude and inflexible hack to get the application to behave.

Your hell will be doubled if you choose to use a scripting language like MEL or MaxScript by the way. They are usually handicapped compared to C++ APIs and are way too slow for complex algorithms. Scripting APIs are rarely easier to learn, they're just different APIs to figure out while learning a new language. In my opinion scripting is rarely the answer to anything. I'm a C++ programmer and I'm very proficient in it, switching to Python isn't going to magically help me come up with algorithms faster, it's mostly just going to get in the way.

We concluded that the "right" thing to do would be to utilize Maya solely because it is a professional grade world creation tool after all. However just because it's the "right" thing doesn't mean it won't be a waste of time. In the end it's a balance of developer headache versus artist headache. We decided we are going to do as much as we can in Maya, but entity placement, scripting, and final touches to the culling portals are going to be in a separate application. We still get to wrestle Maya over some of the basics, though luckily Jeff has figured most of mesh exporting out already, and we still have to implement a world editing tool from scratch. We just lack the resources to battle Maya for the next 6 months just to integrate our character scripting and material system into it. And the biggest problem we are going to face: our Maya plugin is likely not going to be able to load the data our custom app saves out. That means everything has to be perfected in Maya before things are changed in the custom app or the custom app changes have to be discarded as we reload the exported Maya data. Now we are working on some schemes to make this less of a problem.

In conclusion, we need a Maya plugin intern. Great industry experience! The hourly rate is 3 cents, a piece of string, and a Flintstones vitamin. Please contact andres@reinot.com.